Пример #1
0
 ///<summary>Includes all attached fields.  Intelligently inserts, updates, or deletes old fields.</summary>
 ///<param name="isOldSheetDuplicate">True if the sheetDef being created is a copy of a custom sheet that has a DateTCreated of 0001-01-01.
 ///DateTCreated determines whether or not text fields will be shifted up 5 pixels when PDF is created from sheet to fix bug job B16020.</param>
 public static long InsertOrUpdate(SheetDef sheetDef, bool isOldSheetDuplicate = false)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         sheetDef.SheetDefNum = Meth.GetLong(MethodBase.GetCurrentMethod(), sheetDef, isOldSheetDuplicate);
         return(sheetDef.SheetDefNum);
     }
     if (sheetDef.IsNew)
     {
         if (!isOldSheetDuplicate)
         {
             sheetDef.DateTCreated = MiscData.GetNowDateTime();
         }
         sheetDef.SheetDefNum = Crud.SheetDefCrud.Insert(sheetDef);
     }
     else
     {
         Crud.SheetDefCrud.Update(sheetDef);
     }
     foreach (SheetFieldDef field in sheetDef.SheetFieldDefs)
     {
         field.SheetDefNum = sheetDef.SheetDefNum;
     }
     SheetFieldDefs.Sync(sheetDef.SheetFieldDefs, sheetDef.SheetDefNum);
     return(sheetDef.SheetDefNum);
 }
Пример #2
0
 ///<summary>Must be called after Preference cache has been filled.
 ///Deletes all signals older than 2 days if this has not been run within the last week.  Will fail silently if anything goes wrong.</summary>
 public static void ClearOldSignals()
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         Meth.GetVoid(MethodBase.GetCurrentMethod());
         return;
     }
     try {
         if (Prefs.GetContainsKey(PrefName.SignalLastClearedDate.ToString()) &&
             PrefC.GetDateT(PrefName.SignalLastClearedDate) > MiscData.GetNowDateTime().AddDays(-7)) //Has already been run in the past week. This is all server based time.
         {
             return;                                                                                 //Do not run this process again.
         }
         string command = "";
         if (DataConnection.DBtype == DatabaseType.MySql)                                          //easier to read that using the DbHelper Functions and it also matches the ConvertDB3 script
         {
             command = "DELETE FROM signalod WHERE SigDateTime < DATE_ADD(NOW(),INTERVAL -2 DAY)"; //Itypes only older than 2 days
             Db.NonQ(command);
         }
         else                                                                           //oracle
         {
             command = "DELETE FROM signalod WHERE SigDateTime < CURRENT_TIMESTAMP -2"; //Itypes only older than 2 days
             Db.NonQ(command);
         }
         SigMessages.ClearOldSigMessages();                                            //Clear messaging buttons which use to be stored in the signal table.
         //SigElements.DeleteOrphaned();
         Prefs.UpdateDateT(PrefName.SignalLastClearedDate, MiscData.GetNowDateTime()); //Set Last cleared to now.
     }
     catch (Exception) {
         //fail silently
     }
 }
Пример #3
0
        private static DateTime GetDateLimit(Permissions permType, long userGroupNum)
        {
            //No need to check RemotingRole; no call to db.
            DateTime nowDate = MiscData.GetNowDateTime().Date;
            DateTime retVal  = DateTime.MinValue;

            for (int i = 0; i < GroupPermissionC.List.Length; i++)
            {
                if (GroupPermissionC.List[i].UserGroupNum != userGroupNum || GroupPermissionC.List[i].PermType != permType)
                {
                    continue;
                }
                //this should only happen once.  One match.
                if (GroupPermissionC.List[i].NewerDate.Year > 1880)
                {
                    retVal = GroupPermissionC.List[i].NewerDate;
                }
                if (GroupPermissionC.List[i].NewerDays == 0)              //do not restrict by days
                //do not change retVal
                {
                }
                else if (nowDate.AddDays(-GroupPermissionC.List[i].NewerDays) > retVal)
                {
                    retVal = nowDate.AddDays(-GroupPermissionC.List[i].NewerDays);
                }
            }
            return(retVal);
        }
Пример #4
0
        ///<summary>Creates historical entry of deletion into wikiPageHist, and deletes current non-draft page from WikiPage.
        ///For middle tier purposes we need to have the currently logged in user passed into this method.</summary>
        public static void Archive(string pageTitle, long userNumCur)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                Meth.GetVoid(MethodBase.GetCurrentMethod(), pageTitle, userNumCur);
                return;
            }
            WikiPage wikiPage = GetByTitle(pageTitle);

            if (wikiPage == null)
            {
                return;                //The wiki page could not be found by the page title, nothing to do.
            }
            WikiPageHist wikiPageHist = PageToHist(wikiPage);

            //preserve the existing page with user credentials
            WikiPageHists.Insert(wikiPageHist);
            //make entry to show who deleted the page
            wikiPageHist.IsDeleted     = true;
            wikiPageHist.UserNum       = userNumCur;
            wikiPageHist.DateTimeSaved = MiscData.GetNowDateTime();
            WikiPageHists.Insert(wikiPageHist);
            //Now mark the wikipage as IsDeleted
            wikiPage.IsDeleted     = true;
            wikiPage.DateTimeSaved = MiscData.GetNowDateTime();
            Crud.WikiPageCrud.Update(wikiPage);
            //Remove all associated home pages for all users.
            UserOdPrefs.DeleteForValueString(0, UserOdFkeyType.WikiHomePage, pageTitle);
        }
