private void butOK_Click(object sender, EventArgs e) { if (!EntriesAreValid()) { return; } //This list should only contain a single patNum, but just in case. List <long> listDistinctPatNums = ProcList.Select(x => x.PatNum).Distinct().ToList(); DateTime procDate = DateTime.MinValue; if (textDate.Text != "" && ProcList.Any(x => x.ProcDate != PIn.Date(textDate.Text))) { procDate = PIn.Date(textDate.Text); } #region Update ProcList and DB to reflect selections List <ClaimProc> listClaimProcsAll = ClaimProcs.RefreshForProcs(ProcList.Select(x => x.ProcNum).ToList()); //Get data for any OrthoCases that may be linked to procs in ProcList List <OrthoProcLink> listOrthoProcLinksAllForPat = new List <OrthoProcLink>(); Dictionary <long, OrthoProcLink> dictOrthoProcLinksForProcList = new Dictionary <long, OrthoProcLink>(); Dictionary <long, OrthoCase> dictOrthoCases = new Dictionary <long, OrthoCase>(); Dictionary <long, OrthoSchedule> dictOrthoSchedules = new Dictionary <long, OrthoSchedule>(); OrthoCases.GetDataForListProcs(ref listOrthoProcLinksAllForPat, ref dictOrthoProcLinksForProcList, ref dictOrthoCases, ref dictOrthoSchedules, ProcList); OrthoCase orthoCase = null; OrthoSchedule orthoSchedule = null; List <OrthoProcLink> listOrthoProcLinksForOrthoCase = null; foreach (Procedure proc in ProcList) { bool hasChanged = false; bool hasDateChanged = false; List <ClaimProc> listClaimProcsForProc = ClaimProcs.GetForProc(listClaimProcsAll, proc.ProcNum); Procedure procOld = _procOldList.Find(x => x.ProcNum == proc.ProcNum); //this shouldn't fail, it needs to be in this list. if (procDate != DateTime.MinValue && proc.ProcDate != procDate) //Using value entered in the textbox. { proc.ProcDate = procDate; //ClaimProc.ProcDate will be "synched" in Procedures.ComputeEstimates(), but only if not attached to a claim. Mimics FormprocEdit. hasDateChanged = true; hasChanged = true; } if (comboProv.GetSelected <Provider>() != null && comboProv.GetSelected <Provider>().ProvNum != proc.ProvNum) //Using selection { proc.ProvNum = comboProv.GetSelected <Provider>().ProvNum; //Mimics FormProcEdit, uses different criteria than Procedures.ComputeEstimates(). ClaimProcs.TrySetProvFromProc(proc, listClaimProcsForProc); hasChanged = true; } if (comboClinic.GetSelected <Clinic>() != null && comboClinic.GetSelected <Clinic>().ClinicNum != proc.ClinicNum) //Using selection { proc.ClinicNum = comboClinic.GetSelected <Clinic>().ClinicNum; listClaimProcsForProc.ForEach(x => x.ClinicNum = proc.ClinicNum); hasChanged = true; } if (hasChanged) { Procedures.Update(proc, procOld); if (hasDateChanged) { List <ClaimProc> listNewClaimProcs; dictOrthoProcLinksForProcList.TryGetValue(proc.ProcNum, out OrthoProcLink orthoProcLink); //If proc is linked to an OrthoCase, update dates for OrthoCase. if (orthoProcLink != null) { OrthoCases.UpdateDatesByLinkedProc(orthoProcLink, proc); } OrthoCases.FillOrthoCaseObjectsForProc(proc.ProcNum, ref orthoProcLink, ref orthoCase, ref orthoSchedule, ref listOrthoProcLinksForOrthoCase, dictOrthoProcLinksForProcList, dictOrthoCases, dictOrthoSchedules, listOrthoProcLinksAllForPat); RecomputeEstimates(proc, listClaimProcsForProc, out listNewClaimProcs, orthoProcLink, orthoCase, orthoSchedule, listOrthoProcLinksForOrthoCase); ClaimProcs.InsertMany(listNewClaimProcs); //Only insert claimProcs that were newly added. } } } ClaimProcs.UpdateMany(listClaimProcsAll); //Does not contain new claimProcs. foreach (long patNum in listDistinctPatNums) //Should be a single patient. { Recalls.Synch(patNum); } #endregion #region Security Log Entries string logTextProcComplete = ""; //To make security log for procs that were C (specific permission) string logTextProcExisting = ""; //To make a security log for procs that were EO,EC (specific permission) string logTextProcOther = ""; //All other procedures (general permission) foreach (long patNum in listDistinctPatNums) { foreach (Procedure proc in ProcList) //necessary because of different original values { Procedure procOld = _procOldList.FirstOrDefault(x => x.ProcNum == proc.ProcNum); if (procOld == null) { continue; } //If proc has not been changed then a blank string will be returned. //Only changed procs will be reflected in security log entries. switch (procOld.ProcStatus) { case ProcStat.C: logTextProcComplete += ConstructSecurityLogForProcType(proc, procOld); break; case ProcStat.EO: case ProcStat.EC: logTextProcExisting += ConstructSecurityLogForProcType(proc, procOld); break; default: logTextProcOther += ConstructSecurityLogForProcType(proc, procOld); break; } } if (logTextProcComplete != "") { SecurityLogs.MakeLogEntry(Permissions.ProcComplEdit, patNum, logTextProcComplete); } if (logTextProcExisting != "") { SecurityLogs.MakeLogEntry(Permissions.ProcExistingEdit, patNum, logTextProcExisting); } if (logTextProcOther != "") { SecurityLogs.MakeLogEntry(Permissions.ProcEdit, patNum, logTextProcOther); } } #endregion DialogResult = DialogResult.OK; }
///<summary>Checks to see if the appointments provider has at least one mismatch provider on all the completed procedures attached to the appointment. ///If so, checks to see if the user has permission to edit a completed procedure. If the user does, then the user has the option to change the provider to match.</summary> public static bool DoRemoveCompletedProcs(Appointment apt, List <Procedure> listProcsForAppt, bool checkForAllProcCompl = false) { if (listProcsForAppt.Count == 0) { return(false); } if (checkForAllProcCompl && (apt.AptStatus != ApptStatus.Complete || listProcsForAppt.All(x => x.ProcStatus == ProcStat.C))) { return(false); } List <Procedure> listCompletedProcWithDifferentProv = new List <Procedure>(); foreach (Procedure proc in listProcsForAppt) { if (proc.ProcStatus != ProcStat.C || proc.AptNum != apt.AptNum) //should all be complete already. { continue; } ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum); long provNum = Procedures.GetProvNumFromAppointment(apt, proc, procCode); if (provNum != proc.ProvNum) { listCompletedProcWithDifferentProv.Add(proc); } } if (listCompletedProcWithDifferentProv.Count == 0) { return(true); //All completed procs match appt, so ignore completed procedures when running Procedures.UpdateProcsInApptHelper() } if (PrefC.GetBool(PrefName.ProcProvChangesClaimProcWithClaim)) { List <ClaimProc> listClaimProcs = ClaimProcs.RefreshForProcs(listCompletedProcWithDifferentProv.Select(x => x.ProcNum).ToList()); if (listClaimProcs.Any(x => x.Status == ClaimProcStatus.Received || x.Status == ClaimProcStatus.Supplemental || x.Status == ClaimProcStatus.CapClaim)) { MsgBox.Show("Procedures", "The appointment provider does not match the provider on at least one procedure that is attached " + "to a claim.\r\nThe provider on the procedure(s) cannot be changed."); return(true); } } List <PaySplit> listPaySplit = PaySplits.GetPaySplitsFromProcs(listCompletedProcWithDifferentProv.Select(x => x.ProcNum).ToList()); if (listPaySplit.Count > 0) { MsgBox.Show("Procedures", "The appointment provider does not match the provider on at least one completed procedure.\r\n" + "The procedure provider cannot be changed to match the appointment provider because the paysplit provider would no longer match. " + "Any change to the provider on the completed procedure(s) or paysplit(s) will have to be made manually."); return(true); //paysplits exist on one of the completed procedures. Per Nathan, don't change the provider. User will need to change manually. } foreach (Procedure proc in listCompletedProcWithDifferentProv) { Permissions perm = Permissions.ProcComplEdit; if (proc.ProcStatus.In(ProcStat.EC, ProcStat.EO)) { perm = Permissions.ProcExistingEdit; } if (Security.IsGlobalDateLock(perm, proc.ProcDate)) { return(true); } if (!Security.IsAuthorized(perm, proc.ProcDate, true, true)) { MessageBox.Show(Lan.g("Procedures", "The appointment provider does not match the provider on at least one completed procedure.") + "\r\n" + Lans.g("Procedures", "Not authorized for") + ": " + GroupPermissions.GetDesc(perm) + "\r\n" + Lan.g("Procedures", "Any change to the provider on the completed procedure(s) will have to be made manually.")); return(true); //user does not have permission to change the provider. Don't change provider. } } //The appointment is set complete, completed procedures exist, and provider does not match appointment. //Ask if they would like to change the providers on the completed procedure to match the appointments provider if (!MsgBox.Show("Procedures", MsgBoxButtons.YesNo, "The appointment provider does not match the provider on at least one completed procedure.\r\n" + "Change the provider on the completed procedure(s) to match the provider on the appointment?")) { return(true); //user does not want to change the providers } //user wants to change the provider on the completed procedure return(false); }
private bool EntriesAreValid() { //Get a new recent list of claimprocs for pat to be able to validate for provider and procedure status change. if (textDate.Text != "" && textDate.errorProvider1.GetError(textDate) != "") { //Either loaded blank or user deleted date. Either way blank will not make it to DB. MsgBox.Show(this, "Please fix data entry errors first."); return(false); } DateTime procDate = PIn.Date(textDate.Text); if (textDate.Text != "" && ProcList.Any(x => x.ProcDate != procDate)) { if (!IsUserAuthorizedForProcDate(procDate)) //Do not allow new ProcDate outside of date limitations. Mimics behavior in FormProcEdit. { return(false); } Appointment apt; foreach (Procedure proc in ProcList) //first validate for all dates. { #region Future dating completed procedures validation. if (!PrefC.GetBool(PrefName.FutureTransDatesAllowed) && proc.ProcStatus == ProcStat.C && procDate > DateTime.Today) { MsgBox.Show(this, "Completed procedures cannot have future dates."); return(false); } #endregion #region Procedures attached to appointments date validation. if (proc.AptNum == 0) { continue; } apt = Appointments.GetOneApt(proc.AptNum); if (proc.ProcDate.Date != apt.AptDateTime.Date) { string error = Lan.g(this, "Date does not match appointment date for a procedure dated:") + " " + proc.ProcDate.ToShortDateString() + "\r\n" + Lan.g(this, "Continue anyway?"); if (MessageBox.Show(error, "", MessageBoxButtons.YesNo) == DialogResult.No) { return(false); } break; } #endregion } } List <ClaimProc> listClaimProcsForPat = ClaimProcs.RefreshForProcs(ProcList.Select(x => x.ProcNum).ToList()); foreach (Procedure proc in ProcList) { if (proc.IsLocked) { MsgBox.Show(this, "Locked procedures cannot be edited."); return(false); } #region Provider change validation. List <ClaimProc> listClaimProcsForProc = ClaimProcs.GetForProc(listClaimProcsForPat, proc.ProcNum); long selectedProvNum = (comboProv.GetSelected <Provider>()?.ProvNum ?? 0);//0 if no selection made if (selectedProvNum != 0 && !ProcedureL.ValidateProvider(listClaimProcsForProc, selectedProvNum, proc.ProvNum)) { return(false); } #endregion } return(true); }