private void FormEtrans835Edit_Load(object sender, EventArgs e) { if (_form835 != null && !_form835.IsDisposed) { if (!MsgBox.Show(this, true, "Opening another ERA will close the current ERA you already have open. Continue?")) { //Form already exists and user wants to keep current instance. TranSetId835 = _form835.TranSetId835; EtransCur = _form835.EtransCur; MessageText835 = _form835.MessageText835; } _form835.Close(); //Always close old form and open new form, so the new copy will come to front, since BringToFront() does not always work. } _form835 = this; //Set the static variable to this form because we're always going to show this form even if they're viewing old information. List <Etrans835Attach> listAttached = Etrans835Attaches.GetForEtrans(EtransCur.EtransNum); _x835 = new X835(EtransCur, MessageText835, TranSetId835, listAttached); RefreshFromDb(); FillAll(); Menu.MenuItemCollection menuItemCollection = new Menu.MenuItemCollection(gridClaimDetailsMenu); List <MenuItem> listMenuItems = new List <MenuItem>(); listMenuItems.Add(new MenuItem(Lan.g(this, "Go to Account"), new EventHandler(gridClaimDetails_RightClickHelper))); listMenuItems.Add(new MenuItem(Lan.g(this, "Add Tracking Status"), new EventHandler(gridClaimDetails_RightClickHelper))); //Enabled by default menuItemCollection.AddRange(listMenuItems.ToArray()); gridClaimDetails.ContextMenu = gridClaimDetailsMenu; gridClaimDetails.AllowSortingByColumn = true; }
///<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>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) { Action actionCloseProgress = null; if (isRefreshNeeded) { actionCloseProgress = ODProgressOld.ShowProgressStatus("Etrans835", this, Lan.g(this, "Gathering data") + "...", false); _dictEtrans835s.Clear(); _dictEtransClaims.Clear(); _dictClaimPayExists.Clear(); List <Etrans835Attach> listAttached = Etrans835Attaches.GetForEtrans(_listEtranss.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 _listEtranss) { if (rowCur % batchQueryInterval == 0) { int range = Math.Min(batchQueryInterval, _listEtranss.Count - rowCur); //Either the full batchQueryInterval amount or the remaining amount of etrans. dictEtransMessages = EtransMessageTexts.GetMessageTexts(_listEtranss.GetRange(rowCur, range).Select(x => x.EtransMessageTextNum).ToList(), false); } rowCur++; ODEvent.Fire(new ODEventArgs("Etrans835", Lan.g(this, "Processing 835: ") + ": " + rowCur + " out of " + _listEtranss.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. ODEvent.Fire(new ODEventArgs("Etrans835", Lan.g(this, "Gathering internal claim matches."))); List <long> listClaimNums = Claims.GetClaimFromX12(list835ClaimMatches); //Can return null. ODEvent.Fire(new ODEventArgs("Etrans835", Lan.g(this, "Building data sets."))); int claimIndexCur = 0; List <long> listMatchedClaimNums = new List <long>(); foreach (Etrans etrans in _listEtranss) { 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()); _dictClaimPayExists = ClaimPayments.HasClaimPayment(listMatchedClaimNums); //Every claim num is associated to a bool. True when there is an existing claimPayment. foreach (Etrans etrans in _listEtranss) { 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. if (claimCur == null && claim.IsAttachedToClaim && claim.ClaimNum == 0) { claimCur = new Claim(); //Create empty claim since user detached claim manually, will not be considered in GetStringStatus(...). } if (claimCur != null && claim.IsPreauth) //User attached preauth to internal claim, no payment needed to be considered 'Finalized' in GetStringStatus(...). { _dictClaimPayExists[claim.ClaimNum] = true; } _dictEtransClaims[etrans.EtransNum].Add(claimCur); } #endregion } ODEvent.Fire(new ODEventArgs("Etrans835", Lan.g(this, "Filling Grid."))); #endregion } gridMain.BeginUpdate(); #region Initilize columns only once if (gridMain.Columns.Count == 0) { ODGridColumn col; col = new ODGridColumn(Lan.g("TableEtrans835s", "Patient Name"), 250); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableEtrans835s", "Carrier Name"), 190); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableEtrans835s", "Status"), 80); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableEtrans835s", "Date"), 80); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableEtrans835s", "Amount"), 80); gridMain.Columns.Add(col); if (PrefC.HasClinicsEnabled) { col = new ODGridColumn(Lan.g("TableEtrans835s", "Clinic"), 70); gridMain.Columns.Add(col); } col = new ODGridColumn(Lan.g("TableEtrans835s", "Code"), 37, HorizontalAlignment.Center); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableEtrans835s", "Note"), 0); gridMain.Columns.Add(col); } #endregion gridMain.Rows.Clear(); foreach (Etrans etrans in _listEtranss) { X835 x835 = _dictEtrans835s[etrans.EtransNum]; #region Filter: Carrier Name if (carrierName != "" && !x835.PayerName.ToLower().Contains(carrierName.ToLower())) { 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.Contains(checkTraceNum)) //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 ODGridRow row = new ODGridRow(); #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); row.Cells.Add(etrans.Note); row.Tag = etrans; gridMain.Rows.Add(row); } gridMain.EndUpdate(); actionCloseProgress?.Invoke(); }