Пример #5
0
 ///<summary></summary>
 public static long Insert(Signalod sig)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         sig.SignalNum = Meth.GetLong(MethodBase.GetCurrentMethod(), sig);
         return(sig.SignalNum);
     }
     if (RemotingClient.RemotingRole == RemotingRole.ServerWeb)
     {
         //Refresh the cache now so that we don't have to refresh the cache when the clients update their cache.
         if (sig.IType == InvalidType.Fees && sig.FKeyType == KeyType.FeeSched && sig.FKey > 0)
         {
             //We don't want to refresh the entire feecache if we don't have to.
             Fees.InvalidateFeeSchedule(sig.FKey);
         }
         else
         {
             Cache.Refresh(sig.IType);
         }
     }
     //We need to explicitly get the server time in advance rather than using NOW(), because we need to update the signal object soon after creation.
     sig.SigDateTime = MiscData.GetNowDateTime();
     sig.RemoteRole  = RemotingClient.RemotingRole;
     return(Crud.SignalodCrud.Insert(sig));
 }
Пример #6
0
        ///<summary>The main logic that sends Podium invitations.  Set isService true only when the calling method is the Open Dental Service.</summary>
        public static void ThreadPodiumSendInvitations(bool isService)
        {
            long programNum = Programs.GetProgramNum(ProgramName.Podium);

            //Consider blocking re-entrance if this hasn't finished.
            //Only send invitations if the program link is enabled, the computer name is set to this computer, and eConnector is not set to send invitations
            if (!Programs.IsEnabled(ProgramName.Podium) ||
                !ODEnvironment.IdIsThisComputer(ProgramProperties.GetPropVal(programNum, PropertyDescs.ComputerNameOrIP)) ||
                ProgramProperties.GetPropVal(programNum, PropertyDescs.UseService) != POut.Bool(isService))
            {
                return;
            }
            //Keep a consistant "Now" timestamp throughout this method.
            DateTime nowDT = MiscData.GetNowDateTime();

            if (Podium.DateTimeLastRan == DateTime.MinValue)           //First time running the thread.
            {
                Podium.DateTimeLastRan = nowDT.AddMilliseconds(-PodiumThreadIntervalMS);
            }
            ReviewInvitationTrigger newPatTrigger      = PIn.Enum <ReviewInvitationTrigger>(ProgramProperties.GetPropVal(programNum, PropertyDescs.NewPatientTriggerType));
            ReviewInvitationTrigger existingPatTrigger = PIn.Enum <ReviewInvitationTrigger>(ProgramProperties.GetPropVal(programNum, PropertyDescs.ExistingPatientTriggerType));
            List <Appointment>      listNewPatAppts    = GetAppointmentsToSendReview(newPatTrigger, programNum, true);

            foreach (Appointment apptCur in listNewPatAppts)
            {
                Podium.SendData(Patients.GetPat(apptCur.PatNum), apptCur.ClinicNum);
            }
            List <Appointment> listExistingPatAppts = GetAppointmentsToSendReview(existingPatTrigger, programNum, false);

            foreach (Appointment apptCur in listExistingPatAppts)
            {
                Podium.SendData(Patients.GetPat(apptCur.PatNum), apptCur.ClinicNum);
            }
            Podium.DateTimeLastRan = nowDT;
        }
Пример #7
0
        ///<summary>Will throw an exception if already clocked in.</summary>
        public static void ClockIn(long employeeNum)
        {
            //we'll get this again, because it may have been a while and may be out of date
            ClockEvent clockEvent = ClockEvents.GetLastEvent(employeeNum);

            if (clockEvent == null)           //new employee clocking in
            {
                clockEvent             = new ClockEvent();
                clockEvent.EmployeeNum = employeeNum;
                clockEvent.ClockStatus = TimeClockStatus.Home;
                ClockEvents.Insert(clockEvent);                       //times handled
            }
            else if (clockEvent.ClockStatus == TimeClockStatus.Break) //only incomplete breaks will have been returned.
            //clocking back in from break
            {
                clockEvent.TimeEntered2   = MiscData.GetNowDateTime();
                clockEvent.TimeDisplayed2 = clockEvent.TimeEntered2;
                ClockEvents.Update(clockEvent);
            }
            else                                           //normal clock in/out
            {
                if (clockEvent.TimeDisplayed2.Year < 1880) //already clocked in
                {
                    throw new Exception(Lans.g("ClockEvents", "Error.  Already clocked in."));
                }
                else                  //clocked out for home or lunch.  Need to clock back in by starting a new row.
                {
                    TimeClockStatus tcs = clockEvent.ClockStatus;
                    clockEvent             = new ClockEvent();
                    clockEvent.EmployeeNum = employeeNum;
                    clockEvent.ClockStatus = tcs;
                    ClockEvents.Insert(clockEvent);                    //times handled
                }
            }
        }
Пример #8
0
 ///<summary>Process all Signals and Acks Since a given DateTime.  Only to be used by OpenDentalWebService.  Returns latest valid signal Date/Time.  Can throw exception.</summary>
 public static void RefreshForWeb(ref DateTime sinceDateT)
 {
     //No need to check RemotingRole; no call to db.
     try {
         if (sinceDateT.Year < 1880)
         {
             sinceDateT = MiscData.GetNowDateTime();
         }
         //Get all invalid types since given time.
         List <int> itypes = Signalods.GetInvalidTypes(Signalods.RefreshTimed(sinceDateT));
         if (itypes.Count <= 0)
         {
             return;
         }
         string itypesStr = "";
         for (int i = 0; i < itypes.Count; i++)
         {
             if (i > 0)
             {
                 itypesStr += ",";
             }
             itypesStr += ((int)itypes[i]).ToString();
         }
         //Refresh the cache for the given invalid types.
         Cache.RefreshCache(itypesStr);
         sinceDateT = OpenDentBusiness.MiscData.GetNowDateTime();
     }
     catch (Exception e) {
         //Most likely cause for an exception here would be a thread collision between 2 consumers trying to refresh the cache at the exact same instant.
         //There is a chance that performing as subsequent refresh here would cause yet another collision but it's the best we can do without redesigning the entire cache pattern.
         Cache.Refresh(InvalidType.AllLocal);
         throw new Exception("Server cache may be invalid. Please try again. Error: " + e.Message);
     }
 }
