Пример #1
0
        ///<summary>Kills the processes OpenDental and WebCamOD and then starts a file copier thread.</summary>
        private void StartFileCopierThread()
        {
            Cursor = Cursors.WaitCursor;
            if (_doKillServices)             //Generally kill except when dealing with DynamicMode
            //kill all processes named OpenDental.
            //If the software has been rebranded, the original exe will NOT be correctly closed.
            {
                KillProcess("OpenDental");
                //kill all processes named WebCamOD.
                //web cam does not always close properly when updater kills OpenDental
                //web cam relies on shared library, OpenDentBusiness.dll (shared ref with OpenDental).
                //if this lib can't be updated then the opendental update/install fails
                KillProcess("WebCamOD");
                KillProcess("ProximityOD");
                //Kill known applications that are present within the installation directory so that the resources are freed if currently in use.
                //A customer complained on the forums about CentralManager explicitly.  DatabaseIntegrityCheck and ServiceManager are just in case.
                KillProcess("CentralManager");
                KillProcess("DatabaseIntegrityCheck");
                KillProcess("ServiceManager");
                //Create a separate thread to copy over the files from the UpdateFiles folder share.
                //In putting this logic in a thread, the user can close the window and not disrupt the copying process.
            }
            ODThread odThread = new ODThread(OnThreadStart);

            odThread.AddExitHandler(OnThreadComplete);
            odThread.Start(true);
        }
        ///<summary></summary>
        private string RunWebMethod(Func <string> funcWebMethod)
        {
            Exception    ex = null;
            RemotingRole remotingRoleCur = RemotingClient.RemotingRole;
            //Create an ODThread so that we can safely change the database connection settings without affecting the calling method's connection.
            ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => {
                //Change the remoting role to ServerWeb (this will get set back to remotingRoleCur later.
                RemotingClient.RemotingRole = RemotingRole.ServerWeb;
                //Set new database connection settings if designated.  E.g. some unit tests need to set and utilize userLow and passLow.
                if (!string.IsNullOrEmpty(_server) &&
                    !string.IsNullOrEmpty(_db) &&
                    !string.IsNullOrEmpty(_user))
                {
                    new DataConnection().SetDbT(_server, _db, _user, _password, _userLow, _passLow, DatabaseType.MySql);
                }
                //Execute the func that was passed in now that our remoting role and database connection are correct.
                o.Tag = funcWebMethod();
            }));

            odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => {
                ex = e;              //Cannot throw exception here due to still being in a threaded context.
            }));
            if (ex != null)
            {
                throw ex;                //Should never happen because this would be a "web exception" as in the ProcessRequest could not even invoke or something like that.
            }
            odThread.Name = "threadMiddleTierUnitTestRunWebMethod";
            //Set the remoting role back after exiting the thread.
            odThread.AddExitHandler((e) => RemotingClient.RemotingRole = remotingRoleCur);
            odThread.Start(true);
            odThread.Join(System.Threading.Timeout.Infinite);
            return((string)odThread.Tag);
        }
