using CsvHelper; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; /* References */ // Using a delegate to trigger method on the customer view form // https://www.coderslexicon.com/passing-data-between-forms-using-delegates-and-events/ namespace QueueSys { public partial class frmEmployeeView : Form { public frmEmployeeView() { InitializeComponent(); } // Our delegate (which "points" at any method which takes an object and EventArgs) // Look familiar? This is the signature of most control events on a form public delegate void SendMessage(object obj, EventArgs e); // Here is the event we trigger to send messages out to listeners public event SendMessage OnSendMessage; /* Execute when program / main form loads. * Pop up the customer view screen to drag onto second monitor * creates our second form, says "attach its MessageReceived function to the event" */ private void frmEmployeeView_Load(object sender, EventArgs e) { frmCustomerView frm = new frmCustomerView(); OnSendMessage += frm.MessageReceived; frm.Show(); RefreshEmployeeView(); } /* Enable options menu. */ private void optionsToolStripMenuItem_Click(object sender, EventArgs e) { frmOptions frm = new frmOptions(); frm.Show(); frm.Activate(); } // Exits the application. private void exitAltF4ToolStripMenuItem_Click(object sender, EventArgs e) => Environment.Exit(0); private void generateReportToolStripMenuItem_Click(object sender, EventArgs e) { //Build the default filename saveFileDialogReport.FileName = DateTime.Now.ToString("yy.MM.dd") + "-report.csv"; if(saveFileDialogReport.ShowDialog() == DialogResult.OK && saveFileDialogReport.FileName != "") { string filename = saveFileDialogReport.FileName; SqliteDataAccess sdaGenRep = new SqliteDataAccess(); List report = new List(); report = sdaGenRep.QueryReports(); TextWriter textWriter = new StreamWriter(filename); CsvWriter csvWriter = new CsvWriter(textWriter); csvWriter.WriteRecords(report); textWriter.Close(); MessageBox.Show("Report Generated", "Queue System", MessageBoxButtons.OK, MessageBoxIcon.None); } } private void btnAdd_Click(object sender, EventArgs e) { if(tbCustomerName.Text == "" || cbNumBags.Text == "" || tbEmployeeName.Text == "") { MessageBox.Show("Please fill in the customer intake fields"); return; } // Check to see if any control is in error. foreach(Control c in errorProvider1.ContainerControl.Controls) { if(errorProvider1.GetError(c) != "") { MessageBox.Show("Please fix the errors on the customer intake form!"); return; } } SqliteDataAccess sda = new SqliteDataAccess(); ReportView evNewCx = new ReportView(); evNewCx.customer_name = tbCustomerName.Text; evNewCx.num_bags = Int32.Parse(cbNumBags.Text); evNewCx.employee = tbEmployeeName.Text; sda.SaveCustomer(evNewCx); //Invoke the delegate to update customer view. OnSendMessage?.Invoke(this, e); tbCustomerName.Text = ""; cbNumBags.Text = ""; tbEmployeeName.Text = ""; RefreshEmployeeView(); MessageBox.Show("Customer has been added!", "Queue System", MessageBoxButtons.OK, MessageBoxIcon.None); } private void RefreshEmployeeView() { dgvEmployeeView.Rows.Clear(); //Clear the status and delete columns //as it fixes a bug duplicating these columns. if (dgvEmployeeView.Columns.Count == 4) { dgvEmployeeView.Columns.Remove(dgvEmployeeView.Columns[3]); dgvEmployeeView.Columns.Remove(dgvEmployeeView.Columns[2]); } dgvEmployeeView.Refresh(); // Build the row. SqliteDataAccess sdaEvView = new SqliteDataAccess(); List evList = new List(); evList = sdaEvView.LoadEmployeeView(); foreach (EmployeeView item in evList) { string[] row = new string[] { item.id.ToString(), item.customer_name }; dgvEmployeeView.Rows.Add(row); } DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn(); cmb.HeaderText = "Status"; cmb.MaxDropDownItems = 3; //Allows for dynamic adding/removing status items per //the status lookup table in the sqlite db. List s = new List(); s = sdaEvView.LoadStatusStrings(); foreach (StatusModel item in s) { cmb.Items.Add(item.status); } dgvEmployeeView.Columns.Add(cmb); //Change the status of the combobox based on the query from the db. List cxStatus = new List(); //Select the id column from the current row. foreach(DataGridViewRow row in dgvEmployeeView.Rows) { cxStatus = sdaEvView.GetCxStatus(Int32.Parse(dgvEmployeeView.Rows[row.Index].Cells[0].Value.ToString())); row.Cells[2].Value = cxStatus[0].status; } // Add the delete button. DataGridViewButtonColumn btn = new DataGridViewButtonColumn(); btn.HeaderText = "Delete"; btn.Text = "Delete"; btn.Name = "btn"; btn.UseColumnTextForButtonValue = true; dgvEmployeeView.Columns.Add(btn); } private void dgvEmployeeView_CellClick(object sender, DataGridViewCellEventArgs e) { //The delete button was clicked. if (e.ColumnIndex == 3) { //Sanity check, per option. if (Properties.Settings.Default.ConfirmDelete) { DialogResult result = MessageBox.Show("Are you sure you want to delete this customer?", "Queue System", MessageBoxButtons.YesNo, MessageBoxIcon.None); if (result == DialogResult.No) { MessageBox.Show("Customer was not deleted.", "Queue System", MessageBoxButtons.OK, MessageBoxIcon.None); return; } } SqliteDataAccess sdaEvView = new SqliteDataAccess(); EmployeeView evCustomer = new EmployeeView(); evCustomer.id = Int32.Parse(dgvEmployeeView.CurrentRow.Cells[0].Value.ToString()); sdaEvView.ArchiveCustomer(evCustomer); RefreshEmployeeView(); //Invoke the delegate to update customer view with updated data. OnSendMessage?.Invoke(this, e); MessageBox.Show("Customer has been removed from the queue", "Queue System", MessageBoxButtons.OK, MessageBoxIcon.None); } } // This event hooks the status combobox into the change commit event private void dgvEmployeeView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { if (dgvEmployeeView.CurrentCell.ColumnIndex == 2) { ComboBox combo = e.Control as ComboBox; if(combo != null) { combo.SelectionChangeCommitted += new EventHandler(dgvCbStatus_SelectionChangeCommitted); } } } /* This event fires when the "status" combo box was changed * and that change was "committed" * This is needed to update the backend SQL db on demand, * then update the customer view screen. */ private void dgvCbStatus_SelectionChangeCommitted(object sender, EventArgs e) { DataGridViewComboBoxEditingControl dgvcbec = sender as DataGridViewComboBoxEditingControl; int CustomerId = Int32.Parse(dgvcbec.EditingControlDataGridView.CurrentRow.Cells[0].Value.ToString()); string new_status = dgvcbec.Text; //Check to see if we need an update. SqliteDataAccess sdaEvView = new SqliteDataAccess(); List cxStatus = new List(); cxStatus = sdaEvView.GetCxStatus(CustomerId); // Update not required. if (cxStatus[0].status == new_status) return; /* Update of the backend DB required beyond this point * Update the customer status on the backend db. */ sdaEvView.UpdateCustomerStatus(CustomerId, new_status); if(new_status == "Ready") { sdaEvView.UpdateEndTime(CustomerId, "add"); } else { sdaEvView.UpdateEndTime(CustomerId, "remove"); } //Invoke the delegate to update customer view with updated data. OnSendMessage?.Invoke(this, e); } private void tbCustomerName_Validating(object sender, CancelEventArgs e) { if (!Regex.IsMatch(tbCustomerName.Text, "[A-Za-z]{2,}")) { errorProvider1.SetError(tbCustomerName, "Enter customer name a-z only!"); } else { errorProvider1.SetError(tbCustomerName, ""); } } private void cbNumBags_Validating(object sender, CancelEventArgs e) { if (cbNumBags.SelectedIndex < 0) { errorProvider1.SetError(cbNumBags, "Select the number of bags."); } else { errorProvider1.SetError(cbNumBags, ""); } } private void tbEmployeeName_Validating(object sender, CancelEventArgs e) { if (!Regex.IsMatch(tbEmployeeName.Text, "[A-Za-z]{2,}")) { errorProvider1.SetError(tbEmployeeName, "Enter the employee name a-z only!"); } else { errorProvider1.SetError(tbEmployeeName, ""); } } } }