Пример #9
0
 ///<summary>Returns serialized DbInfo object as JSON string of database info from both the preference table and non preferernce table info.</summary>
 private string GetDbInfoJSON(long patNum, string moduleName)
 {
     _info = new BugSubmission.SubmissionInfo();
     try {
         //This list is not in a separate method because we want to ensure that future development related to bug submissions don't try to make assumptions
         //on which preferences are in an object at any given time.
         //Ex.  Let's say in version 17.4, the list doesn't contain the payplan version preference, but 17.5 does.
         //If we called the method that retrieves the used preferences from WebServiceMainHQ which in this example is on version 17.5,
         // it would think all bugsubmission rows contain the payplan version preference when that is not the case.
         List <PrefName> listPrefs = new List <PrefName>()
         {
             PrefName.AtoZfolderUsed,
             PrefName.ClaimSnapshotEnabled,
             PrefName.ClaimSnapshotRunTime,
             PrefName.ClaimSnapshotTriggerType,
             PrefName.CorruptedDatabase,
             PrefName.DataBaseVersion,
             PrefName.EasyNoClinics,
             PrefName.LanguageAndRegion,
             PrefName.MySqlVersion,
             PrefName.PayPlansVersion,
             PrefName.ProcessSigsIntervalInSecs,
             PrefName.ProgramVersionLastUpdated,
             PrefName.ProgramVersion,
             PrefName.RandomPrimaryKeys,
             PrefName.RegistrationKey,
             PrefName.RegistrationKeyIsDisabled,
             PrefName.ReplicationFailureAtServer_id,
             PrefName.ReportingServerCompName,
             PrefName.ReportingServerDbName,
             PrefName.ReportingServerMySqlUser,
             PrefName.ReportingServerMySqlPassHash,
             PrefName.ReportingServerURI,
             PrefName.WebServiceServerName
         };
         foreach (PrefName pref in listPrefs)
         {
             _info.DictPrefValues[pref] = Prefs.GetOne(pref).ValueString;
         }
         _info.CountClinics            = Clinics.GetCount();
         _info.EnabledPlugins          = Programs.GetWhere(x => x.Enabled && !string.IsNullOrWhiteSpace(x.PluginDllName)).Select(x => x.ProgName).ToList();
         _info.ClinicNumCur            = Clinics.ClinicNum;
         _info.UserNumCur              = Security.CurUser.UserNum;
         _info.PatientNumCur           = patNum;
         _info.IsOfficeOnReplication   = (ReplicationServers.GetCount() > 0 ? true : false);
         _info.IsOfficeUsingMiddleTier = (RemotingClient.RemotingRole == RemotingRole.ClientWeb ? true : false);
         _info.WindowsVersion          = MiscData.GetOSVersionInfo();
         _info.CompName = Environment.MachineName;
         List <UpdateHistory> listHist = UpdateHistories.GetPreviouUpdateHistories(2);                       //Ordered by newer versions first.
         _info.PreviousUpdateVersion = listHist.Count == 2 ? listHist[1].ProgramVersion : "";                //Show the previous version they updated from
         _info.PreviousUpdateTime    = listHist.Count > 0 ? listHist[0].DateTimeUpdated : DateTime.MinValue; //Show when they updated to the current version.
         _info.ModuleNameCur         = moduleName;
         _info.DatabaseName          = DataConnection.GetDatabaseName();
     }
     catch (Exception ex) {
         ex.DoNothing();
     }
     return(JsonConvert.SerializeObject(_info));
 }
Пример #10
0
        ///<summary>When user clicks on a colored light, they intend to ack it to turn it off.  This acks all signals with the specified index.  This is in case multiple signals have been created from different workstations.  This acks them all in one shot.  Must specify a time because you only want to ack signals earlier than the last time this workstation was refreshed.  A newer signal would not get acked.
        ///If this seems slow, then I will need to check to make sure all these tables are properly indexed.</summary>
        public static void AckButton(int buttonIndex, DateTime time)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                Meth.GetVoid(MethodBase.GetCurrentMethod(), buttonIndex, time);
                return;
            }
            //FIXME:UPDATE-MULTIPLE-TABLES

            /*string command= "UPDATE signalod,sigelement,sigelementdef "
             +"SET signalod.AckTime = ";
             *      if(FormChooseDatabase.DBtype==DatabaseType.Oracle) {
             *              command+="(SELECT CURRENT_TIMESTAMP FROM DUAL)";
             *      }else{//Assume MySQL
             *              command+="NOW()";
             *      }
             *      command+=" "
             +"WHERE signalod.AckTime < '1880-01-01' "
             +"AND SigDateTime <= '"+POut.PDateT(time)+"' "
             +"AND signalod.SignalNum=sigelement.SignalNum "
             +"AND sigelement.SigElementDefNum=sigelementdef.SigElementDefNum "
             +"AND sigelementdef.LightRow="+POut.PInt(buttonIndex);
             * Db.NonQ(command);*/
            //Rewritten so that the SQL is compatible with both Oracle and MySQL.
            string command = "SELECT signalod.SignalNum FROM signalod,sigelement,sigelementdef "
                             + "WHERE signalod.AckTime < " + POut.Date(new DateTime(1880, 1, 1), true) + " "
                             + "AND SigDateTime <= " + POut.DateT(time) + " "
                             + "AND signalod.SignalNum=sigelement.SignalNum "
                             + "AND sigelement.SigElementDefNum=sigelementdef.SigElementDefNum "
                             + "AND sigelementdef.LightRow=" + POut.Long(buttonIndex);
            DataTable table = Db.GetTable(command);

            if (table.Rows.Count == 0)
            {
                return;
            }
            command = "UPDATE signalod SET AckTime = ";
            if (DataConnection.DBtype == DatabaseType.Oracle)
            {
                command += POut.DateT(MiscData.GetNowDateTime());
            }
            else               //Assume MySQL
            {
                command += "NOW()";
            }
            command += " WHERE ";
            for (int i = 0; i < table.Rows.Count; i++)
            {
                command += "SignalNum=" + table.Rows[i][0].ToString();
                if (i < table.Rows.Count - 1)
                {
                    command += " OR ";
                }
            }
            Db.NonQ(command);
        }
