private void butOK_Click(object sender, System.EventArgs e) { //Using a switch statement in case we want special functionality for the other statuses later on. switch ((PhoneEmpStatusOverride)listStatusOverride.SelectedIndex) { case PhoneEmpStatusOverride.None: if (StatusOld == PhoneEmpStatusOverride.Unavailable) { MsgBox.Show(this, "Change your status from unavailable by using the small phone panel."); return; } break; case PhoneEmpStatusOverride.OfflineAssist: if (StatusOld == PhoneEmpStatusOverride.Unavailable) { MsgBox.Show(this, "Change your status from unavailable by using the small phone panel."); return; } break; } if (IsNew) { if (textEmployeeNum.Text == "") { MsgBox.Show(this, "Unique EmployeeNum is required."); return; } if (textEmpName.Text == "") { MsgBox.Show(this, "Employee name is required."); return; } PedCur.EmployeeNum = PIn.Long(textEmployeeNum.Text); } //Get the current database state of the phone emp default (before we change it) PhoneEmpDefault pedFromDatabase = PhoneEmpDefaults.GetOne(PedCur.EmployeeNum); if (pedFromDatabase == null) { pedFromDatabase = new PhoneEmpDefault(); } int newExtension = PIn.Int(textPhoneExt.Text); bool extensionChange = pedFromDatabase.PhoneExt != newExtension; if (extensionChange) //Only check when extension has changed and clocked in. //We need to prevent changes to phoneempdefault table which involve employees who are currently logged in. //Failing to do so would cause subtle race conditions between the phone table and phoneempdefault. //Net result would be the phone panel looking wrong. { if (ClockEvents.IsClockedIn(PedCur.EmployeeNum)) //Prevent any change if employee being edited is currently clocked in. { MsgBox.Show(this, "You must first clock out before making changes"); return; } //Find out if the target extension is already being occuppied by a different employee. Phone phoneOccuppied = Phones.GetPhoneForExtension(Phones.GetPhoneList(), PIn.Int(textPhoneExt.Text)); if (phoneOccuppied != null) { if (ClockEvents.IsClockedIn(phoneOccuppied.EmployeeNum)) //Prevent change if employee's new extension is occupied by a different employee who is currently clocked in. { MessageBox.Show(Lan.g(this, "This extension cannot be inherited because it is currently occuppied by an employee who is currently logged in.\r\n\r\nExisting employee: ") + phoneOccuppied.EmployeeName); return; } if (phoneOccuppied.EmployeeNum != PedCur.EmployeeNum) { //We are setting to a new employee so let's clean up the old employee. //This will prevent duplicates in the phone table and subsequently prevent duplicates in the phone panel. Phones.UpdatePhoneToEmpty(phoneOccuppied.EmployeeNum, -1); PhoneEmpDefault pedOccuppied = PhoneEmpDefaults.GetOne(phoneOccuppied.EmployeeNum); if (pedOccuppied != null) //prevent duplicate in phoneempdefault { pedOccuppied.PhoneExt = 0; PhoneEmpDefaults.Update(pedOccuppied); } } } //Get the employee that is normally assigned to this extension (assigned ext set in the employee table). long permanentLinkageEmployeeNum = Employees.GetEmpNumAtExtension(pedFromDatabase.PhoneExt); if (permanentLinkageEmployeeNum >= 1) //Extension is nomrally assigned to an employee. { if (PedCur.EmployeeNum != permanentLinkageEmployeeNum) //This is not the normally linked employee so let's revert back to the proper employee. { PhoneEmpDefault pedRevertTo = PhoneEmpDefaults.GetOne(permanentLinkageEmployeeNum); //Make sure the employee we are about to revert is not logged in at yet a different workstation. This would be rare but it's worth checking. if (pedRevertTo != null && !ClockEvents.IsClockedIn(pedRevertTo.EmployeeNum)) { //Revert to the permanent extension for this PhoneEmpDefault. pedRevertTo.PhoneExt = pedFromDatabase.PhoneExt; PhoneEmpDefaults.Update(pedRevertTo); //Update phone table to match this change. Phones.SetPhoneStatus(ClockStatusEnum.Home, pedRevertTo.PhoneExt, pedRevertTo.EmployeeNum); } } } } //Ordering of these updates is IMPORTANT!!! //Phone Emp Default must be updated first PedCur.EmpName = textEmpName.Text; PedCur.IsGraphed = checkIsGraphed.Checked; PedCur.HasColor = checkHasColor.Checked; PedCur.RingGroups = (AsteriskRingGroups)listRingGroup.SelectedIndex; PedCur.PhoneExt = PIn.Int(textPhoneExt.Text); PedCur.StatusOverride = (PhoneEmpStatusOverride)listStatusOverride.SelectedIndex; PedCur.Notes = textNotes.Text; PedCur.ComputerName = textComputerName.Text; PedCur.IsPrivateScreen = checkIsPrivateScreen.Checked; PedCur.IsTriageOperator = checkIsTriageOperator.Checked; if (IsNew) { PhoneEmpDefaults.Insert(PedCur); //insert the new Phone record to keep the 2 tables in sync Phone phoneNew = new Phone(); phoneNew.EmployeeName = PedCur.EmpName; phoneNew.EmployeeNum = PedCur.EmployeeNum; phoneNew.Extension = PedCur.PhoneExt; phoneNew.ClockStatus = ClockStatusEnum.Home; Phones.Insert(phoneNew); } else { PhoneEmpDefaults.Update(PedCur); } //It is now safe to update Phone table as it will draw from the newly updated Phone Emp Default row if ((PhoneEmpStatusOverride)listStatusOverride.SelectedIndex == PhoneEmpStatusOverride.Unavailable && ClockEvents.IsClockedIn(PedCur.EmployeeNum)) { //We set ourselves unavailable from this window because we require an explanation. //This is the only status that will synch with the phone table, all others should be handled by the small phone panel. Phones.SetPhoneStatus(ClockStatusEnum.Unavailable, PedCur.PhoneExt, PedCur.EmployeeNum); } if (extensionChange) { //Phone extension has changed so update the phone table as well. //We have already guaranteed that this employee is Clocked Out (above) so set to home and update phone table. Phones.SetPhoneStatus(ClockStatusEnum.Home, PedCur.PhoneExt, PedCur.EmployeeNum); } DialogResult = DialogResult.OK; }
private void FillData() { DictEmployeesPerBucket = new Dictionary <int, List <Employee> >(); labelDate.Text = DateShowing.ToString("dddd, MMMM d"); butEdit.Enabled = DateShowing.Date >= DateTime.Today; //do not allow editing of past dates listCalls = new List <PointF>(); if (DateShowing.DayOfWeek == DayOfWeek.Friday) { listCalls.Add(new PointF(5f, 25)); //was 0 listCalls.Add(new PointF(5.5f, 70)); //5-6am was 50 listCalls.Add(new PointF(6.5f, 145)); listCalls.Add(new PointF(7.5f, 218)); listCalls.Add(new PointF(8.5f, 335)); listCalls.Add(new PointF(9f, 363)); //- listCalls.Add(new PointF(9.5f, 375)); // listCalls.Add(new PointF(10f, 364)); //- listCalls.Add(new PointF(10.5f, 362)); // listCalls.Add(new PointF(11.5f, 360)); listCalls.Add(new PointF(12.5f, 345)); // listCalls.Add(new PointF(13.5f, 330)); // listCalls.Add(new PointF(14.5f, 290)); listCalls.Add(new PointF(15.5f, 200)); listCalls.Add(new PointF(16.5f, 160)); listCalls.Add(new PointF(17f, 100)); listCalls.Add(new PointF(17.5f, 50)); listCalls.Add(new PointF(17.5f, 0)); } else if (DateShowing.DayOfWeek == DayOfWeek.Saturday || DateShowing.DayOfWeek == DayOfWeek.Sunday) { //do nothing, no call curve to show yet } else { listCalls.Add(new PointF(5f, 50)); listCalls.Add(new PointF(5.5f, 325)); //5-6am listCalls.Add(new PointF(6.5f, 780)); listCalls.Add(new PointF(7.5f, 1248)); listCalls.Add(new PointF(8.5f, 1753)); listCalls.Add(new PointF(9f, 1920)); //- listCalls.Add(new PointF(9.5f, 2000)); // listCalls.Add(new PointF(10f, 1950)); // listCalls.Add(new PointF(10.5f, 1925)); // listCalls.Add(new PointF(11.5f, 1900)); // listCalls.Add(new PointF(12.5f, 1860)); listCalls.Add(new PointF(13.5f, 1835)); listCalls.Add(new PointF(14.5f, 1600)); listCalls.Add(new PointF(15.5f, 1200)); listCalls.Add(new PointF(16.5f, 750)); listCalls.Add(new PointF(17.5f, 290)); listCalls.Add(new PointF(18f, 90)); listCalls.Add(new PointF(18f, 0)); } buckets = new float[56]; //Number of total bucket. 4 buckets per hour * 14 hours = 56 buckets. _listSchedules = Schedules.GetDayList(DateShowing); //PhoneGraph exceptions will take precedence over employee default List <PhoneGraph> listPhoneGraphs = PhoneGraphs.GetAllForDate(DateShowing); TimeSpan time1; TimeSpan time2; TimeSpan delta; for (int i = 0; i < _listSchedules.Count; i++) { if (_listSchedules[i].SchedType != ScheduleType.Employee) { continue; } //get this employee Employee employee = Employees.GetEmp(_listSchedules[i].EmployeeNum); if (employee == null) //employees will NEVER be deleted. even after they cease to work here. but just in case. { continue; } bool hasPhoneGraphEntry = false; bool isGraphed = false; //PhoneGraph entries will take priority over the default employee graph state for (int iPG = 0; iPG < listPhoneGraphs.Count; iPG++) { if (listPhoneGraphs[iPG].EmployeeNum == employee.EmployeeNum) { isGraphed = listPhoneGraphs[iPG].IsGraphed; hasPhoneGraphEntry = true; break; } } if (!hasPhoneGraphEntry) //no phone graph entry found (likely for a future date which does not have entries created yet OR past date where current employee didn't work here yet) { if (DateShowing <= DateTime.Today) //no phone graph entry and we are on a past OR current date. if it's not already created then don't graph this employee for this date { continue; } //we are on a future date AND we don't have a PhoneGraph entry explicitly set so use the default for this employee PhoneEmpDefault ped = PhoneEmpDefaults.GetEmpDefaultFromList(_listSchedules[i].EmployeeNum, _listPhoneEmpDefaults); if (ped == null) //we will default to PhoneEmpDefault.IsGraphed so make sure the deafult exists { continue; } //no entry in PhoneGraph for the employee on this date so use the default isGraphed = ped.IsGraphed; } if (!isGraphed) //only care about employees that are being graphed { continue; } for (int b = 0; b < buckets.Length; b++) { //minutes field multiplier is a function of buckets per hour. answers the question, "how many minutes long is each bucket?" time1 = new TimeSpan(5, 0, 0) + new TimeSpan(0, b * 15, 0); time2 = new TimeSpan(5, 15, 0) + new TimeSpan(0, b * 15, 0); //situation 1: this bucket is completely within the start and stop times. if (_listSchedules[i].StartTime <= time1 && _listSchedules[i].StopTime >= time2) { AddEmployeeToBucket(b, employee); } //situation 2: the start time is after this bucket else if (_listSchedules[i].StartTime >= time2) { continue; } //situation 3: the stop time is before this bucket else if (_listSchedules[i].StopTime <= time1) { continue; } //situation 4: start time falls within this bucket if (_listSchedules[i].StartTime > time1) { delta = _listSchedules[i].StartTime - time1; //7.5 minutes is half of one bucket. if (delta.TotalMinutes > 7.5) //has to work more than 15 minutes to be considered *in* this bucket { AddEmployeeToBucket(b, employee); } } //situation 5: stop time falls within this bucket if (_listSchedules[i].StopTime < time2) { delta = time2 - _listSchedules[i].StopTime; if (delta.TotalMinutes > 7.5) //has to work more than 15 minutes to be considered *in* this bucket { AddEmployeeToBucket(b, employee); } } } //break;//just show one sched for debugging. } //missed calls //missedCalls=new int[28]; //List<DateTime> callTimes=PhoneAsterisks.GetMissedCalls(dateShowing); //for(int i=0;i<callTimes.Count;i++) { // for(int b=0;b<missedCalls.Length;b++) { // time1=new TimeSpan(5,0,0) + new TimeSpan(0,b*30,0); // time2=new TimeSpan(5,30,0) + new TimeSpan(0,b*30,0); // if(callTimes[i].TimeOfDay >= time1 && callTimes[i].TimeOfDay < time2) { // missedCalls[b]++; // } // } //} //Minutes Behind minutesBehind = PhoneMetrics.AverageMinutesBehind(DateShowing); this.Invalidate(); }
private void FillGrid() { //do not refresh from db SchedList.Sort(CompareSchedule); gridMain.BeginUpdate(); gridMain.Columns.Clear(); ODGridColumn col = new ODGridColumn(Lan.g("TableSchedDay", "Provider"), 100); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Employee"), 100); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Start Time"), 100); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Stop Time"), 100); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Note"), 100); gridMain.Columns.Add(col); gridMain.Rows.Clear(); ODGridRow row; string note; for (int i = 0; i < SchedList.Count; i++) { row = new ODGridRow(); //Prov if (SchedList[i].ProvNum != 0) { row.Cells.Add(Providers.GetAbbr(SchedList[i].ProvNum)); } else { row.Cells.Add(""); } //Employee if (SchedList[i].EmployeeNum == 0) { row.Cells.Add(""); } else { row.Cells.Add(Employees.GetEmp(SchedList[i].EmployeeNum).FName); } //times if (SchedList[i].StartTime.TimeOfDay == PIn.PDateT("12 AM").TimeOfDay && SchedList[i].StopTime.TimeOfDay == PIn.PDateT("12 AM").TimeOfDay) //SchedList[i].SchedType==ScheduleType.Practice){ { row.Cells.Add(""); row.Cells.Add(""); } else { row.Cells.Add(SchedList[i].StartTime.ToShortTimeString()); row.Cells.Add(SchedList[i].StopTime.ToShortTimeString()); } //note note = ""; if (SchedList[i].Status == SchedStatus.Holiday) { note += Lan.g(this, "Holiday: "); } note += SchedList[i].Note; row.Cells.Add(note); gridMain.Rows.Add(row); } gridMain.EndUpdate(); }
private void FormSiteLinkEdit_Load(object sender, EventArgs e) { Site site = Sites.GetFirstOrDefault(x => x.SiteNum == _siteLink.SiteNum); if (_siteLink.SiteNum < 1 || site == null) { MsgBox.Show(this, "Invalid SiteNum set for the passed in siteLink."); DialogResult = DialogResult.Abort; Close(); return; } textSite.Text = site.Description; //Octets if (!string.IsNullOrEmpty(_siteLink.OctetStart)) { string[] arrayOctets = _siteLink.OctetStart.Split('.'); if (arrayOctets.Length > 0) { textOctet1.Text = arrayOctets[0]; } if (arrayOctets.Length > 1) { textOctet2.Text = arrayOctets[1]; } if (arrayOctets.Length > 2) { textOctet3.Text = arrayOctets[2]; } } //Triage comboTriageCoordinator.Items.Clear(); foreach (Employee employee in Employees.GetDeepCopy(true)) { int index = comboTriageCoordinator.Items.Add(new ODBoxItem <Employee>(Employees.GetNameFL(employee), employee)); if (_siteLink.EmployeeNum == employee.EmployeeNum) { comboTriageCoordinator.SelectedIndex = index; } } //Colors panelSiteColor.BackColor = _siteLink.SiteColor; panelForeColor.BackColor = _siteLink.ForeColor; panelInnerColor.BackColor = _siteLink.InnerColor; panelOuterColor.BackColor = _siteLink.OuterColor; labelOpsCountPreview.SetColors(panelForeColor.BackColor, panelOuterColor.BackColor, panelInnerColor.BackColor); }