Пример #3
0
 ///<summary></summary>
 public static void Open(Claim claim, Action actionOkClick = null)
 {
     //Show a dialog if the user tries to open more than one claim at a time
     if (_threadFormClaimAttach != null)
     {
         MsgBox.Show("A claim attachment window is already open.");
         return;
     }
     _threadFormClaimAttach = new ODThread(new ODThread.WorkerDelegate((ODThread o) => {
         FormClaimAttachment formCA = new FormClaimAttachment(claim);
         if (formCA.ShowDialog() == DialogResult.OK)
         {
             actionOkClick?.Invoke();
         }
     }));
     //This thread needs to be STA because FormClaimAttachment will have the ability to open child forms,
     //which will need to block FormClaimAttachment while it is open.
     //STA mode is the only way to have ShowDialog() behavior in a non-main thread,
     //without throwing an exception (the exception literally says change the thread to STA)
     _threadFormClaimAttach.SetApartmentState(System.Threading.ApartmentState.STA);
     _threadFormClaimAttach.AddExitHandler(new ODThread.WorkerDelegate((ODThread o) => {
         _threadFormClaimAttach = null;
     }));
     _threadFormClaimAttach.Start(true);
 }
        private void FillGridWebSchedTimeSlotsThreaded()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke((Action) delegate() {
                    FillGridWebSchedTimeSlotsThreaded();
                });
                return;
            }
            //Validate time slot settings.
            if (textWebSchedDateStart.errorProvider1.GetError(textWebSchedDateStart) != "")
            {
                //Don't bother warning the user.  It will just be annoying.  The red indicator should be sufficient.
                return;
            }
            if (comboWebSchedRecallTypes.SelectedIndex < 0 ||
                comboWebSchedClinic.SelectedIndex < 0 ||
                comboWebSchedProviders.SelectedIndex < 0)
            {
                return;
            }
            //Protect against re-entry
            if (_threadFillGridWebSchedTimeSlots != null)
            {
                //A thread is already refreshing the time slots grid so we simply need to queue up another refresh once the one thread has finished.
                _isWebSchedTimeSlotsOutdated = true;
                return;
            }
            _isWebSchedTimeSlotsOutdated = false;
            DateTime        dateStart     = PIn.Date(textWebSchedDateStart.Text);
            RecallType      recallType    = _listRecallTypes[comboWebSchedRecallTypes.SelectedIndex];
            Clinic          clinic        = _listWebSchedClinics.Find(x => x.ClinicNum == _webSchedClinicNum); //null clinic is treated as unassigned.
            List <Provider> listProviders = new List <Provider>(_listWebSchedProviders);                       //Use all providers by default.
            Provider        provider      = _listWebSchedProviders.Find(x => x.ProvNum == _webSchedProvNum);

            if (provider != null)
            {
                //Only use the provider that the user picked from the provider picker.
                listProviders = new List <Provider>()
                {
                    provider
                };
            }
            WebSchedTimeSlotArgs webSchedTimeSlotArgs = new WebSchedTimeSlotArgs()
            {
                RecallTypeCur = recallType,
                ClinicCur     = clinic,
                DateStart     = dateStart,
                DateEnd       = dateStart.AddDays(30),
                ListProviders = listProviders
            };

            _threadFillGridWebSchedTimeSlots      = new ODThread(GetWebSchedTimeSlotsWorker, webSchedTimeSlotArgs);
            _threadFillGridWebSchedTimeSlots.Name = "ThreadWebSchedRecallTimeSlots";
            _threadFillGridWebSchedTimeSlots.AddExitHandler(GetWebSchedTimeSlotsThreadExitHandler);
            _threadFillGridWebSchedTimeSlots.AddExceptionHandler(GetWebSchedTimeSlotsExceptionHandler);
            _threadFillGridWebSchedTimeSlots.Start(true);
        }
Пример #5
0
 ///<summary>Starts the thread which will populate the graph's data. DB context should be set before calling this method.</summary>
 /// <param name="forceCacheRefesh">Will pass this flag along to the thread which retrieves the cache. If true then cache will be invalidated and re-initialiazed from the db. Use sparingly.</param>
 /// <param name="onException">Exception handler if something fails. If not set then all exceptions will be swallowed.</param>
 /// <param name="onThreadDone">Done event handler. Will be invoked when init thread has completed.</param>
 private void Init(bool forceCacheRefesh = false, ODThread.ExceptionDelegate onException = null, EventHandler onThreadDone = null)
 {
     if (_thread != null)
     {
         return;
     }
     if (onThreadDone == null)
     {
         onThreadDone = new EventHandler(delegate(object o, EventArgs e) { });
     }
     if (onException == null)
     {
         onException = new ODThread.ExceptionDelegate((Exception e) => { });
     }
     _thread = new ODThread(new ODThread.WorkerDelegate((ODThread x) => {
         //The thread may have run and return before the window is even ready to display.
         if (this.IsHandleCreated)
         {
             OnThreadStartLocal(this, new EventArgs());
         }
         else
         {
             this.HandleCreated += OnThreadStartLocal;
         }
         //Alert caller that it's time to start querying the db.
         OnInit(forceCacheRefesh);
     }));
     _thread.Name = "GraphQuantityFilterOverTime.Init";
     _thread.AddExceptionHandler(onException);
     _thread.AddExitHandler(new ODThread.WorkerDelegate((ODThread x) => {
         try {
             _thread = null;
             //The thread may have run and return before the window is even ready to display.
             if (this.IsHandleCreated)
             {
                 OnThreadExitLocal(this, new EventArgs());
             }
             else
             {
                 this.HandleCreated += OnThreadExitLocal;
             }
             //Alert caller that db querying is done.
             onThreadDone(this, new EventArgs());
         }
         catch (Exception) { }
     }));
     _thread.Start(true);
 }