Пример #11
0
        ///<summary>NO LONGER USED.
        ///Leaving function here in case we want to reuse the code in future.  We only support connecting to archive DB directly.</summary>
        public static T RunFuncOnArchiveDatabase <T>(Func <T> f)
        {
            //Makes a connection to the archive database, validates that the version of the database is the same as the current database version,
            //executes the func passed in, and then sets the connection back to the original database before returning the results of the func passed in.
            //Optionally pass in connection settings to override the archive preferences.  Throws exceptions.
            if (RemotingClient.RemotingRole.In(RemotingRole.ClientWeb, RemotingRole.ServerWeb))            //May already be behind a remoting role check.
            //This method will eventually invoke SetDB() which is unacceptable for the Middle Tier.
            {
                throw new ApplicationException(Lans.g(nameof(MiscData), "Archive databases are not available when using a Middle Tier connection.") + "\r\n" +
                                               Lans.g(nameof(MiscData), "Archive databases may only be created or accessed on a direct database connection."));
            }
            string         connectionStrOrig = DataConnection.GetCurrentConnectionString();
            DatabaseType   dbTypeOrig        = DataConnection.DBtype;
            DataConnection dcon = new DataConnection();

            try {
                //Keep track of the original connection settings so that we can revert back to them once finished archiving.
                Version versionDbOrig     = new Version(PrefC.GetString(PrefName.DataBaseVersion));
                string  archiveServerName = PrefC.GetString(PrefName.ArchiveServerName);
                string  archiveUserName   = PrefC.GetString(PrefName.ArchiveUserName);
                string  decryptedPass;
                CDT.Class1.Decrypt(PrefC.GetString(PrefName.ArchivePassHash), out decryptedPass);
                //Connect to the archive database.  This can throw many exceptions.
                dcon.SetDb(archiveServerName, MiscData.GetArchiveDatabaseName(), archiveUserName, decryptedPass, "", "", dbTypeOrig);
                #region Validate archive database version
                //At this point there is an active connection to the archive database, validate the DataBaseVersion.
                string version = PrefC.GetStringNoCache(PrefName.DataBaseVersion);
                if (string.IsNullOrEmpty(version))
                {
                    //Preference table does not have version information.  Somehow they have a database with proper structure but no data.
                    //This archive database can't be trusted and we have no idea what version the schema is at.
                    //They need to call support so that we can take a look or they need to delete the invalid archive (or remove it from the data dir)
                    //so that a new archive database can be made from scratch.
                    throw new ApplicationException("Invalid archive database detected.");
                }
                Version versionDbArchive = new Version(version);
                if (versionDbOrig > versionDbArchive)
                {
                    //The archive database needs to be updated before funcs can be invoked against it.
                    throw new ApplicationException("Archive database is at a lower version than the current database."
                                                   + "  Run the Archive tool in order to update the database.");
                }
                else if (versionDbArchive > versionDbOrig)
                {
                    throw new ApplicationException("Archive database version is higher than the current database.  Process cannot continue.");
                }
                #endregion
                //Invoke the func passed in.
                return(f());
            }
            finally {                                          //Always put the connection back to the original no matter what happened above when trying to make an archive.
                dcon.SetDb(connectionStrOrig, "", dbTypeOrig); //It is acceptable to crash the program if this fails.
            }
        }
Пример #12
0
 ///<summary>Acknowledge one sig message from the manage module grid.</summary>
 public static void AckSigMessage(SigMessage sigMessage)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         Meth.GetVoid(MethodBase.GetCurrentMethod(), sigMessage);
         return;
     }
     //To ack a message, simply update the AckDateTime on the original row.
     sigMessage.AckDateTime = MiscData.GetNowDateTime();
     Update(sigMessage);
 }
Пример #13
0
 ///<summary></summary>
 public static long Insert(Signalod sig)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         sig.SignalNum = Meth.GetLong(MethodBase.GetCurrentMethod(), sig);
         return(sig.SignalNum);
     }
     //we need to explicitly get the server time in advance rather than using NOW(),
     //because we need to update the signal object soon after creation.
     sig.SigDateTime = MiscData.GetNowDateTime();
     return(Crud.SignalodCrud.Insert(sig));
 }
