private void butHideUnused_Click(object sender, EventArgs e) { if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "Hide fee schedules that are not in use by insurance plans, patients, or providers?\r\n" + "A backup of the database will be made first.")) { return; } bool hasChanged = FeeScheds.Sync(_listFeeScheds, _listFeeSchedsOld); Action actionProgress = ODProgress.Show(ODEventType.HideUnusedFeeSchedules, startingMessage: Lans.g(this, "Backing up database...")); try { MiscData.MakeABackup(); } catch (Exception ex) { actionProgress?.Invoke(); FriendlyException.Show(Lans.g(this, "Unable to make a backup. No fee schedules have been altered."), ex); return; } ODEvent.Fire(ODEventType.HideUnusedFeeSchedules, Lans.g(this, "Hiding unused fee schedules...")); long countChanged = FeeScheds.HideUnusedScheds(); if (hasChanged || countChanged > 0) { DataValid.SetInvalid(InvalidType.FeeScheds); } actionProgress?.Invoke(); MessageBox.Show(countChanged.ToString() + " " + Lans.g(this, "unused fee schedules hidden.")); _listFeeScheds = FeeScheds.GetDeepCopy(_isSelectionMode); _listFeeSchedsOld = _listFeeScheds.Select(x => x.Copy()).ToList(); FillGrid(); }
///<summary>Using shown so we can properly display a progress bar on the initial fillgrid.</summary> private void FormFamilyBalancer_Shown(object sender, EventArgs e) { Action actionCloseProgress = ODProgress.Show(ODEventType.Billing, startingMessage: "Loading first batch. Please wait..."); FillNextBatch(); actionCloseProgress(); }
private void butGetNextBatch_Click(object sender, EventArgs e) { Action actionCloseProgress = ODProgress.Show(ODEventType.Billing, startingMessage: "Retrieving family information. Please wait..."); ODEvent.Fire(ODEventType.Billing, Lan.g(this, "Filling the grid. This may take awhile...")); FillNextBatch(); actionCloseProgress(); }
private void butSynch_Click(object sender, EventArgs e) { Cursor = Cursors.WaitCursor; GC.Collect(); //free up resources since this could take a lot of memory DataValid.SetInvalid(InvalidType.RecallTypes); Action actionCloseRecallSyncProgress = ODProgress.Show(ODEventType.RecallSync, typeof(RecallSyncEvent), Lan.g(this, "Running Prep Queries") + "...", false, true); bool isSyncCompleted = Recalls.SynchAllPatients(); actionCloseRecallSyncProgress?.Invoke(); GC.Collect(); //clean up resources, force the garbage collector to collect since resources may remain tied-up Cursor = Cursors.Default; if (isSyncCompleted) { changed = false; MsgBox.Show(this, "Done."); } else { MsgBox.Show(this, "Synch is currently running from a different workstation."); } }
private void FormEServicesSetup_FormClosing(object sender, FormClosingEventArgs e) { if (DialogResult == DialogResult.Abort || !Security.IsAuthorized(Permissions.EServicesSetup, true)) { return; } //Anything they could have modified should have been disabled on load anyways. if (!SaveForm()) //Something failed. Ask the user if they are ok with exiting and not saving. { if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "Validation failed and no changes were saved. Would you like to close without saving?")) { //User wants to keep the form open. e.Cancel = true; } } //Call this a second time so we can log if any important changes were made to this form. //_signupOut gets filled on load and should not be null at this point Action actionCloseProgress = ODProgress.Show(ODEventType.EServices, typeof(EServicesEvent), "Saving eServices..."); WebServiceMainHQProxy.GetEServiceSetupFull(GetUserSignupPortalPermissions(), oldSignupOut: _signupOut); actionCloseProgress?.Invoke(); }
private void FormRecallTypes_FormClosing(object sender, FormClosingEventArgs e) { if (changed) { DataValid.SetInvalid(InvalidType.RecallTypes); if (MessageBox.Show(Lan.g(this, "Recalls for all patients should be synchronized. Synchronize now?"), "", MessageBoxButtons.YesNo) == DialogResult.Yes) { Cursor = Cursors.WaitCursor; GC.Collect(); //free up resources since this could take a lot of memory Action actionCloseRecallSyncProgress = ODProgress.Show(ODEventType.RecallSync, typeof(RecallSyncEvent), Lan.g(this, "Running Prep Queries") + "..."); bool isSyncSuccessful = Recalls.SynchAllPatients(); actionCloseRecallSyncProgress?.Invoke(); GC.Collect(); //clean up resources, force the garbage collector to collect since resources may remain tied-up Cursor = Cursors.Default; if (!isSyncSuccessful) { MsgBox.Show(this, "Synch is currently running from a different workstation. Recalls should be synchronized again later."); } } } }
private void FillGridMain() { string[] searchTokens = textSearch.Text.ToLower().Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); long[] userNums = new long[0]; JobCategory[] jobCats = new JobCategory[0]; JobPhase[] jobPhases = new JobPhase[0]; long[] jobPriorities = new long[0]; if (listBoxUsers.SelectedIndices.Count > 0 && !listBoxUsers.SelectedIndices.Contains(0)) { userNums = listBoxUsers.SelectedIndices.Cast <int>().Select(x => _listUsers[x - 1].UserNum).ToArray(); } if (listBoxCategory.SelectedIndices.Count > 0 && !listBoxCategory.SelectedIndices.Contains(0)) { jobCats = listBoxCategory.SelectedIndices.Cast <int>().Select(x => (JobCategory)(x - 1)).ToArray(); } if (listBoxPhases.SelectedIndices.Count > 0 && !listBoxPhases.SelectedIndices.Contains(0)) { jobPhases = listBoxPhases.SelectedIndices.Cast <int>().Select(x => (JobPhase)(x - 1)).ToArray(); } if (listBoxPriorities.SelectedIndices.Count > 0 && !listBoxPriorities.SelectedIndices.Contains(0)) { jobPriorities = listBoxPriorities.GetListSelected <Def>().Select(x => x.DefNum).ToArray(); } Action actionCloseProgress = ODProgress.Show(ODEventType.Job, typeof(JobEvent), "Getting job data..."); #region Get Missing Data //This entire section will go out to the database and get any data that is unknown based on some of the filters. //The other filters will be applied later via the cached lists. try { List <Job> listJobs = Jobs.GetForSearch(dateFrom.Value, dateTo.Value, jobPhases.ToList(), jobPriorities.ToList(), _listJobsAll.Select(x => x.JobNum).ToList()); Jobs.FillInMemoryLists(listJobs, true); _listJobsAll.AddRange(listJobs); } catch (OutOfMemoryException oome) { actionCloseProgress(); oome.DoNothing(); MsgBox.Show(this, "Not enough memory to complete the search. Please refine search filters."); return; } //Only get the feature request entries that we care about. JobEvent.Fire(ODEventType.Job, "Getting feature request data..."); List <long> listFeatureRequestNums = _listJobsAll.SelectMany(x => x.ListJobLinks) .Where(x => x.LinkType == JobLinkType.Request) .Select(x => x.FKey) .Distinct() .ToList(); //Don't download any feature requests that we already know about. listFeatureRequestNums.RemoveAll(x => x.In(_listFeatureRequestsAll.Select(y => y.FeatReqNum))); if (!listFeatureRequestNums.IsNullOrEmpty()) { _listFeatureRequestsAll.AddRange(FeatureRequests.GetAll(listFeatureRequestNums)); } //Only get the bug entries that we care about. JobEvent.Fire(ODEventType.Job, "Getting bug data..."); List <long> listBugIds = _listJobsAll.SelectMany(x => x.ListJobLinks) .Where(x => x.LinkType == JobLinkType.Bug) .Select(x => x.FKey) .Distinct() .ToList(); //Don't download any bugs that we already know about. listBugIds.RemoveAll(x => x.In(_listBugsAll.Select(y => y.BugId))); if (!listBugIds.IsNullOrEmpty()) { _listBugsAll.AddRange(Bugs.GetMany(listBugIds)); } #endregion JobEvent.Fire(ODEventType.Job, "Filling grid..."); gridMain.BeginUpdate(); gridMain.ListGridColumns.Clear(); gridMain.ListGridColumns.Add(new GridColumn("Job\r\nNum", 50, GridSortingStrategy.AmountParse)); gridMain.ListGridColumns.Add(new GridColumn("Priority", 50, HorizontalAlignment.Center)); gridMain.ListGridColumns.Add(new GridColumn("Phase", 85)); gridMain.ListGridColumns.Add(new GridColumn("Category", 80)); gridMain.ListGridColumns.Add(new GridColumn("Job Title", -1)); gridMain.ListGridColumns.Add(new GridColumn("Version", 80)); gridMain.ListGridColumns.Add(new GridColumn("Est. Version", 80)); gridMain.ListGridColumns.Add(new GridColumn("Expert", 75)); gridMain.ListGridColumns.Add(new GridColumn("Engineer", 75)); gridMain.ListGridColumns.Add(new GridColumn("Est.\r\nHours", 60, GridSortingStrategy.AmountParse)); gridMain.ListGridColumns.Add(new GridColumn("Act.\r\nHours", 60, GridSortingStrategy.AmountParse)); gridMain.ListGridColumns.Add(new GridColumn("Job\r\nMatch", 45, HorizontalAlignment.Center)); gridMain.ListGridColumns.Add(new GridColumn("Bug\r\nMatch", 45, HorizontalAlignment.Center)); gridMain.ListGridColumns.Add(new GridColumn("FR\r\nMatch", 45, HorizontalAlignment.Center)); gridMain.ListGridRows.Clear(); _listJobsFiltered = new List <Job>(); foreach (Job jobCur in _listJobsAll) { if (jobCats.Length > 0 && !jobCats.Contains(jobCur.Category)) { continue; } if (jobPhases.Length > 0 && !jobPhases.Contains(jobCur.PhaseCur)) { continue; } if (jobPriorities.Length > 0 && !jobPriorities.Contains(jobCur.Priority)) { continue; } if (userNums.Length > 0 && !userNums.All(x => Jobs.GetUserNums(jobCur).Contains(x))) { continue; } if (!jobCur.DateTimeEntry.Between(dateFrom.Value, dateTo.Value)) { continue; } bool isJobMatch = false; bool isBugMatch = false; bool isFeatureReqMatch = false; if (searchTokens.Length > 0) { bool addRow = false; List <Bug> listBugs = jobCur.ListJobLinks.FindAll(x => x.LinkType == JobLinkType.Bug) .Select(x => _listBugsAll.FirstOrDefault(y => x.FKey == y.BugId)) .Where(x => x != null) .ToList(); List <FeatureRequest> listFeatures = jobCur.ListJobLinks.FindAll(x => x.LinkType == JobLinkType.Request) .Select(x => _listFeatureRequestsAll.FirstOrDefault(y => x.FKey == y.FeatReqNum)) .Where(x => x != null) .ToList(); foreach (string token in searchTokens.Distinct()) { bool isFound = false; //JOB MATCHES if (jobCur.Title.ToLower().Contains(token) || jobCur.Implementation.ToLower().Contains(token) || jobCur.Requirements.ToLower().Contains(token) || jobCur.Documentation.ToLower().Contains(token) || jobCur.JobNum.ToString().Contains(token)) { isFound = true; isJobMatch = true; } //BUG MATCHES if (!isFound || !isBugMatch) { if (listBugs.Any(x => x.Description.ToLower().Contains(token) || x.Discussion.ToLower().Contains(token))) { isFound = true; isBugMatch = true; } } //FEATURE REQUEST MATCHES if (!isFound || !isFeatureReqMatch) { if (listFeatures.Any(x => x.Description.Contains(token) || x.FeatReqNum.ToString().ToLower().Contains(token))) { isFound = true; isFeatureReqMatch = true; } } addRow = isFound; if (!isFound) { break; //stop looking for additional tokens, we didn't find this one. } } if (!addRow) { continue; //we did not find one of the search terms. } } _listJobsFiltered.Add(jobCur); Def jobPriority = _listJobPriorities.FirstOrDefault(y => y.DefNum == jobCur.Priority); GridRow row = new GridRow(); row.Cells.Add(jobCur.JobNum.ToString()); row.Cells.Add(new GridCell(jobPriority.ItemName) { ColorBackG = jobPriority.ItemColor, ColorText = (jobCur.Priority == _listJobPriorities.FirstOrDefault(y => y.ItemValue.Contains("Urgent")).DefNum) ? Color.White : Color.Black, }); row.Cells.Add(jobCur.PhaseCur.ToString()); row.Cells.Add(jobCur.Category.ToString()); row.Cells.Add(jobCur.Title); row.Cells.Add(jobCur.JobVersion.ToString()); row.Cells.Add(jobCur.ProposedVersion.ToString()); row.Cells.Add(Userods.GetName(jobCur.UserNumExpert)); row.Cells.Add(Userods.GetName(jobCur.UserNumEngineer)); row.Cells.Add(jobCur.HoursEstimate.ToString()); row.Cells.Add(jobCur.HoursActual.ToString()); row.Cells.Add(isJobMatch ? "X" : ""); row.Cells.Add(isBugMatch ? "X" : ""); row.Cells.Add(new GridCell(isFeatureReqMatch ? "X" : "") { ColorBackG = _listFeatureRequestsAll.Count == 0 ? Control.DefaultBackColor : Color.Empty }); row.Tag = jobCur; gridMain.ListGridRows.Add(row); } gridMain.EndUpdate(); actionCloseProgress(); }
private void FillSubGrid(bool isRefreshNeeded = false, string grouping95 = "") { List <string> listSelectedVersions = listVersionsFilter.SelectedItems.OfType <string>().ToList(); if (listSelectedVersions.Contains("All")) { listSelectedVersions.Clear(); } if (isRefreshNeeded && listSelectedVersions.IsNullOrEmpty()) { if (!MsgBox.Show(MsgBoxButtons.YesNo, "All bug submissions are going to be downloaded...\r\nAre you sure about this?")) { return; } } Action loadingProgress = null; Cursor = Cursors.WaitCursor; #region gridSubs columns gridSubs.BeginUpdate(); gridSubs.ListGridColumns.Clear(); gridSubs.ListGridColumns.Add(new GridColumn("Submitter", 140)); gridSubs.ListGridColumns.Add(new GridColumn("Vers.", 55, GridSortingStrategy.VersionNumber)); if (comboGrouping.SelectedIndex == 0) //Group by 'None' { gridSubs.ListGridColumns.Add(new GridColumn("DateTime", 75, GridSortingStrategy.DateParse)); } else { gridSubs.ListGridColumns.Add(new GridColumn("#", 30, HorizontalAlignment.Right, GridSortingStrategy.AmountParse)); } gridSubs.ListGridColumns.Add(new GridColumn("Flag", 50, HorizontalAlignment.Center)); gridSubs.ListGridColumns.Add(new GridColumn("Msg Text", 0)); gridSubs.AllowSortingByColumn = true; gridSubs.ListGridRows.Clear(); #endregion bugSubmissionControl.ClearCustomerInfo(); bugSubmissionControl.SetTextDevNoteEnabled(false); if (isRefreshNeeded) { loadingProgress = ODProgress.Show(ODEventType.BugSubmission, typeof(BugSubmissionEvent), Lan.g(this, "Refreshing Data") + "..."); #region Refresh Logic if (_viewMode.In(FormBugSubmissionMode.ViewOnly, FormBugSubmissionMode.ValidationMode)) { _listAllSubs = ListViewedSubs; } else { BugSubmissionEvent.Fire(ODEventType.BugSubmission, Lan.g(this, "Refreshing Data: Bugs")); _listAllSubs = BugSubmissions.GetAllInRange(dateRangePicker.GetDateTimeFrom(), dateRangePicker.GetDateTimeTo(), listSelectedVersions); } try { BugSubmissionEvent.Fire(ODEventType.BugSubmission, Lan.g(this, "Refreshing Data: Patients")); _dictPatients = RegistrationKeys.GetPatientsByKeys(_listAllSubs.Select(x => x.RegKey).ToList()); } catch (Exception e) { e.DoNothing(); _dictPatients = new Dictionary <string, Patient>(); } BugSubmissionEvent.Fire(ODEventType.BugSubmission, Lan.g(this, "Refreshing Data: JobLinks")); _listJobLinks = JobLinks.GetManyForType(JobLinkType.Bug, _listAllSubs.Select(x => x.BugId).Where(x => x != 0).Distinct().ToList()); #endregion } #region Filter Logic BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Filtering Data"); List <BugSubmission> listFilteredSubs = null; List <string> listSelectedRegKeys = comboRegKeys.ListSelectedItems.Select(x => (string)x).ToList(); if (listSelectedRegKeys.Contains("All")) { listSelectedRegKeys.Clear(); } List <string> listStackFilters = textStackFilter.Text.Split(',') .Where(x => !string.IsNullOrWhiteSpace(x)) .Select(x => x.ToLower()).ToList(); List <string> listPatNumFilters = textPatNums.Text.Split(',') .Where(x => !string.IsNullOrWhiteSpace(x)) .Select(x => x.ToLower()).ToList(); _listAllSubs.ForEach(x => x.TagCustom = null); List <string> listCategoryFilters = textCategoryFilters.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); string msgText = textMsgText.Text; string devNoteFilter = textDevNoteFilter.Text; DateTime dateTimeFrom = dateRangePicker.GetDateTimeFrom(); DateTime dateTimeTo = dateRangePicker.GetDateTimeTo(); //Filter the list of all bug submissions and then order it by program version and submission date time so that the grouping is predictable. listFilteredSubs = _listAllSubs.Where(x => PassesFilterValidation(x, listCategoryFilters, listSelectedRegKeys, listStackFilters, listPatNumFilters, listSelectedVersions, grouping95, msgText, devNoteFilter, dateTimeFrom, dateTimeTo) ) .OrderByDescending(x => new Version(x.ProgramVersion)) .ThenByDescending(x => x.SubmissionDateTime) .ToList(); if (isRefreshNeeded) { FillPatNameFilter(_listAllSubs); } #endregion #region Grouping Logic List <BugSubmission> listGridSubmissions = new List <BugSubmission>(); BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Grouping Data"); switch (comboGrouping.SelectedIndex) { case 0: #region None foreach (BugSubmission bugSubmission in listFilteredSubs) { AddGroupedSubsToGridSubs(listGridSubmissions, new List <BugSubmission>() { bugSubmission }); } listShowHideOptions.SetSelected(3, false); //Deselect 'None' _minGroupingCount = -1; butAddJob.Enabled = true; #endregion break; case 1: #region RegKey/Ver/Stack listFilteredSubs.GroupBy(x => new { x.BugId, x.RegKey, x.ProgramVersion, x.ExceptionMessageText, x.ExceptionStackTrace }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = true; #endregion break; case 2: #region StackTrace listFilteredSubs.GroupBy(x => new { x.BugId, x.ExceptionMessageText, x.ExceptionStackTrace }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = true; #endregion break; case 3: #region 95% //At this point all bugSubmissions in listFilteredSubs is at least a 95% match. Group them all together in a single row. AddGroupedSubsToGridSubs(listGridSubmissions, listFilteredSubs); butAddJob.Enabled = true; #endregion break; case 4: #region StackSig listFilteredSubs.GroupBy(x => new { x.BugId, x.ExceptionMessageText, x.OdStackSignature }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = false; //Can not add jobs in this mode. #endregion break; case 5: #region StackSimple listFilteredSubs.GroupBy(x => new { x.BugId, x.ExceptionMessageText, x.SimplifiedStackTrace }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = false; //Can not add jobs in this mode. #endregion break; case 6: #region Hash listFilteredSubs.GroupBy(x => new { x.BugId, x.BugSubmissionHashNum }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = false; //Can not add jobs in this mode. #endregion break; } if (_minGroupingCount > 0) { listGridSubmissions.RemoveAll(x => (x.TagCustom as List <BugSubmission>).Count < _minGroupingCount); } #endregion #region Sorting Logic BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Sorting Data"); switch (comboSortBy.SelectedIndex) { case 0: listGridSubmissions = listGridSubmissions.OrderByDescending(x => new Version(x.ProgramVersion)) .ThenByDescending(x => GetGroupCount(x)) .ThenByDescending(x => x.SubmissionDateTime).ToList(); break; } #endregion #region Fill gridSubs BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Filling Grid"); foreach (BugSubmission sub in listGridSubmissions) { gridSubs.ListGridRows.Add(GetODGridRowForSub(sub)); } gridSubs.EndUpdate(); #endregion loadingProgress?.Invoke(); Cursor = Cursors.Default; }
///<summary>Fills grid based on values in _listEtrans. ///Set isRefreshNeeded to true when we need to reinitialize local dictionarys after in memory list is also updated. Required true for first time running. ///Also allows you to passed in predetermined filter options.</summary> private void FillGrid(bool isRefreshNeeded, List <string> listSelectedStatuses, List <long> listSelectedClinicNums, string carrierName, string checkTraceNum, string amountMin, string amountMax, string controlId) { Cursor = Cursors.WaitCursor; labelControlId.Visible = PrefC.GetBool(PrefName.EraShowControlIdFilter); textControlId.Visible = PrefC.GetBool(PrefName.EraShowControlIdFilter); Action actionCloseProgress = null; if (isRefreshNeeded) { actionCloseProgress = ODProgress.Show(ODEventType.Etrans, typeof(EtransEvent), Lan.g(this, "Gathering data") + "..."); _dictEtrans835s.Clear(); _dictEtransClaims.Clear(); List <Etrans835Attach> listAttached = Etrans835Attaches.GetForEtrans(_listAllEtrans.Select(x => x.EtransNum).ToArray()); Dictionary <long, string> dictEtransMessages = new Dictionary <long, string>(); List <X12ClaimMatch> list835ClaimMatches = new List <X12ClaimMatch>(); Dictionary <long, int> dictClaimMatchCount = new Dictionary <long, int>(); //1:1 with _listEtranss. Stores how many claim matches each 835 has. int batchQueryInterval = 500; //Every 500 rows we get the next 500 message texts to save memory. int rowCur = 0; foreach (Etrans etrans in _listAllEtrans) { if (rowCur % batchQueryInterval == 0) { int range = Math.Min(batchQueryInterval, _listAllEtrans.Count - rowCur); //Either the full batchQueryInterval amount or the remaining amount of etrans. dictEtransMessages = EtransMessageTexts.GetMessageTexts(_listAllEtrans.GetRange(rowCur, range).Select(x => x.EtransMessageTextNum).ToList(), false); } rowCur++; EtransEvent.Fire(ODEventType.Etrans, Lan.g(this, "Processing 835: ") + ": " + rowCur + " out of " + _listAllEtrans.Count); List <Etrans835Attach> listAttachedTo835 = listAttached.FindAll(x => x.EtransNum == etrans.EtransNum); X835 x835 = new X835(etrans, dictEtransMessages[etrans.EtransMessageTextNum], etrans.TranSetId835, listAttachedTo835, true); _dictEtrans835s.Add(etrans.EtransNum, x835); List <X12ClaimMatch> listClaimMatches = x835.GetClaimMatches(); dictClaimMatchCount.Add(etrans.EtransNum, listClaimMatches.Count); list835ClaimMatches.AddRange(listClaimMatches); } #region Set 835 unattached in batch and build _dictEtransClaims and _dictClaimPayCheckNums. EtransEvent.Fire(ODEventType.Etrans, Lan.g(this, "Gathering internal claim matches.")); List <long> listClaimNums = Claims.GetClaimFromX12(list835ClaimMatches); //Can return null. EtransEvent.Fire(ODEventType.Etrans, Lan.g(this, "Building data sets.")); int claimIndexCur = 0; List <long> listMatchedClaimNums = new List <long>(); foreach (Etrans etrans in _listAllEtrans) { X835 x835 = _dictEtrans835s[etrans.EtransNum]; if (listClaimNums != null) { x835.SetClaimNumsForUnattached(listClaimNums.GetRange(claimIndexCur, dictClaimMatchCount[etrans.EtransNum])); } claimIndexCur += dictClaimMatchCount[etrans.EtransNum]; listMatchedClaimNums.AddRange(x835.ListClaimsPaid.FindAll(x => x.ClaimNum != 0).Select(x => x.ClaimNum).ToList()); } List <Claim> listClaims = Claims.GetClaimsFromClaimNums(listMatchedClaimNums.Distinct().ToList()); //The following line includes manually detached and split attaches. _listAllAttaches = Etrans835Attaches.GetForEtransNumOrClaimNums(false, _listAllEtrans.Select(x => x.EtransNum).ToList(), listMatchedClaimNums.ToArray()); _listAllClaimProcs = ClaimProcs.RefreshForClaims(listMatchedClaimNums); foreach (Etrans etrans in _listAllEtrans) { X835 x835 = _dictEtrans835s[etrans.EtransNum]; #region _dictEtransClaims, _dictClaimPayCheckNums _dictEtransClaims.Add(etrans.EtransNum, new List <Claim>()); List <long> listSubClaimNums = x835.ListClaimsPaid.FindAll(x => x.ClaimNum != 0).Select(y => y.ClaimNum).ToList(); List <Claim> listClaimsFor835 = listClaims.FindAll(x => listSubClaimNums.Contains(x.ClaimNum)); foreach (Hx835_Claim claim in x835.ListClaimsPaid) { Claim claimCur = listClaimsFor835.FirstOrDefault(x => x.ClaimNum == claim.ClaimNum); //Can be null. _dictEtransClaims[etrans.EtransNum].Add(claimCur); } #endregion } EtransEvent.Fire(ODEventType.Etrans, Lan.g(this, "Filling Grid.")); #endregion } gridMain.BeginUpdate(); #region Initilize columns gridMain.ListGridColumns.Clear(); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Patient Name"), 250)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Carrier Name"), 190)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Status"), 80)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Date"), 80, GridSortingStrategy.DateParse)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Amount"), 80, GridSortingStrategy.AmountParse)); if (PrefC.HasClinicsEnabled) { gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Clinic"), 70)); } gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Code"), 37, HorizontalAlignment.Center)); if (PrefC.GetBool(PrefName.EraShowControlIdFilter)) { gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "ControlID"), -1)); } gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableEtrans835s", "Note"), -2)); #endregion gridMain.ListGridRows.Clear(); foreach (Etrans etrans in _listAllEtrans) { X835 x835 = _dictEtrans835s[etrans.EtransNum]; #region Filter: Carrier Name if (carrierName != "" && !x835.PayerName.ToLower().Contains(carrierName.ToLower().Trim())) { continue; } #endregion string status = GetStringStatus(etrans.EtransNum); #region Filter: Status if (!listSelectedStatuses.Contains(status.Replace("*", ""))) //The filter will ignore finalized with detached claims. { continue; } #endregion //List of ClinicNums for the current etrans.ListClaimsPaid from the DB. List <long> listClinicNums = _dictEtransClaims[etrans.EtransNum].Select(x => x == null? 0 :x.ClinicNum).Distinct().ToList(); #region Filter: Clinics if (PrefC.HasClinicsEnabled && !listClinicNums.Exists(x => listSelectedClinicNums.Contains(x))) { continue; //The ClinicNums associated to the 835 do not match any of the selected ClinicNums, so nothing to show in this 835. } #endregion #region Filter: Check and Trace Value if (checkTraceNum != "" && !x835.TransRefNum.ToLower().Contains(checkTraceNum.ToLower().Trim())) //Trace Number does not match { continue; } #endregion #region Filter: Insurance Check Range Min and Max if (amountMin != "" && x835.InsPaid < PIn.Decimal(amountMin) || amountMax != "" && x835.InsPaid > PIn.Decimal(amountMax)) { continue; //Either the InsPaid is below or above our range. } #endregion #region Filter: ControlID if (controlId != "" && !x835.ControlId.ToLower().Contains(controlId.ToLower())) { continue; } #endregion GridRow row = new GridRow(); #region Column: Patient Name List <string> listPatNames = x835.ListClaimsPaid.Select(x => x.PatientName.ToString()).Distinct().ToList(); string patName = (listPatNames.Count > 0 ? listPatNames[0] : ""); if (listPatNames.Count > 1) { patName = "(" + POut.Long(listPatNames.Count) + ")"; } row.Cells.Add(patName); #endregion row.Cells.Add(x835.PayerName); row.Cells.Add(status); //See GetStringStatus(...) for possible values. row.Cells.Add(POut.Date(etrans.DateTimeTrans)); row.Cells.Add(POut.Decimal(x835.InsPaid)); #region Column: Clinic if (PrefC.HasClinicsEnabled) { string clinicAbbr = ""; if (listClinicNums.Count == 1) { if (listClinicNums[0] == 0) { clinicAbbr = Lan.g(this, "Unassigned"); } else { clinicAbbr = Clinics.GetAbbr(listClinicNums[0]); } } else if (listClinicNums.Count > 1) { clinicAbbr = "(" + Lan.g(this, "Multiple") + ")"; } row.Cells.Add(clinicAbbr); } #endregion row.Cells.Add(x835._paymentMethodCode); if (PrefC.GetBool(PrefName.EraShowControlIdFilter)) { row.Cells.Add(x835.ControlId); } row.Cells.Add(etrans.Note); row.Tag = etrans; gridMain.ListGridRows.Add(row); } gridMain.EndUpdate(); actionCloseProgress?.Invoke(); //When this function executes quickly this can fail rarely, fail silently because of WaitCursor. Cursor = Cursors.Default; }
///<summary>Balances all selected accounts.</summary> private void butTransfer_Click(object sender, EventArgs e) { //FormIncomeTransferManage requires PaymentCreate to run. //This form requires SecurityAdmin and a password to open, and although rare, // a SecuirtyAdmin doesn't have to have PaymentCreate permission if (!Security.IsAuthorized(Permissions.PaymentCreate)) { return; } //Make sure the user wants to run the tool. if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "This process can take a long time and cannot be reversed.\r\n\r\nContinue?")) { return; } Action actionCloseProgress = ODProgress.Show(ODEventType.Billing); //Build list of families based off of selected rows. _logger.WriteLine("This is the summary of all transactions that took place.This can be saved for later reference if one or more" + " transactions need to be undone outside of the tool.\r\n", LogLevel.Information); //Do income transfers if applicable. for (int i = _batchNum - 1; i < _listBatches.Count(); i++) //_batchNum is 1-based, so drop i by 1 to make sure the current batch is included { string logText = ""; if (checkAllocateCharges.Checked) { ODEvent.Fire(ODEventType.Billing, Lan.g(this, $"Creating income transfers for batch {_batchNum}/{_listBatches.Count()} please wait...")); foreach (FamilyAccount famAccountCur in _dictCurrentFamilyBatch.Select(x => x.Value)) { //Clear the list of splits in case any are hanging around from a previous run. famAccountCur.ListSplits.Clear(); famAccountCur.ListSplitsAssociated.Clear(); //Make lists of positive and negative charges. List <AccountEntry> listPosCharges = famAccountCur.Account.ListAccountCharges.Where(x => x.AmountEnd > 0).ToList(); List <AccountEntry> listNegCharges = famAccountCur.Account.ListAccountCharges.Where(x => x.AmountEnd < 0).ToList(); List <long> listPatNumsForCharges = listPosCharges.Select(x => x.PatNum).Distinct().ToList(); List <AccountEntry> listEntriesForPats = famAccountCur.Account.ListAccountCharges.FindAll(x => x.PatNum.In(listPatNumsForCharges)); //This catch will save us some time if they run the tool on the same family twice. if (listPosCharges.Count() == 0 || listNegCharges.Count() == 0) { continue; //No need to add to logText, CreateTransfers wouldn't return anything either. } Payment payCur = CreatePaymentTransferHelper(famAccountCur.Guarantor); logText += CreateTransfers(listPosCharges, listNegCharges, listEntriesForPats, famAccountCur, payCur); logText += CreditsToUnallocated(listNegCharges, famAccountCur, payCur); //Remove any $0 splits created from CreateTransfers. famAccountCur.ListSplits.RemoveAll(x => x.SplitAmt == 0); foreach (PaySplit split in famAccountCur.ListSplits) { PaySplits.Insert(split); } //Go through family accounts and update FSplitNums. foreach (PaySplits.PaySplitAssociated split in famAccountCur.ListSplitsAssociated) { //Update the FSplitNum after inserts are made. if (split.PaySplitLinked != null && split.PaySplitOrig != null) { PaySplits.UpdateFSplitNum(split.PaySplitOrig.SplitNum, split.PaySplitLinked.SplitNum); } } } } //Transfer balances to guarantor if applicable. if (checkGuarAllocate.Checked) { ODEvent.Fire(ODEventType.Billing, Lan.g(this, $"Transferring remaining balance to guarantor for batch {_batchNum}/{_listBatches.Count()} please wait...")); logText += "Balances transferred to Guarantor:\r\n"; logText += TransferToGuarantor(); } //load up the next batch ODEvent.Fire(ODEventType.Billing, Lan.g(this, $"Loading next batch please wait...")); FillNextBatch(); _logger.WriteLine(logText, LogLevel.Information); } actionCloseProgress(); }
///<summary>Refreshes the data and changes the UI accordingly. Called from FillGrid when dataRefresh is true.</summary> private void RefreshData() { List <ODThread> listThreadsRunning = ODThread.GetThreadsByGroupName("FormBackport_Refresh"); //Quit all threads that are still running. The user may have changed the path. This way the grid will not be filled with false information. listThreadsRunning.ForEach(x => x.QuitAsync()); //Store path _pathOnRefresh = comboPath.Text.TrimEnd('\\'); _ignoreListNameOnRefresh = textIgnoreList.Text; _currentProject = BackportProjects.Unknown; _listFileChanges = new List <ODFileChanges>(); //Clear Rows gridMain.BeginUpdate(); gridMain.ListGridRows.Clear(); gridMain.EndUpdate(); if (!Directory.Exists(comboPath.Text)) { MessageBox.Show("The directory does not exist."); return; } else { if (_pathOnRefresh.Contains("OPEN DENTAL SUBVERSION")) //look for open dental first as its naming scheme does not match the rest. { _currentProject = BackportProjects.OpenDental; } else { for (int i = 0; i < Enum.GetNames(typeof(ProjectName)).Length; i++) { if (_pathOnRefresh.Contains(Enum.GetNames(typeof(ProjectName))[i])) { _currentProject = BackportProjects.ListProjects.Find(x => x.Name == ((ProjectName)i)); break; } } } } if (_currentProject == BackportProjects.Unknown) { MessageBox.Show("Could not find the correct project."); return; } //Get available versions based on folder structure. UpdateListVersions(); Cursor = Cursors.AppStarting; //Refresh Data string pathOnRefresh = _pathOnRefresh; string ignoreListNameOnRefresh = _ignoreListNameOnRefresh; BackportProject currentProject = _currentProject.Copy(); ODThread odThread = new ODThread((o) => { List <ODFileChanges> listFileChanges = GetListOfFiles(pathOnRefresh, _listAvailableVersions, ignoreListNameOnRefresh, currentProject); this.InvokeIfNotDisposed(() => { //If window quit, this action will not run and the thread will die. if (o.HasQuit) //If the user refreshed the path and this was marked to quit. { return; } Cursor = Cursors.Default; _listFileChanges = listFileChanges; labelCurProj.Text = "Current Project: " + Enum.GetName(_currentProject.Name.GetType(), _currentProject.Name); FillGrid(); _progressBarAction?.Invoke(); _progressBarAction = null; }); }); odThread.AddExceptionHandler(ex => { _progressBarAction?.Invoke(); _progressBarAction = null; this.InvokeIfNotDisposed(() => { //If there's an exception after the form is closed, swallow and do not do anything. FriendlyException.Show("Error refreshing data.", ex); }); }); odThread.GroupName = "FormBackport_Refresh"; odThread.Name = "FormBackport_Refresh" + DateTime.Now.Millisecond; odThread.Start(); if (_progressBarAction == null) { _progressBarAction = ODProgress.Show(); } }
///<summary>Makes a web call to WebServiceMainHQ to get the corresponding EServiceSetupFull information and then attempts to fill each tab. ///If anything goes wrong within this method a message box will show to the user and then the window will auto close via Abort.</summary> private void FillForm() { Action actionCloseProgress = ODProgress.Show(ODEventType.EServices, typeof(EServicesEvent), "Validating eServices..."); try { if (!ODBuild.IsWeb() && MiscUtils.TryUpdateIeEmulation()) { throw new Exception("Browser emulation version updated.\r\nYou must restart this application before accessing the Signup Portal."); } //Send light version of clinics to HQ to be used by signup portal below. Get back all args needed from HQ in order to perform the operations of this window. SignupPortalPermission perm = GetUserSignupPortalPermissions(); SecurityLogs.MakeLogEntry(Permissions.Setup, 0, $"User {Security.CurUser.UserName} entered EService Setup with SignupPortalPermission {perm}"); if (_signupOut == null) //the first time this loads _signupOut will be null, so we won't have a previous state to compare { _signupOut = WebServiceMainHQProxy.GetEServiceSetupFull(perm); } else //If we are switching from the signup tab to another this will get called again and we don't want to lose the "diff" { _signupOut = WebServiceMainHQProxy.GetEServiceSetupFull(perm, oldSignupOut: _signupOut); } //Show user any prompts that were generated by GetEServiceSetupFull(). if (_signupOut.Prompts.Count > 0) { MessageBox.Show(string.Join("\r\n", _signupOut.Prompts.Select(x => Lans.g(this, x)))); } if (ODBuild.IsWeb()) { bool isSignupSelected = tabControl.SelectedTab == tabSignup; tabControl.TabPages.Remove(tabSignup); if (isSignupSelected) { actionCloseProgress?.Invoke(); this.ForceBringToFront(); Process.Start(_signupOut.SignupPortalUrl); DialogResult = DialogResult.Abort; return; } } #region Fill EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Signup")); FillTabSignup(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - eConnector Service")); FillTabEConnector(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Mobile Synch (old-style)")); FillTabMobileSynch(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Mobile Web")); FillTabMobileWeb(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Patient Portal")); FillTabPatientPortal(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Web Sched Recall")); FillTabWebSchedRecall(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Web Sched New Pat Appt")); FillTabWebSchedNewPat(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Web Sched Verify")); FillTabWebSchedVerify(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Texting Services")); FillTabTexting(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - eReminders & eConfirmations")); FillTabECR(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - eClipboard")); FillTabEClipboard(); EServicesEvent.Fire(ODEventType.EServices, Lan.g(this, "Loading tab - Miscellaneous")); FillTabMisc(); #endregion #region Authorize editing //Disable certain buttons but let them continue to view. bool allowEdit = Security.IsAuthorized(Permissions.EServicesSetup, true); AuthorizeTabSignup(allowEdit); AuthorizeTabEConnector(allowEdit); AuthorizeTabMobileSynch(allowEdit); AuthorizeTabPatientPortal(allowEdit); AuthorizeTabWebSchedRecall(allowEdit); AuthorizeTabWebSchedNewPat(allowEdit); AuthorizeTabTexting(allowEdit); AuthorizeTabECR(allowEdit); AuthorizeTabEClipboard(allowEdit); AuthorizeTabMisc(allowEdit); ((Control)tabMobileSynch).Enabled = allowEdit; #endregion } catch (WebException we) { actionCloseProgress?.Invoke(); this.ForceBringToFront(); FriendlyException.Show(Lan.g(this, "Could not reach HQ. Please make sure you have an internet connection and try again or call support."), we); //Set the dialog result to Abort so that FormClosing knows to not try and save any changes. DialogResult = DialogResult.Abort; Close(); } catch (Exception e) { actionCloseProgress?.Invoke(); this.ForceBringToFront(); FriendlyException.Show(Lan.g(this, "There was a problem loading the eServices Setup window. Please try again or call support."), e); //Set the dialog result to Abort so that FormClosing knows to not try and save any changes. DialogResult = DialogResult.Abort; Close(); } actionCloseProgress?.Invoke(); this.ForceBringToFront(); }