private void gridWebChatSurveys_CellDoubleClick(object sender, ODGridClickEventArgs e) { WebChatSession webChatSession = (WebChatSession)gridWebChatSurveys.ListGridRows[e.Row].Tag; FormWebChatSession formWebChatSession = new FormWebChatSession(webChatSession, () => { }); formWebChatSession.ShowDialog(); }
///<summary>This form is only displayed when accessed from the triage list at ODHQ.</summary> public FormWebChatSession(WebChatSession webChatSession, Action onCloseAction) { InitializeComponent(); Lan.F(this); _webChatSession = webChatSession; _onCloseAction = onCloseAction; }
private void TakeOwnership() { //Refresh the session in case the owner changed in less than the last signal interval. _webChatSession = WebChatSessions.GetOne(_webChatSession.WebChatSessionNum); bool isOkToTake = true; if (_webChatSession.TechName == Security.CurUser.UserName) { //Ownership is already claimed. Do not run a pointless update command. isOkToTake = false; } else if (!String.IsNullOrEmpty(_webChatSession.TechName)) { if (MessageBox.Show(Lan.g(this, "This session is owned by another technician. Take this session from user") + " " + _webChatSession.TechName + "?", "", MessageBoxButtons.YesNo) != DialogResult.Yes) { isOkToTake = false; } } if (isOkToTake) { WebChatSession oldWebChatSession = _webChatSession.Clone(); _webChatSession.TechName = Security.CurUser.UserName; WebChatSessions.Update(_webChatSession, oldWebChatSession); } textOwner.Text = _webChatSession.TechName; if (isOkToTake) //show after previous text has changed { MessageBox.Show(Lan.g(this, "Session is now owned by") + " " + _webChatSession.TechName); } }
public override void OnProcessSignals(List <Signalod> listSignals) { if (listSignals.Exists(x => x.IType == InvalidType.WebChatSessions && x.FKey == _webChatSession.WebChatSessionNum)) { _sessionNote = textNote.Text; _webChatSession = WebChatSessions.GetOne(_webChatSession.WebChatSessionNum); //Refresh the session in case the owner changed. FillSession(); FillMessageThread(); } }
private void SetEscalationList(List <PhoneEmpDefault> peds, List <Phone> phones) { try { escalationView.BeginUpdate(); escalationView.Items.Clear(); escalationView.DictProximity.Clear(); escalationView.DictShowExtension.Clear(); escalationView.DictExtensions.Clear(); escalationView.DictWebChat.Clear(); escalationView.DictGTAChat.Clear(); if (escalationView.Tag == null || (((int)escalationView.Tag) != tabMain.SelectedIndex)) { escalationView.IsNewItems = true; escalationView.Tag = tabMain.SelectedIndex; } List <PhoneEmpDefault> listFiltered = peds.FindAll(x => DoAddToEscalationView(x, phones)); List <PhoneEmpDefault> listSorted = SortForEscalationView(listFiltered, phones); if (_listChatUsers == null) { _listChatUsers = ChatUsers.GetAll(); } if (_listWebChatSessions == null) { _listWebChatSessions = WebChatSessions.GetActiveSessions(); } for (int i = 0; i < listSorted.Count; i++) { PhoneEmpDefault ped = listSorted[i]; Phone phone = ODMethodsT.Coalesce(Phones.GetPhoneForEmployeeNum(phones, ped.EmployeeNum)); escalationView.Items.Add(ped.EmpName); //Only show the proximity icon if the phone.IsProxVisible AND the employee is at the same site as our currently selected room. escalationView.DictProximity.Add(ped.EmpName, (_mapCur.SiteNum == ped.SiteNum && phone.IsProxVisible)); WebChatSession webChatSession = _listWebChatSessions.FirstOrDefault(x => x.TechName == phone.EmployeeName); if (webChatSession != null) { escalationView.DictWebChat.Add(ped.EmpName, true); escalationView.DictGTAChat.Add(ped.EmpName, false); } else { escalationView.DictWebChat.Add(ped.EmpName, false); escalationView.DictGTAChat.Add(ped.EmpName, _listChatUsers.FindAll(x => x.Extension == ped.PhoneExt && x.CurrentSessions > 0).Count > 0); } //Extensions will always show for both locations unless the employee is not proximal. escalationView.DictShowExtension.Add(ped.EmpName, phone.IsProxVisible); escalationView.DictExtensions.Add(ped.EmpName, ped.PhoneExt); } } catch { } finally { escalationView.EndUpdate(); } }
private void FormWebChatSession_FormClosing(object sender, FormClosingEventArgs e) { if (Regex.Replace(_webChatSession.Note, @"\s+", "") != Regex.Replace(textNote.Text, @"\s+", "") && MsgBox.Show(this, MsgBoxButtons.YesNo, "Notes changed. Save changes?")) { WebChatSession webChatSessionOld = _webChatSession.Clone(); _webChatSession.Note = textNote.Text; WebChatSessions.Update(_webChatSession, webChatSessionOld); } _onCloseAction(); }
///<summary>Returns true if Update(WebChatSession,WebChatSession) would make changes to the database. ///Does not make any changes to the database and can be called before remoting role is checked.</summary> public static bool UpdateComparison(WebChatSession webChatSession, WebChatSession oldWebChatSession) { if (webChatSession.UserName != oldWebChatSession.UserName) { return(true); } if (webChatSession.PracticeName != oldWebChatSession.PracticeName) { return(true); } if (webChatSession.EmailAddress != oldWebChatSession.EmailAddress) { return(true); } if (webChatSession.PhoneNumber != oldWebChatSession.PhoneNumber) { return(true); } if (webChatSession.IsCustomer != oldWebChatSession.IsCustomer) { return(true); } if (webChatSession.QuestionText != oldWebChatSession.QuestionText) { return(true); } if (webChatSession.TechName != oldWebChatSession.TechName) { return(true); } if (webChatSession.DateTcreated != oldWebChatSession.DateTcreated) { return(true); } if (webChatSession.DateTend != oldWebChatSession.DateTend) { return(true); } if (webChatSession.PatNum != oldWebChatSession.PatNum) { return(true); } if (webChatSession.Note != oldWebChatSession.Note) { return(true); } return(false); }
private void butPatientSelect_Click(object sender, EventArgs e) { FormPatientSelect formPS = new FormPatientSelect(); if (formPS.ShowDialog() != DialogResult.OK) { return; } Patient pat = Patients.GetPat(formPS.SelectedPatNum); textCustomer.Text = pat.GetNameLF(); WebChatSession oldWebChatSession = _webChatSession.Clone(); _webChatSession.PatNum = pat.PatNum; WebChatSessions.Update(_webChatSession, oldWebChatSession); //update here so we can associate pats after chat has ended, or before ownership. }
///<summary>Inserts one WebChatSession into the database. Provides option to use the existing priKey. Doesn't use the cache.</summary> public static long InsertNoCache(WebChatSession webChatSession, bool useExistingPK) { string command = "INSERT INTO webchatsession ("; if (useExistingPK) { command += "WebChatSessionNum,"; } command += "UserName,PracticeName,EmailAddress,PhoneNumber,IsCustomer,QuestionText,TechName,DateTcreated,DateTend,PatNum,Note) VALUES("; if (useExistingPK) { command += POut.Long(webChatSession.WebChatSessionNum) + ","; } command += "'" + POut.String(webChatSession.UserName) + "'," + "'" + POut.String(webChatSession.PracticeName) + "'," + "'" + POut.String(webChatSession.EmailAddress) + "'," + "'" + POut.String(webChatSession.PhoneNumber) + "'," + POut.Bool(webChatSession.IsCustomer) + "," + "'" + POut.String(webChatSession.QuestionText) + "'," + "'" + POut.String(webChatSession.TechName) + "'," + POut.DateT(webChatSession.DateTcreated) + "," + POut.DateT(webChatSession.DateTend) + "," + POut.Long(webChatSession.PatNum) + "," + DbHelper.ParamChar + "paramNote)"; if (webChatSession.Note == null) { webChatSession.Note = ""; } OdSqlParameter paramNote = new OdSqlParameter("paramNote", OdDbType.Text, POut.StringNote(webChatSession.Note)); if (useExistingPK) { Db.NonQ(command, paramNote); } else { webChatSession.WebChatSessionNum = Db.NonQ(command, true, "WebChatSessionNum", "webChatSession", paramNote); } return(webChatSession.WebChatSessionNum); }
private void FillTile() { //UpdateComboRooms();//We can't do this in the constructor and all the other methods fire too often. FillTile is a good place for this. //Get the new phone list from the database and redraw control. SetPhoneList(PhoneEmpDefaults.Refresh(), Phones.GetPhoneList()); //Set the currently selected phone accordingly. if (_listPhones == null) //No phone list. Shouldn't get here. { phoneTile.SetPhone(null, null, null, false, null); return; } Phone phone = Phones.GetPhoneForExtension(_listPhones, Extension); PhoneEmpDefault phoneEmpDefault = null; ChatUser chatUser = null; WebChatSession webChatSession = null; if (phone != null) { phoneEmpDefault = PhoneEmpDefaults.GetEmpDefaultFromList(phone.EmployeeNum, _listPhoneEmpDefaults); chatUser = ChatUsers.GetFromExt(phone.Extension); webChatSession = WebChatSessions.GetActiveSessionsForEmployee(phone.EmployeeName); } phoneTile.SetPhone(phone, phoneEmpDefault, chatUser, PhoneEmpDefaults.IsTriageOperatorForExtension(Extension, _listPhoneEmpDefaults), webChatSession); }
///<summary>Converts a DataTable to a list of objects.</summary> public static List <WebChatSession> TableToList(DataTable table) { List <WebChatSession> retVal = new List <WebChatSession>(); WebChatSession webChatSession; foreach (DataRow row in table.Rows) { webChatSession = new WebChatSession(); webChatSession.WebChatSessionNum = PIn.Long(row["WebChatSessionNum"].ToString()); webChatSession.UserName = PIn.String(row["UserName"].ToString()); webChatSession.PracticeName = PIn.String(row["PracticeName"].ToString()); webChatSession.EmailAddress = PIn.String(row["EmailAddress"].ToString()); webChatSession.PhoneNumber = PIn.String(row["PhoneNumber"].ToString()); webChatSession.IsCustomer = PIn.Bool(row["IsCustomer"].ToString()); webChatSession.QuestionText = PIn.String(row["QuestionText"].ToString()); webChatSession.TechName = PIn.String(row["TechName"].ToString()); webChatSession.DateTcreated = PIn.DateT(row["DateTcreated"].ToString()); webChatSession.DateTend = PIn.DateT(row["DateTend"].ToString()); webChatSession.PatNum = PIn.Long(row["PatNum"].ToString()); webChatSession.Note = PIn.String(row["Note"].ToString()); retVal.Add(webChatSession); } return(retVal); }
///<summary>Updates one WebChatSession in the database.</summary> public static void Update(WebChatSession webChatSession) { string command = "UPDATE webchatsession SET " + "UserName = '******', " + "PracticeName = '" + POut.String(webChatSession.PracticeName) + "', " + "EmailAddress = '" + POut.String(webChatSession.EmailAddress) + "', " + "PhoneNumber = '" + POut.String(webChatSession.PhoneNumber) + "', " + "IsCustomer = " + POut.Bool(webChatSession.IsCustomer) + ", " + "QuestionText = '" + POut.String(webChatSession.QuestionText) + "', " + "TechName = '" + POut.String(webChatSession.TechName) + "', " + "DateTcreated = " + POut.DateT(webChatSession.DateTcreated) + ", " + "DateTend = " + POut.DateT(webChatSession.DateTend) + ", " + "PatNum = " + POut.Long(webChatSession.PatNum) + ", " + "Note = " + DbHelper.ParamChar + "paramNote " + "WHERE WebChatSessionNum = " + POut.Long(webChatSession.WebChatSessionNum); if (webChatSession.Note == null) { webChatSession.Note = ""; } OdSqlParameter paramNote = new OdSqlParameter("paramNote", OdDbType.Text, POut.StringNote(webChatSession.Note)); Db.NonQ(command, paramNote); }
///<summary>Set phone and triage flag to display. Get/Set accessor won't work here because we require 2 seperate fields in order to update the control properly.</summary> public void SetPhone(Phone phone, PhoneEmpDefault phoneEmpDefault, ChatUser chatUserCur, bool isTriageOperator , WebChatSession webChatSession, bool doHideIfNoPhone = false) { _phoneCur = phone; if (_phoneCur == null) //empty out everything and return { pictureInUse.Visible = false; labelStatusAndNote.Text = ""; pictureProx.Visible = false; labelExtensionName.Text = ""; labelTime.Text = ""; labelTime.BackColor = this.BackColor; pictureNeedsHelpButton.Visible = false; pictureGTA.Visible = false; pictureWebChat.Visible = false; labelCustomer.Text = "Invalid Comp or Phone"; if (doHideIfNoPhone) { labelCustomer.Visible = false; labelTime.Visible = false; } return; } labelCustomer.Visible = true; labelTime.Visible = true; pictureInUse.Visible = _phoneCur.Description != ""; //Check if the user is logged in. if (_phoneCur.ClockStatus == ClockStatusEnum.Home || _phoneCur.ClockStatus == ClockStatusEnum.None || _phoneCur.ClockStatus == ClockStatusEnum.Off) { labelStatusAndNote.Text = "Clock In"; } else { labelStatusAndNote.Text = _phoneCur.ClockStatus.GetDescription(); } //Always show ext and name, no matter if user is clocked in or not. This keeps phone tiles from appearing blank with no extension and name. /*if(_phoneCur.EmployeeName!="") { * labelExtensionName.Text=_phoneCur.Extension.ToString()+"-"+_phoneCur.EmployeeName; * } * else { * labelExtensionName.Text=_phoneCur.Extension.ToString()+"-Vacant"; * }*/ if (_phoneCur.DateTimeNeedsHelpStart.Date == DateTime.Today) { labelTime.Text = (DateTime.Now - _phoneCur.DateTimeNeedsHelpStart + TimeDelta).ToStringHmmss(); } else if (_phoneCur.DateTimeStart.Date == DateTime.Today) { labelTime.Text = (DateTime.Now - _phoneCur.DateTimeStart + TimeDelta).ToStringHmmss(); } else { labelTime.Text = ""; } if (_phoneCur.ClockStatus == ClockStatusEnum.Home || _phoneCur.ClockStatus == ClockStatusEnum.None || _phoneCur.ClockStatus == ClockStatusEnum.Break) { labelTime.BackColor = this.BackColor; //No color if employee is not currently working. pictureNeedsHelpButton.BackColor = this.BackColor; //No color if employee is not currently working. } else { Color outerColor; Color innerColor; Color fontColor; bool isTriageOperatorOnTheClock = false; //get the cubicle color and triage status Phones.GetPhoneColor(phone, phoneEmpDefault, false, out outerColor, out innerColor, out fontColor, out isTriageOperatorOnTheClock); if (!timerFlash.Enabled) { //if the control is already flashing then don't overwrite the colors. this would cause a "spastic" flash effect. Phones.PhoneColorScheme colorScheme = new Phones.PhoneColorScheme(true); labelTime.BackColor = outerColor; if (phone.ClockStatus == ClockStatusEnum.HelpOnTheWay) { labelTime.BackColor = colorScheme.ColorOuterNeedsHelp; } if (_phoneCur.ClockStatus == ClockStatusEnum.NeedsHelp) { //Only start the flash timer and color the control once. This prevents over-flashing effect. labelTime.Tag = new object[2] { false, colorScheme.ColorOuterNeedsHelp }; // labelTime.BackColor }; timerFlash.Start(); } } } if (_phoneCur.ClockStatus != ClockStatusEnum.NeedsHelp) //Always assume the flash timer was previously turned on and turn it off here. No harm if it' already off. { timerFlash.Stop(); } if (_phoneCur.ClockStatus == ClockStatusEnum.Home || _phoneCur.ClockStatus == ClockStatusEnum.None) { labelTime.BorderStyle = System.Windows.Forms.BorderStyle.None; //Remove color box if employee is not currently working. } else { labelTime.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; } labelCustomer.Text = _phoneCur.CustomerNumber; //Always show ext and name, no matter if user is clocked in or not. This keeps phone tiles from appearing blank with no extension and name. if (_phoneCur.EmployeeName != "") { labelExtensionName.Text = _phoneCur.Extension.ToString() + "-" + _phoneCur.EmployeeName; // +(IsProximal ? " "+_cPerson : ""); } else { labelExtensionName.Text = _phoneCur.Extension.ToString() + "-Vacant"; } pictureProx.Visible = true; if (phone.IsProxVisible) { pictureProx.Image = Properties.Resources.Figure; } else if (phone.DateTProximal.AddHours(8) > DateTime.Now) { pictureProx.Image = Properties.Resources.NoFigure; //TODO: replace image with one from Nathan } else { pictureProx.Visible = false; } if (LayoutHorizontal) //never used anymore. Was used to draw large phone map. //Warning!: never change the layout in the designer without considering how those settings are used in the vertical layout. { this.labelExtensionName.Location = new Point(0, 0); pictureProx.Location = new Point(161, 3); } else //vertical (the one at the lower left of each person's screen) { int stringW = TextRenderer.MeasureText(labelExtensionName.Text, labelExtensionName.Font).Width; int locationX = labelExtensionName.Location.X + stringW + (labelExtensionName.Width - stringW) / 2 //half of the unused space around the centered text + 1; //padding pictureProx.Location = new Point(locationX, 6); pictureNeedsHelpButton.Visible = true; } if (phone.ClockStatus == ClockStatusEnum.Home || phone.ClockStatus == ClockStatusEnum.Lunch || phone.ClockStatus == ClockStatusEnum.Break || phone.ClockStatus == ClockStatusEnum.None) { pictureNeedsHelpButton.Visible = false; } else { pictureNeedsHelpButton.Enabled = true; pictureNeedsHelpButton.Image = Properties.Resources.raisehanddisabled; } if (pictureInUse.Visible) { pictureWebChat.Visible = false; pictureWebChat.SendToBack(); pictureGTA.Visible = false; pictureGTA.SendToBack(); } else if (webChatSession != null) //active webChatSession { pictureWebChat.Visible = true; pictureWebChat.BringToFront(); labelTime.Text = (DateTime.Now - webChatSession.DateTcreated).ToStringHmmss(); } else if (chatUserCur != null && chatUserCur.CurrentSessions != 0) //active GTA session { pictureGTA.Visible = true; pictureGTA.BringToFront(); labelTime.Text = TimeSpan.FromMilliseconds(chatUserCur.SessionTime).ToStringHmmss(); } else //no active chat sessions { ResetTimer(pictureWebChat.Visible); //Reset can only happen if user just closed a webchat. pictureWebChat.Visible = false; pictureWebChat.SendToBack(); pictureGTA.Visible = false; pictureGTA.SendToBack(); } }
///<summary>Set the phone which is linked to the extension at this desk. If phone==null then no phone info shown.</summary> public void SetPhone(Phone phone, PhoneEmpDefault phoneEmpDefault, ChatUser chat, bool isTriageOperator, WebChatSession webChatSession) { phoneTile.SetPhone(phone, phoneEmpDefault, chat, isTriageOperator, webChatSession); }
///<summary>Updates one WebChatSession in the database. Uses an old object to compare to, and only alters changed fields. This prevents collisions and concurrency problems in heavily used tables. Returns true if an update occurred.</summary> public static bool Update(WebChatSession webChatSession, WebChatSession oldWebChatSession) { string command = ""; if (webChatSession.UserName != oldWebChatSession.UserName) { if (command != "") { command += ","; } command += "UserName = '******'"; } if (webChatSession.PracticeName != oldWebChatSession.PracticeName) { if (command != "") { command += ","; } command += "PracticeName = '" + POut.String(webChatSession.PracticeName) + "'"; } if (webChatSession.EmailAddress != oldWebChatSession.EmailAddress) { if (command != "") { command += ","; } command += "EmailAddress = '" + POut.String(webChatSession.EmailAddress) + "'"; } if (webChatSession.PhoneNumber != oldWebChatSession.PhoneNumber) { if (command != "") { command += ","; } command += "PhoneNumber = '" + POut.String(webChatSession.PhoneNumber) + "'"; } if (webChatSession.IsCustomer != oldWebChatSession.IsCustomer) { if (command != "") { command += ","; } command += "IsCustomer = " + POut.Bool(webChatSession.IsCustomer) + ""; } if (webChatSession.QuestionText != oldWebChatSession.QuestionText) { if (command != "") { command += ","; } command += "QuestionText = '" + POut.String(webChatSession.QuestionText) + "'"; } if (webChatSession.TechName != oldWebChatSession.TechName) { if (command != "") { command += ","; } command += "TechName = '" + POut.String(webChatSession.TechName) + "'"; } if (webChatSession.DateTcreated != oldWebChatSession.DateTcreated) { if (command != "") { command += ","; } command += "DateTcreated = " + POut.DateT(webChatSession.DateTcreated) + ""; } if (webChatSession.DateTend != oldWebChatSession.DateTend) { if (command != "") { command += ","; } command += "DateTend = " + POut.DateT(webChatSession.DateTend) + ""; } if (webChatSession.PatNum != oldWebChatSession.PatNum) { if (command != "") { command += ","; } command += "PatNum = " + POut.Long(webChatSession.PatNum) + ""; } if (webChatSession.Note != oldWebChatSession.Note) { if (command != "") { command += ","; } command += "Note = " + DbHelper.ParamChar + "paramNote"; } if (command == "") { return(false); } if (webChatSession.Note == null) { webChatSession.Note = ""; } OdSqlParameter paramNote = new OdSqlParameter("paramNote", OdDbType.Text, POut.StringNote(webChatSession.Note)); command = "UPDATE webchatsession SET " + command + " WHERE WebChatSessionNum = " + POut.Long(webChatSession.WebChatSessionNum); Db.NonQ(command, paramNote); return(true); }
private void FillGridWebChatSurveys() { gridWebChatSurveys.BeginUpdate(); if (gridWebChatSurveys.ListGridColumns.Count == 0) { gridWebChatSurveys.ListGridColumns.Add(new GridColumn("DateTime", 80, HorizontalAlignment.Center, GridSortingStrategy.DateParse)); gridWebChatSurveys.ListGridColumns.Add(new GridColumn("Owner", 80, HorizontalAlignment.Left)); gridWebChatSurveys.ListGridColumns.Add(new GridColumn("PatNum", 80, HorizontalAlignment.Right, GridSortingStrategy.AmountParse)); gridWebChatSurveys.ListGridColumns.Add(new GridColumn("SessionNum", 90, HorizontalAlignment.Right, GridSortingStrategy.AmountParse)); gridWebChatSurveys.ListGridColumns.Add(new GridColumn("Rating", 80, HorizontalAlignment.Center)); gridWebChatSurveys.ListGridColumns.Add(new GridColumn("Comment", 0, HorizontalAlignment.Left)); gridWebChatSurveys.ListGridColumns.Add(new GridColumn("Experience", 0, HorizontalAlignment.Left)); } gridWebChatSurveys.ListGridRows.Clear(); List <WebChatSession> listWebChatSessions = null; List <WebChatSurvey> listWebChatSurveys = null; //If connection to webchat is lost or not visible from a specific network location, then continue, in order to keep the call center operational. ODException.SwallowAnyException(() => { listWebChatSessions = WebChatSessions.GetSessions(true, dateRangeWebChat.GetDateTimeFrom(), dateRangeWebChat.GetDateTimeTo()); listWebChatSurveys = WebChatSurveys.GetSurveysForSessions(listWebChatSessions.Select(x => x.WebChatSessionNum).ToList()); }); if (listWebChatSessions == null || listWebChatSurveys == null) { return; } int totalPositive = 0; int totalNeutral = 0; int totalNegative = 0; List <Userod> listSelectedUsers = comboUsers.SelectedTags <Userod>(); List <string> listSelectedUsernames = listSelectedUsers.Select(x => x.UserName).ToList(); foreach (WebChatSurvey webChatSurvey in listWebChatSurveys) { if (!string.IsNullOrEmpty(textSessionNum.Text) && !webChatSurvey.WebChatSessionNum.ToString().Contains(textSessionNum.Text)) { continue; } string searchText = textSurveyTextContains.Text.ToLower(); if (!string.IsNullOrEmpty(searchText) && !webChatSurvey.CustomerComment.ToLower().Contains(searchText) && !webChatSurvey.CustomerExperience.ToLower().Contains(searchText)) { continue; } WebChatSession webChatSession = listWebChatSessions.First(x => x.WebChatSessionNum == webChatSurvey.WebChatSessionNum); if (listSelectedUsernames.Count > 0 && !listSelectedUsernames.Contains(webChatSession.TechName)) { continue; } if (webChatSurvey.TechRating == TechSurveyRating.Positive) { totalPositive++; } else if (webChatSurvey.TechRating == TechSurveyRating.Neutral) { totalNeutral++; } else if (webChatSurvey.TechRating == TechSurveyRating.Negative) { totalNegative++; } GridRow row = new GridRow(); row.Tag = webChatSession; row.Cells.Add(webChatSession.DateTcreated.ToString()); row.Cells.Add(webChatSession.TechName); row.Cells.Add((webChatSession.PatNum == 0)?"":webChatSession.PatNum.ToString()); row.Cells.Add(webChatSession.WebChatSessionNum.ToString()); row.Cells.Add(webChatSurvey.TechRating.ToString()); row.Cells.Add(webChatSurvey.CustomerComment); row.Cells.Add(webChatSurvey.CustomerExperience); gridWebChatSurveys.ListGridRows.Add(row); } gridWebChatSurveys.EndUpdate(); labelTotals.Text = "Totals: Positive (" + totalPositive + ") Neutral (" + totalNeutral + ") Negative (" + totalNegative + ")"; }
///<summary>Inserts one WebChatSession into the database. Returns the new priKey. Doesn't use the cache.</summary> public static long InsertNoCache(WebChatSession webChatSession) { return(InsertNoCache(webChatSession, false)); }
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; Pen pen = new Pen(Color.Black); SolidBrush solidBrush = new SolidBrush(Color.Black); Font fontDraw = new Font("Microsoft Sans Serif", 8.25f); Font fontBold = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Bold); List <WebChatSession> listWebChatSessions = WebChatSessions.GetActiveSessions(); int controlHeight = 16; int controlMargin = 3; int customerWidth = 80; int customerX = 60; int customerY = 18; int extensionWidth = 96; int statusWidth = 62; int statusX = 0; int statusY = 20; int imageLocationX = 99; int proxLocationX = 126; int timeBoxLocationX = 3; int timeBoxLocationY = 17; int timeBoxWidth = 56; int timeLocationX = 11; int yTop = _tileStart; //the offset of the phone tile taking the other controls of the form into account int x = 0; //x axis location int y = 0; //y axis location int numColumns = (int)Math.Ceiling((double)_listPhones.Count / _tilesPerColumn); int webChatHeightWidth = 17; //Used for the rectangle that houses the web chat icon to prevent it from breaking the box boundary. //i starts at 1, because it determines the number of columns with modulo division on line if(i%_tilesPerColumn==0) for (int i = 1; i < _listPhones.Count + 1; i++) { int numCur = i - 1; ChatUser chatUser = _listChatUsers.Where(chat => chat.Extension == _listPhones[numCur].Extension).FirstOrDefault(); WebChatSession webChatSession = listWebChatSessions.FirstOrDefault(session => session.TechName == _listPhones[numCur].EmployeeName); Color outerColor; Color innerColor; Color fontColor; bool isTriageOperatorOnTheClock = false; //set the phone color Phones.GetPhoneColor(_listPhones[numCur], _listPhoneEmpDefaults.Find(phone => phone.EmployeeNum == _listPhones[numCur].EmployeeNum), false, out outerColor, out innerColor, out fontColor, out isTriageOperatorOnTheClock); //get the color scheme Phones.PhoneColorScheme phoneColorScheme = new Phones.PhoneColorScheme(true); string extensionAndName = $"{_listPhones[numCur].Extension}-{_listPhones[numCur].EmployeeName}"; //determine if the extension has a user associated with it if (_listPhones[numCur].EmployeeName == "") { extensionAndName += "Vacant"; } //determine the status or note if the user is gone, otherwise just leave it string statusAndNote = ""; if (_listPhones[numCur].ClockStatus == ClockStatusEnum.Home || _listPhones[numCur].ClockStatus == ClockStatusEnum.None || _listPhones[numCur].ClockStatus == ClockStatusEnum.Off) { statusAndNote = "Clock In"; } if (_listPhones[numCur].ClockStatus == ClockStatusEnum.Unavailable) { statusAndNote = "Unavailable"; } //get the customer number string customer = _listPhones[numCur].CustomerNumber; //get the time that has passed on a call string time = ""; if (_listPhones[numCur].DateTimeNeedsHelpStart.Date == DateTime.Today) { time = (DateTime.Now - _listPhones[numCur].DateTimeNeedsHelpStart + _timeSpanDelta).ToStringHmmss(); } else if (_listPhones[numCur].DateTimeStart.Date == DateTime.Today) { time = (DateTime.Now - _listPhones[numCur].DateTimeStart + _timeSpanDelta).ToStringHmmss(); } //draw the time box with its determined color Color colorBar = outerColor; //don't draw anything if they are clocked out or unavailable if (_listPhones[numCur].ClockStatus != ClockStatusEnum.Home && _listPhones[numCur].ClockStatus != ClockStatusEnum.None && _listPhones[numCur].ClockStatus != ClockStatusEnum.Off && _listPhones[numCur].ClockStatus != ClockStatusEnum.Unavailable) { //determine if they need help and flash pink if they do if (_listPhones[numCur].ClockStatus == ClockStatusEnum.NeedsHelp) { if (_isFlashingPink) { colorBar = phoneColorScheme.ColorOuterNeedsHelp; } else { colorBar = Color.Transparent; } } //set the color of the inside of the time box if (_listPhones[numCur].ClockStatus == ClockStatusEnum.HelpOnTheWay) { colorBar = phoneColorScheme.ColorOuterNeedsHelp; } //draw the inside of the time box if the user is not on break if (_listPhones[numCur].ClockStatus != ClockStatusEnum.Break) { using (SolidBrush brush = new SolidBrush(colorBar)) { g.FillRectangle(brush, (x * _tileWidth) + timeBoxLocationX, (y * _tileHeight) + yTop + timeBoxLocationY, timeBoxWidth, controlHeight); } } //draw the outline of the time box g.DrawRectangle(pen, (x * _tileWidth) + timeBoxLocationX, (y * _tileHeight) + yTop + timeBoxLocationY, timeBoxWidth, controlHeight); //draw either the figure or circle depending on if they are proxmial if (_listPhones[numCur].IsProxVisible) { g.DrawImage(Properties.Resources.Figure, (x * _tileWidth) + proxLocationX, (y * _tileHeight) + yTop + controlMargin); } else if (_listPhones[numCur].DateTProximal.AddHours(8) > DateTime.Now) { g.DrawImage(Properties.Resources.NoFigure, (x * _tileWidth) + proxLocationX, (y * _tileHeight) + yTop + controlMargin); } //draw the phone image if it is in use if (_listPhones[numCur].Description != "") { g.DrawImage(Properties.Resources.phoneInUse, (x * _tileWidth) + imageLocationX, (y * _tileHeight) + yTop + controlMargin); } else if (webChatSession != null) { g.DrawImage(Properties.Resources.WebChatIcon, new Rectangle((x * _tileWidth) + imageLocationX, (y * _tileHeight) + yTop + controlMargin, webChatHeightWidth, webChatHeightWidth)); time = (DateTime.Now - webChatSession.DateTcreated).ToStringHmmss(); } else if (chatUser != null && chatUser.CurrentSessions != 0) { g.DrawImage(Properties.Resources.gtaicon3, (x * _tileWidth) + imageLocationX, (y * _tileHeight) + yTop + controlMargin); time = TimeSpan.FromMilliseconds(chatUser.SessionTime).ToStringHmmss(); } //draw the time on call or what ever activity they are doing if (time != "") { g.DrawString(time, fontDraw, solidBrush, (x * _tileWidth) + timeLocationX, (y * _tileHeight) + yTop + timeBoxLocationY + 2); } } //draw the things that need to be shown at all times such as the employee name, customer, and emp status g.DrawString(extensionAndName, fontBold, solidBrush, new RectangleF((x * _tileWidth), (y * _tileHeight) + yTop + controlMargin, extensionWidth, controlHeight), new StringFormat() { FormatFlags = StringFormatFlags.NoWrap }); if (statusAndNote != "") //the status only shows if it is Clock In or Unavailable { g.DrawString(statusAndNote, fontDraw, solidBrush, new RectangleF((x * _tileWidth) + statusX, (y * _tileHeight) + yTop + statusY, statusWidth, controlHeight), new StringFormat() { Trimming = StringTrimming.EllipsisCharacter, FormatFlags = StringFormatFlags.NoWrap }); } g.DrawString(customer, fontDraw, solidBrush, new RectangleF((x * _tileWidth) + customerX, (y * _tileHeight) + yTop + customerY + controlMargin, customerWidth, controlHeight), new StringFormat() { Trimming = StringTrimming.EllipsisCharacter, FormatFlags = StringFormatFlags.NoWrap }); //draw the grid lines if (i == 1) //this line needs to be drawn differently than the rest { g.DrawLine(pen, 0, yTop, numColumns * _tileWidth, yTop); } else { g.DrawLine(pen, 0, (_tileHeight * y) + yTop, numColumns * _tileWidth, (_tileHeight * y) + yTop); } y++; if (i % _tilesPerColumn == 0 && i != _listPhones.Count) { x++; //draw the right grid line of the entire column g.DrawLine(pen, _tileWidth * x, yTop, _tileWidth * x, (_tileHeight * _tilesPerColumn) + yTop); y = 0; } } //for listPhones g.DrawLine(pen, 0, (_tileHeight * _tilesPerColumn) + yTop, numColumns * _tileWidth, (_tileHeight * _tilesPerColumn) + yTop); //final bottom line g.DrawLine(pen, _tileWidth * (x + 1), yTop, _tileWidth * (x + 1), (_tileHeight * _tilesPerColumn) + yTop); //final right line //dispose of the objects we no longer need pen.Dispose(); solidBrush.Dispose(); fontDraw.Dispose(); fontBold.Dispose(); }
///<summary>Refresh the phone panel every X seconds after it has already been setup. Make sure to call FillMapAreaPanel before calling ///this the first time.</summary> public void SetPhoneList(List <PhoneEmpDefault> peds, List <Phone> phones, List <PhoneEmpSubGroup> listSubGroups, List <ChatUser> listChatUsers, List <WebChatSession> listWebChatSessions) { //refresh our lists to minimize trips to the database. _listWebChatSessions = listWebChatSessions; _listChatUsers = listChatUsers; try { string title = "Call Center Map - Triage Coord. - "; try { //get the triage coord label but don't fail just because we can't find it SiteLink siteLink = SiteLinks.GetFirstOrDefault(x => x.SiteNum == _mapCur.SiteNum); title += Employees.GetNameFL(Employees.GetEmp(siteLink.EmployeeNum)); } catch { title += "Not Set"; } labelTriageCoordinator.Text = title; labelCurrentTime.Text = DateTime.Now.ToShortTimeString(); #region Triage Counts //The triage count used to only count up the triage operators within the currently selected room. //Now we want to count all operators at the selected site (local) and then all operators across all sites (total). int triageStaffCountLocal = 0; int triageStaffCountTotal = 0; foreach (PhoneEmpDefault phoneEmpDefault in peds.FindAll(x => x.IsTriageOperator && x.HasColor)) { Phone phone = phones.FirstOrDefault(x => x.Extension == phoneEmpDefault.PhoneExt); if (phone == null) { continue; } if (phone.ClockStatus.In(ClockStatusEnum.None, ClockStatusEnum.Home, ClockStatusEnum.Lunch, ClockStatusEnum.Break, ClockStatusEnum.Off , ClockStatusEnum.Unavailable, ClockStatusEnum.NeedsHelp, ClockStatusEnum.HelpOnTheWay)) { continue; } //This is a triage operator who is currently here and on the clock. if (phoneEmpDefault.SiteNum == _mapCur.SiteNum) { triageStaffCountLocal++; } triageStaffCountTotal++; } labelTriageOpsCountLocal.Text = triageStaffCountLocal.ToString(); labelTriageOpsCountTotal.Text = triageStaffCountTotal.ToString(); #endregion for (int i = 0; i < this.mapAreaPanelHQ.Controls.Count; i++) //loop through all of our cubicles and labels and find the matches { try { if (!(this.mapAreaPanelHQ.Controls[i] is MapAreaRoomControl)) { continue; } MapAreaRoomControl room = (MapAreaRoomControl)this.mapAreaPanelHQ.Controls[i]; if (room.MapAreaItem.Extension == 0) //This cubicle has not been given an extension yet. { room.Empty = true; continue; } Phone phone = Phones.GetPhoneForExtension(phones, room.MapAreaItem.Extension); if (phone == null) //We have a cubicle with no corresponding phone entry. { room.Empty = true; continue; } room.PhoneCur = phone; //Refresh PhoneCur so that it has up to date customer information. ChatUser chatuser = listChatUsers.Where(x => x.Extension == phone.Extension).FirstOrDefault(); PhoneEmpDefault phoneEmpDefault = PhoneEmpDefaults.GetEmpDefaultFromList(phone.EmployeeNum, peds); if (phoneEmpDefault == null) //We have a cubicle with no corresponding phone emp default entry. { room.Empty = true; continue; } //we got this far so we found a corresponding cubicle for this phone entry room.EmployeeNum = phone.EmployeeNum; room.EmployeeName = phone.EmployeeName; WebChatSession webChatSession = listWebChatSessions.FirstOrDefault(x => x.TechName == phone.EmployeeName); if (phone.DateTimeNeedsHelpStart.Date == DateTime.Today) //if they need help, use that time. { TimeSpan span = DateTime.Now - phone.DateTimeNeedsHelpStart + _timeDelta; DateTime timeOfDay = DateTime.Today + span; room.Elapsed = span; } else if (phone.DateTimeStart.Date == DateTime.Today && phone.Description != "") //else if in a call, use call time. { TimeSpan span = DateTime.Now - phone.DateTimeStart + _timeDelta; DateTime timeOfDay = DateTime.Today + span; room.Elapsed = span; } else if (phone.Description == "" && webChatSession != null) //else if in a web chat session, use web chat session time { TimeSpan span = DateTime.Now - webChatSession.DateTcreated + _timeDelta; room.Elapsed = span; } else if (phone.Description == "" && chatuser != null && chatuser.CurrentSessions > 0) //else if in a chat, use chat time. { TimeSpan span = TimeSpan.FromMilliseconds(chatuser.SessionTime) + _timeDelta; room.Elapsed = span; } else if (phone.DateTimeStart.Date == DateTime.Today) //else available, use that time. { TimeSpan span = DateTime.Now - phone.DateTimeStart + _timeDelta; DateTime timeOfDay = DateTime.Today + span; room.Elapsed = span; } else //else, whatever. { room.Elapsed = TimeSpan.Zero; } if (phone.IsProxVisible) { room.ProxImage = Properties.Resources.Figure; } else if (phone.DateTProximal.AddHours(8) > DateTime.Now) { room.ProxImage = Properties.Resources.NoFigure; //TODO: replace image with one from Nathan } else { room.ProxImage = null; } room.IsAtDesk = phone.IsProxVisible; string status = Phones.ConvertClockStatusToString(phone.ClockStatus); //Check if the user is logged in. if (phone.ClockStatus == ClockStatusEnum.None || phone.ClockStatus == ClockStatusEnum.Home) { status = "Home"; } room.Status = status; if (phone.Description == "") { room.PhoneImage = null; if (webChatSession != null) //active web chat session { room.WebChatImage = Properties.Resources.WebChatIcon; room.ChatImage = null; } //Only using one chat icon for both GTA and webchats now else if (chatuser != null && chatuser.CurrentSessions != 0) //check for GTA sessions if no web chats { room.WebChatImage = null; room.ChatImage = Properties.Resources.WebChatIcon; } else { room.WebChatImage = null; room.ChatImage = null; } } else { room.PhoneImage = Properties.Resources.phoneInUse; } Color outerColor; Color innerColor; Color fontColor; bool isTriageOperatorOnTheClock; //get the cubicle color and triage status Phones.GetPhoneColor(phone, phoneEmpDefault, true, out outerColor, out innerColor, out fontColor, out isTriageOperatorOnTheClock); if (!room.IsFlashing) //if the control is already flashing then don't overwrite the colors. this would cause a "spastic" flash effect. { room.OuterColor = outerColor; room.InnerColor = innerColor; } room.ForeColor = fontColor; if (phone.ClockStatus == ClockStatusEnum.NeedsHelp) //turn on flashing { room.StartFlashing(); } else //turn off flashing { room.StopFlashing(); } if (phone.EmployeeNum > 0 && phone.EmployeeNum == userControlMapDetails1.EmployeeNumCur) { userControlMapDetails1.UpdateControl(room); } room.Invalidate(true); } catch (Exception e) { e.DoNothing(); } } refreshCurrentTabHelper(peds, phones, listSubGroups); } catch { //something failed unexpectedly } }