Пример #14
0
 public static void WikiPageRestore(WikiPage wikiPageRestored, long userNum)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         Meth.GetVoid(MethodBase.GetCurrentMethod(), wikiPageRestored, userNum);
         return;
     }
     //Update the wikipage with new user and flip the IsDelete flag.
     wikiPageRestored.IsDeleted     = false;
     wikiPageRestored.UserNum       = userNum;
     wikiPageRestored.DateTimeSaved = MiscData.GetNowDateTime();
     Crud.WikiPageCrud.Update(wikiPageRestored);
 }
Пример #15
0
        ///<summary>Also sets the DateSent to today.</summary>
        public static void SetCanadianClaimSent(long claimNum)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                Meth.GetVoid(MethodBase.GetCurrentMethod(), claimNum);
                return;
            }
            string command = "UPDATE claim SET ClaimStatus = 'S',"
                             + "DateSent= " + POut.Date(MiscData.GetNowDateTime())
                             + " WHERE ClaimNum = " + POut.Long(claimNum);

            Db.NonQ(command);
        }
Пример #16
0
 ///<summary>Sets the necessary fields for the given responseWeb object.
 ///expDate should be in yyMM format.</summary>
 private static void HandleResponseSuccess(PayConnectResponseWeb responseWeb, string resStr, bool isPending)
 {
     if (isPending)
     {
         responseWeb.ProcessingStatus = PayConnectWebStatus.Pending;
         responseWeb.DateTimePending  = MiscData.GetNowDateTime();
     }
     else
     {
         responseWeb.ProcessingStatus  = PayConnectWebStatus.Completed;
         responseWeb.DateTimeCompleted = MiscData.GetNowDateTime();
     }
     responseWeb.LastResponseStr = resStr;
 }
Пример #17
0
        ///<summary>Table must include columns labeled LatestPayment and DateStart.</summary>
        public static void FilterRecurringChargeList(DataTable table)
        {
            DateTime curDate = MiscData.GetNowDateTime();

            //Loop through table and remove patients that do not need to be charged yet.
            for (int i = 0; i < table.Rows.Count; i++)
            {
                DateTime latestPayment = PIn.Date(table.Rows[i]["LatestPayment"].ToString());
                DateTime dateStart     = PIn.Date(table.Rows[i]["DateStart"].ToString());
                if (curDate > latestPayment.AddDays(31))               //if it's been more than a month since they made any sort of payment
                //if we reduce the days below 31, then slighly more people will be charged, especially from Feb to March.  31 eliminates those false positives.
                {
                    continue;                    //charge them
                }
                //Not enough days in the current month so show on the last day of the month
                //Example: DateStart=8/31/2010 and the current month is February 2011 which does not have 31 days.
                //So the patient needs to show in list if current day is the 28th (or last day of the month).
                int daysInMonth = DateTime.DaysInMonth(curDate.Year, curDate.Month);
                if (daysInMonth <= dateStart.Day && daysInMonth == curDate.Day && curDate.Date != latestPayment.Date) //if their recurring charge would fall on an invalid day of the month, and this is that last day of the month
                {
                    continue;                                                                                         //we want them to show because the charge should go in on this date.
                }
                if (curDate.Day >= dateStart.Day)                                                                     //If the recurring charge date was earlier in this month, then the recurring charge will go in for this month.
                {
                    if (curDate.Month > latestPayment.Month || curDate.Year > latestPayment.Year)                     //if the latest payment was last month (or earlier).  The year check catches December
                    {
                        continue;                                                                                     //No payments were made this month, so charge.
                    }
                }
                else                  //Else, current date is before the recurring date in the current month, so the recurring charge will be going in for last month
                                      //Check if payment didn't happen last month.
                {
                    if (curDate.AddMonths(-1).Date > latestPayment.Date &&              //the latest recurring charge payment for this card was before one month ago
                        curDate.AddMonths(-1).Month != latestPayment.Month)                         //the latest recurring charge payment for this card did not happen during last month
                    //&& curDate.Date!=latestPayment.Date)//no longer necessary since latest payment was before one month ago
                    {
                        //Charge did not happen last month so the patient needs to show up in list.
                        //Example: Last month had a recurring charge set at the end of the month that fell on a weekend.
                        //Today is the next month and still before the recurring charge date.
                        //This will allow the charge for the previous month to happen if the 30 day check didn't catch it above.
                        continue;
                    }
                }
                //Patient doesn't need to be charged yet so remove from the table.
                table.Rows.RemoveAt(i);
                i--;
            }
        }
Пример #18
0
        ///<summary>Returns a list of strings in a specific order.
        ///The strings are as follows; socket (service name), version_comment (service comment), hostname (server name), and MySQL version
        ///Oracle is not supported and will throw an exception to have the customer call us to add support.</summary>
        public static List <string> GetServiceInfo()
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <List <string> >(MethodBase.GetCurrentMethod()));
            }
            if (DataConnection.DBtype == DatabaseType.Oracle)
            {
                throw new Exception(Lans.g("Computer", "Currently not Oracle compatible.  Please call support."));
            }
            List <string> retVal = new List <string>();
            DataTable     table  = Db.GetTable("SHOW VARIABLES WHERE Variable_name='socket'");     //service name

            if (table.Rows.Count > 0)
            {
                retVal.Add(table.Rows[0]["VALUE"].ToString());
            }
            else
            {
                retVal.Add("Not Found");
            }
            table = Db.GetTable("SHOW VARIABLES WHERE Variable_name='version_comment'");          //service comment
            if (table.Rows.Count > 0)
            {
                retVal.Add(table.Rows[0]["VALUE"].ToString());
            }
            else
            {
                retVal.Add("Not Found");
            }
            try {
                table = Db.GetTable("SELECT @@hostname");              //server name
                if (table.Rows.Count > 0)
                {
                    retVal.Add(table.Rows[0][0].ToString());
                }
                else
                {
                    retVal.Add("Not Found");
                }
            }
            catch {
                retVal.Add("Not Found");                //hostname variable doesn't exist
            }
            retVal.Add(MiscData.GetMySqlVersion());
            return(retVal);
        }