Пример #6
0
 private void StartShouldCloseMonitor()
 {
     if (_threadShouldWindowClose != null)
     {
         return;
     }
     _threadShouldWindowClose = new ODThread(500, (o) => {
         if (_shouldWindowClose)
         {
             ODException.SwallowAnyException(() => {
                 Invoke(new Action(() => { DialogResult = DialogResult.OK; }));
             });
             o.QuitAsync();
         }
     });
     _threadShouldWindowClose.Name = "FormConnectionLost_ShouldCloseMonitorThread";
     _threadShouldWindowClose.AddExceptionHandler((e) => e.DoNothing());
     _threadShouldWindowClose.AddExitHandler((e) => _threadShouldWindowClose = null);
     _threadShouldWindowClose.Start();
 }
Пример #7
0
 private void FormShowFeatures_Load(object sender, System.EventArgs e)
 {
     checkCapitation.Checked    = !PrefC.GetBool(PrefName.EasyHideCapitation);
     checkMedicaid.Checked      = !PrefC.GetBool(PrefName.EasyHideMedicaid);
     checkPublicHealth.Checked  = !PrefC.GetBool(PrefName.EasyHidePublicHealth);
     checkDentalSchools.Checked = !PrefC.GetBool(PrefName.EasyHideDentalSchools);
     checkHospitals.Checked     = !PrefC.GetBool(PrefName.EasyHideHospitals);
     checkInsurance.Checked     = !PrefC.GetBool(PrefName.EasyHideInsurance);
     checkClinical.Checked      = !PrefC.GetBool(PrefName.EasyHideClinical);
     checkBasicModules.Checked  = PrefC.GetBool(PrefName.EasyBasicModules);
     _isClinicsEnabledInDb      = PrefC.HasClinicsEnabled;
     RestoreClinicCheckBox();
     checkRepeatCharges.Checked = !PrefC.GetBool(PrefName.EasyHideRepeatCharges);
     checkMedicalIns.Checked    = PrefC.GetBool(PrefName.ShowFeatureMedicalInsurance);
     checkEhr.Checked           = PrefC.GetBool(PrefName.ShowFeatureEhr);
     checkSuperFam.Checked      = PrefC.GetBool(PrefName.ShowFeatureSuperfamilies);
     checkPatClone.Checked      = PrefC.GetBool(PrefName.ShowFeaturePatientClone);
     checkQuestionnaire.Checked = PrefC.GetBool(PrefName.AccountShowQuestionnaire);
     checkTrojanCollect.Checked = PrefC.GetBool(PrefName.AccountShowTrojanExpressCollect);
     if (Security.IsAuthorized(Permissions.SecurityAdmin, true))
     {
         //Default error until this thread finishes.
         _signupException    = new Exception(Lan.g(this, "Signup info is still loading"));
         _threadSignupPortal = new ODThread(new ODThread.WorkerDelegate((th) => {
             _signupOut = WebServiceMainHQProxy.GetEServiceSetupFull(SignupPortalPermission.FullPermission);
             //We go this far so allow checkNoClinics_Click().
             _signupException = null;
         }));
         _threadSignupPortal.AddExceptionHandler(new ODThread.ExceptionDelegate((ex) => { _signupException = ex; }));
         _threadSignupPortal.AddExitHandler(new ODThread.WorkerDelegate((th) => { _threadSignupPortal = null; }));
         _threadSignupPortal.Start();
     }
     else
     {
         _signupException = new Exception(Lan.g("Security", "Not authorized for") + "\r\n" + GroupPermissions.GetDesc(Permissions.SecurityAdmin));
     }
 }