Пример #19
0
 ///<summary>Insertion logic that doesn't use the cache. Has special cases for generating random PK's and handling Oracle insertions.</summary>
 public static void SetInvalidNoCache(params InvalidType[] itypes)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         Meth.GetVoid(MethodBase.GetCurrentMethod(), itypes);
         return;
     }
     foreach (InvalidType iType in itypes)
     {
         Signalod sig = new Signalod();
         sig.IType       = iType;
         sig.DateViewing = DateTime.MinValue;
         sig.SigDateTime = MiscData.GetNowDateTime();
         sig.RemoteRole  = RemotingClient.RemotingRole;
         Crud.SignalodCrud.InsertNoCache(sig);
     }
 }
Пример #20
0
 ///<summary>Uses bulk insertion techniques to find and insert all securityloghash rows that are in the specified server/database and equal to or prior to the date.
 ///NOTE ----- MUST BE RUN AFTER BulkInsertSecurityLogs - DOES NOT WORK WITH RANDOM PRIMARY KEYS</summary>
 public static string BulkInsertSecurityLogHashes()
 {
     DatabaseTo  = MiscData.GetArchiveDatabaseName();
     TableName   = "securityloghash";
     TablePriKey = "SecurityLogHashNum";
     try {
         //Insert security log hashes that correspond to maximum security log primary key obtained previously.
         if (LargeTableHelper.ListPriKeyMaxPerBatch != null && LargeTableHelper.ListPriKeyMaxPerBatch.Count > 0)
         {
             InsertIntoLargeTable("WHERE SecurityLogNum <= " + POut.Long(LargeTableHelper.ListPriKeyMaxPerBatch.Max()));
         }
     }
     catch (Exception ex) {
         return(ex.Message);
     }
     return("");
 }
Пример #21
0
 ///<summary>Uses bulk insertion techniques to find and insert all securitylog rows that are in the specified server/database and equal to or prior to the date.
 ///NOTE ----- DOES NOT WORK WITH RANDOM PRIMARY KEYS</summary>
 public static string BulkInsertSecurityLogs(string serverName, string userName, string pass, DateTime dateArchive)
 {
     ServerTo    = POut.String(serverName);
     UserTo      = POut.String(userName);
     PasswordTo  = POut.String(pass);
     DatabaseTo  = MiscData.GetArchiveDatabaseName();
     TableName   = "securitylog";
     TablePriKey = "SecurityLogNum";
     try {
         //Insert security logs
         InsertIntoLargeTable("WHERE DATE(LogDateTime) <= " + POut.Date(dateArchive));
     }
     catch (Exception ex) {
         return(ex.Message);
     }
     return("");
 }
Пример #22
0
 public static void HandleResponseError(PayConnectResponseWeb responseWeb, string resStr)
 {
     responseWeb.LastResponseStr = resStr;
     if (responseWeb.ProcessingStatus == PayConnectWebStatus.Created)
     {
         responseWeb.ProcessingStatus = PayConnectWebStatus.CreatedError;
     }
     else if (responseWeb.ProcessingStatus == PayConnectWebStatus.Pending)
     {
         responseWeb.ProcessingStatus = PayConnectWebStatus.PendingError;
     }
     else
     {
         responseWeb.ProcessingStatus = PayConnectWebStatus.UnknownError;
     }
     responseWeb.DateTimeLastError = MiscData.GetNowDateTime();
 }
Пример #23
0
        ///<summary>Creates a new perio exam for the given patient. Returns that perio exam. Handles setting default skipped teeth/implants. Does not create a security log entry.</summary>
        public static PerioExam CreateNewExam(Patient pat)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <PerioExam>(MethodBase.GetCurrentMethod(), pat));
            }
            PerioExam newExam = new PerioExam {
                PatNum           = pat.PatNum,
                ExamDate         = DateTimeOD.Today,
                ProvNum          = pat.PriProv,
                DateTMeasureEdit = MiscData.GetNowDateTime()
            };

            Insert(newExam);
            PerioMeasures.SetSkipped(newExam.PerioExamNum, GetSkippedTeethForExam(pat, newExam));
            return(newExam);
        }
Пример #24
0
        ///<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);
        }
Пример #25
0
        ///<summary>Returns the Date that the user is restricted to for the passed-in permission.
        ///Returns MinVal if the user is not restricted or does not have the permission.</summary>
        public static DateTime GetDateRestrictedForPermission(Permissions permission, List <long> listUserGroupNums)
        {
            //No need to check RemotingRole; no call to db.
            DateTime        nowDate    = DateTime.MinValue;
            Func <DateTime> getNowDate = new Func <DateTime>(() => {
                if (nowDate.Year < 1880)
                {
                    nowDate = MiscData.GetNowDateTime().Date;
                }
                return(nowDate);
            });
            DateTime retVal = DateTime.MinValue;
            List <GroupPermission> listGroupPerms = GetForUserGroups(listUserGroupNums, permission);
            //get the permission that applies
            GroupPermission perm = listGroupPerms.OrderBy((GroupPermission y) => {
                if (y.NewerDays == 0 && y.NewerDate == DateTime.MinValue)
                {
                    return(DateTime.MinValue);
                }
                if (y.NewerDays == 0)
                {
                    return(y.NewerDate);
                }
                return(getNowDate().AddDays(-y.NewerDays));
            }).FirstOrDefault();

            if (perm == null)
            {
                //do not change retVal. The user does not have the permission.
            }
            else if (perm.NewerDate.Year < 1880 && perm.NewerDays == 0)
            {
                //do not change retVal. The user is not restricted by date.
            }
            else if (perm.NewerDate.Year > 1880)
            {
                retVal = perm.NewerDate;
            }
            else if (getNowDate().AddDays(-perm.NewerDays) > retVal)
            {
                retVal = getNowDate().AddDays(-perm.NewerDays);
            }
            return(retVal);
        }
Пример #26
0
        ///<summary>Returns the PK of the signal inserted if only one signal was passed in; Otherwise, returns 0.</summary>
        public static long Insert(params Signalod[] arraySignals)
        {
            if (arraySignals == null || arraySignals.Length < 1)
            {
                return(0);
            }
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                long signalNum = Meth.GetLong(MethodBase.GetCurrentMethod(), arraySignals);
                if (arraySignals.Length == 1)
                {
                    arraySignals[0].SignalNum = signalNum;
                }
                return(signalNum);
            }
            if (RemotingClient.RemotingRole == RemotingRole.ServerWeb)
            {
                //Make an in-memory list out of the array so that we can manipulate it without actually removing any entries passed in (for our insert below).
                List <Signalod> listSignals = arraySignals.ToList();
                //Refresh the cache now so that we don't have to refresh the cache when the clients update their cache.
                List <Signalod> listFeeSchedSignals = listSignals.Where(x => x.IType == InvalidType.Fees && x.FKeyType == KeyType.FeeSched && x.FKey > 0).ToList();
                foreach (Signalod signal in listFeeSchedSignals)
                {
                    Fees.InvalidateFeeSchedule(signal.FKey);
                }
                //Remove any signals from our list that we've already taken care of.
                listSignals.RemoveAll(x => x.IType == InvalidType.Fees && x.FKeyType == KeyType.FeeSched && x.FKey > 0);
                Cache.Refresh(listSignals.Select(x => x.IType).Distinct().ToArray());
            }
            //We need to explicitly get the server time in advance rather than using NOW(), because we need to update the signal object soon after creation.
            DateTime dateTimeNow = MiscData.GetNowDateTime();

            foreach (Signalod signal in arraySignals)
            {
                signal.SigDateTime = dateTimeNow;
                signal.RemoteRole  = RemotingClient.RemotingRole;
            }
            if (arraySignals.Length == 1)
            {
                return(Crud.SignalodCrud.Insert(arraySignals[0]));
            }
            Crud.SignalodCrud.InsertMany(arraySignals.ToList());
            return(0);
        }
Пример #27
0
        ///<summary>Inserts a signal for each operatory in the schedule that has been changed, and for the provider the schedule is for. This only
        ///inserts a signal for today's schedules. Generally should not be called outside of Schedules.cs</summary>
        public static void SetInvalidSched(params Schedule[] arraySchedules)
        {
            //No need to check RemotingRole; no call to db.
            //Per Nathan, we are only going to insert signals for today's schedules. Most workstations will not be looking at other days for extended
            //lengths of time.
            //Make an array of signals for every operatory involved.
            DateTime serverTime = MiscData.GetNowDateTime();

            Signalod[] arrayOpSignals = arraySchedules
                                        .Where(x => x.SchedDate.Date == DateTime.Today || x.SchedDate.Date == serverTime.Date)
                                        .SelectMany(x => x.Ops.Select(y => new Signalod()
            {
                IType       = InvalidType.Schedules,
                DateViewing = x.SchedDate,
                FKey        = y,
                FKeyType    = KeyType.Operatory,
            }))
                                        .ToArray();
            //Make a array of signals for every provider involved.
            Schedule[] arrayProviderSchedules = arraySchedules.Where(x => x.ProvNum > 0).ToArray();
            Signalod[] arrayProviderSignals   = arrayProviderSchedules
                                                .Where(x => x.SchedDate.Date == DateTime.Today || x.SchedDate.Date == serverTime.Date)
                                                .Select(x => new Signalod()
            {
                IType       = InvalidType.Schedules,
                DateViewing = x.SchedDate,
                FKey        = x.ProvNum,
                FKeyType    = KeyType.Provider,
            })
                                                .ToArray();
            Signalod[] arrayUniqueSignals = arrayOpSignals.Union(arrayProviderSignals).ToArray();
            if (arrayUniqueSignals.Length > 1000)
            {
                //We've had offices insert tens of thousands of signals at once which severely slowed down their database.
                Signalod signal = new Signalod {
                    IType       = InvalidType.Schedules,
                    DateViewing = DateTime.MinValue,                  //This will cause every workstation to refresh regardless of what they're viewing.
                };
                Insert(signal);
                return;
            }
            Insert(arrayUniqueSignals);
        }