Пример #8
0
        ///<summary>Retreives new signals from the DB, updates Caches, and broadcasts signals to all subscribed forms.</summary>
        public static void SignalsTick(Action onShutdown, Action <List <ISignalProcessor>, List <Signalod> > onProcess, Action onDone)
        {
            //No need to check RemotingRole; no call to db.
            Logger.LogToPath("", LogPath.Signals, LogPhase.Start);
            List <Signalod> listSignals          = new List <Signalod>();
            ODThread        threadRefreshSignals = new ODThread(new ODThread.WorkerDelegate((o) => {
                //Get new signals from DB.
                Logger.LogToPath("RefreshTimed", LogPath.Signals, LogPhase.Start);
                listSignals = RefreshTimed(SignalLastRefreshed);
                Logger.LogToPath("RefreshTimed", LogPath.Signals, LogPhase.End);
                //Only update the time stamp with signals retreived from the DB. Do NOT use listLocalSignals to set timestamp.
                if (listSignals.Count > 0)
                {
                    SignalLastRefreshed = listSignals.Max(x => x.SigDateTime);
                }
                Logger.LogToPath("Found " + listSignals.Count.ToString() + " signals", LogPath.Signals, LogPhase.Unspecified);
                if (listSignals.Count == 0)
                {
                    return;
                }
                Logger.LogToPath("Signal count(s)", LogPath.Signals, LogPhase.Unspecified, string.Join(" - ", listSignals.GroupBy(x => x.IType).Select(x => x.Key.ToString() + ": " + x.Count())));
                if (listSignals.Exists(x => x.IType == InvalidType.ShutDownNow))
                {
                    onShutdown();
                    return;
                }
                List <Signalod> listFeeSignals = listSignals.FindAll(x => x.IType == InvalidType.Fees && x.FKeyType == KeyType.FeeSched && x.FKey > 0);
                if (listFeeSignals.Count > 0)
                {
                    Fees.InvalidateFeeSchedules(listFeeSignals.Select(x => x.FKey).ToList());
                }
                InvalidType[] cacheRefreshArray = listSignals.FindAll(x => x.FKey == 0 && x.FKeyType == KeyType.Undefined).Select(x => x.IType).Distinct().ToArray();
                //Always process signals for ClientDirect users regardless of where the RemoteRole source on the signal is from.
                //The middle tier server will have refreshed its cache already.
                bool getCacheFromDb = true;
                if (RemotingClient.RemotingRole == RemotingRole.ClientWeb &&
                    !listSignals.Any(x => x.RemoteRole == RemotingRole.ClientDirect))
                {
                    //ClientWebs do not need to tell the middle tier to go to the database unless a ClientDirect has inserted a signal.
                    getCacheFromDb = false;
                }
                Cache.Refresh(getCacheFromDb, cacheRefreshArray);
                onProcess(_listISignalProcessors, listSignals);
            }));

            threadRefreshSignals.AddExceptionHandler(new ODThread.ExceptionDelegate((e) => {
                DateTime dateTimeRefreshed;
                try {
                    //Signal processing should always use the server's time.
                    dateTimeRefreshed = MiscData.GetNowDateTime();
                }
                catch {
                    //If the server cannot be reached, we still need to move the signal processing forward so use local time as a fail-safe.
                    dateTimeRefreshed = DateTime.Now;
                }
                SignalLastRefreshed = dateTimeRefreshed;
            }));
            threadRefreshSignals.AddExitHandler(new ODThread.WorkerDelegate((o) => {
                Logger.LogToPath("", LogPath.Signals, LogPhase.End);
                onDone();
            }));
            threadRefreshSignals.Name = "SignalsTick";
            threadRefreshSignals.Start(true);
        }