Пример #28
0
        ///<summary>Process all Signals and Acks Since a given DateTime.  Only to be used by OpenDentalWebService.
        ///Returns latest valid signal Date/Time and the list of InvalidTypes that were refreshed.
        ///Can throw exception.</summary>
        public static List <InvalidType> RefreshForWeb()
        {
            InvalidTypeHistory.InitIfNecessary();
            int defaultProcessSigsIntervalInSecs = 7;

            ODException.SwallowAnyException(() => defaultProcessSigsIntervalInSecs = PrefC.GetInt(PrefName.ProcessSigsIntervalInSecs));
            if (DateTime.Now.Subtract(SignalLastRefreshedWeb) <= TimeSpan.FromSeconds(defaultProcessSigsIntervalInSecs))
            {
                return(new List <InvalidType>());
            }
            InvalidType[] arrayInvalidTypes = new InvalidType[0];
            //No need to check RemotingRole; no call to db.
            List <Signalod> listSignals = new List <Signalod>();

            try {
                if (SignalLastRefreshedWeb.Year < 1880)                //First signals for this session so go back in time a bit.
                {
                    SignalLastRefreshedWeb = MiscData.GetNowDateTime().AddSeconds(-1);
                }
                listSignals = Signalods.RefreshTimed(SignalLastRefreshedWeb);
                if (listSignals.Count > 0)                  //Next lower bound is current upper bound.
                {
                    SignalLastRefreshedWeb = listSignals.Max(x => x.SigDateTime);
                }
                arrayInvalidTypes = Signalods.GetInvalidTypesForWeb(listSignals);
                //Get all invalid types since given time and refresh the cache for those given invalid types.
                Cache.Refresh(arrayInvalidTypes);
            }
            catch (Exception e) {
                //Most likely cause for an exception here would be a thread collision between 2 consumers trying to refresh the cache at the exact same instant.
                //There is a chance that performing as subsequent refresh here would cause yet another collision but it's the best we can do without redesigning the entire cache pattern.
                Cache.Refresh(InvalidType.AllLocal);
                //Reset the last signal process time.
                DateTime dateTimeNow = DateTime.Now;
                ODException.SwallowAnyException(() => dateTimeNow = OpenDentBusiness.MiscData.GetNowDateTime());
                SignalLastRefreshedWeb = dateTimeNow;
                throw new Exception("Server cache may be invalid. Please try again. Error: " + e.Message);
            }
            InvalidTypeHistory.UpdateStatus(SignalLastRefreshedWeb, listSignals, arrayInvalidTypes);
            return(arrayInvalidTypes.ToList());
        }
Пример #29
0
        ///<summary>Used when viewing various audit trails of specific types.  This overload will return security logs for multiple objects (or fKeys).
        ///Typically you will only need a specific type audit log for one type.
        ///However, for things like ortho charts, each row (FK) in the database represents just one part of a larger ortho chart "object".
        ///Thus, to get the full experience of a specific type audit trail window, we need to get security logs for multiple objects (FKs) that
        ///comprise the larger object (what the user sees).  Only implemented with ortho chart so far.  FKeys can be null.
        ///Throws exceptions.</summary>
        public static SecurityLog[] Refresh(long patNum, List <Permissions> permTypes, List <long> fKeys, bool includeArchived)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <SecurityLog[]>(MethodBase.GetCurrentMethod(), patNum, permTypes, fKeys, includeArchived));
            }
            string types = "";

            for (int i = 0; i < permTypes.Count; i++)
            {
                if (i > 0)
                {
                    types += " OR";
                }
                types += " PermType=" + POut.Long((int)permTypes[i]);
            }
            string command = "SELECT * FROM securitylog "
                             + "WHERE (" + types + ") ";

            if (fKeys != null && fKeys.Count > 0)
            {
                command += "AND FKey IN (" + String.Join(",", fKeys) + ") ";
            }
            if (patNum != 0)           //appointments
            {
                command += " AND PatNum IN (" + string.Join(",",
                                                            PatientLinks.GetPatNumsLinkedToRecursive(patNum, PatientLinkType.Merge).Select(x => POut.Long(x))) + ")";
            }
            command += "ORDER BY LogDateTime";
            List <SecurityLog> listLogs = Crud.SecurityLogCrud.SelectMany(command);

            if (includeArchived)
            {
                //This will purposefully throw exceptions.
                listLogs.AddRange(MiscData.RunFuncOnArchiveDatabase <List <SecurityLog> >(() => {
                    return(Crud.SecurityLogCrud.SelectMany(command));
                }));
            }
            return(listLogs.OrderBy(x => x.LogDateTime).ToArray());
        }
Пример #30
0
        ///<summary>Will throw an exception if already clocked out.</summary>
        public static void ClockOut(long employeeNum, TimeClockStatus clockStatus)
        {
            ClockEvent clockEvent = ClockEvents.GetLastEvent(employeeNum);

            if (clockEvent == null)           //new employee never clocked in
            {
                throw new Exception(Lans.g("ClockEvents", "Error.  New employee never clocked in."));
            }
            else if (clockEvent.ClockStatus == TimeClockStatus.Break)           //only incomplete breaks will have been returned.
            {
                throw new Exception(Lans.g("ClockEvents", "Error.  Already clocked out for break."));;
            }
            else                                              //normal clock in/out
            {
                if (clockEvent.TimeDisplayed2.Year < 1880)    //clocked in.
                {
                    if (clockStatus == TimeClockStatus.Break) //clocking out on break
                    //leave the half-finished event alone and start a new one
                    {
                        clockEvent             = new ClockEvent();
                        clockEvent.EmployeeNum = employeeNum;
                        clockEvent.ClockStatus = TimeClockStatus.Break;
                        ClockEvents.Insert(clockEvent); //times handled
                    }
                    else                                //finish the existing event
                    {
                        clockEvent.TimeEntered2   = MiscData.GetNowDateTime();
                        clockEvent.TimeDisplayed2 = clockEvent.TimeEntered2;
                        clockEvent.ClockStatus    = clockStatus;                   //whatever the user selected
                        ClockEvents.Update(clockEvent);
                    }
                }
                else                  //clocked out for home or lunch.
                {
                    throw new Exception(Lans.g("ClockEvents", "Error.  Already clocked out."));
                }
            }
        }