Пример #9
0
        private void FillGridWebSchedNewPatApptTimeSlotsThreaded()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke((Action) delegate() {
                    FillGridWebSchedNewPatApptTimeSlotsThreaded();
                });
                return;
            }
            if (comboWSNPADefApptType.GetSelected <Def>() == null)
            {
                if (tabControl.SelectedTab == tabWebSched && tabControlWebSched.SelectedTab == tabWebSchedNewPatAppts)
                {
                    MsgBox.Show(this, "Set a Web Sched New Pat Appt Type in Definitions to show appointment time slots.");
                }
                return;
            }
            //Clear the current grid rows before starting the thread below. This allows that thread to exit at any time without leaving old rows in the grid.
            gridWebSchedNewPatApptTimeSlots.BeginUpdate();
            gridWebSchedNewPatApptTimeSlots.ListGridRows.Clear();
            gridWebSchedNewPatApptTimeSlots.EndUpdate();
            //Validate time slot settings.
            if (textWebSchedNewPatApptsDateStart.errorProvider1.GetError(textWebSchedNewPatApptsDateStart) != "")
            {
                //Don't bother warning the user.  It will just be annoying.  The red indicator should be sufficient.
                return;
            }
            if (!PrefC.HasClinicsEnabled)
            {
                comboWSNPClinics.SelectedIndex = 0;              //Not visible but this will set the combo box the "N/A" which is the non-clinic signup
            }
            if (comboWSNPClinics.SelectedIndex < 0)
            {
                return;                //Nothing to do.
            }
            WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutEService signup = ((ODBoxItem <WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutEService>)comboWSNPClinics.SelectedItem).Tag;
            //Protect against re-entry
            if (_threadFillGridWebSchedNewPatApptTimeSlots != null)
            {
                //A thread is already refreshing the time slots grid so we simply need to queue up another refresh once the one thread has finished.
                _isWebSchedNewPatApptTimeSlotsOutdated = true;
                return;
            }
            _isWebSchedNewPatApptTimeSlotsOutdated = false;
            _indexLastNewPatURL = comboWSNPClinics.SelectedIndex;
            DateTime dateStart = PIn.DateT(textWebSchedNewPatApptsDateStart.Text);
            DateTime dateEnd   = dateStart.AddDays(30);

            if (!signup.IsEnabled)
            {
                return;                //Do nothing, this clinic is excluded from New Pat Appts.
            }
            //Only get time slots for headquarters or clinics that are NOT excluded (aka included).
            var args = new {
                ClinicNum   = signup.ClinicNum,
                DateStart   = dateStart,
                DateEnd     = dateStart.AddDays(30),
                DefApptType = comboWSNPADefApptType.GetSelected <Def>(),
            };

            _threadFillGridWebSchedNewPatApptTimeSlots = new ODThread(new ODThread.WorkerDelegate((th) => {
                //The user might not have Web Sched ops set up correctly.  Don't warn them here because it is just annoying.  They'll figure it out.
                ODException.SwallowAnyException(() => {
                    //Get the next 30 days of open time schedules with the current settings
                    List <TimeSlot> listTimeSlots = TimeSlots.GetAvailableNewPatApptTimeSlots(args.DateStart, args.DateEnd, args.ClinicNum
                                                                                              , args.DefApptType.DefNum);
                    FillGridWebSchedNewPatApptTimeSlots(listTimeSlots);
                });
            }))
            {
                Name = "ThreadWebSchedNewPatApptTimeSlots"
            };
            _threadFillGridWebSchedNewPatApptTimeSlots.AddExitHandler(new ODThread.WorkerDelegate((th) => {
                _threadFillGridWebSchedNewPatApptTimeSlots = null;
                //If something else wanted to refresh the grid while we were busy filling it then we need to refresh again.  A filter could have changed.
                if (_isWebSchedNewPatApptTimeSlotsOutdated)
                {
                    FillGridWebSchedNewPatApptTimeSlotsThreaded();
                }
            }));
            _threadFillGridWebSchedNewPatApptTimeSlots.Start(true);
        }