Added support for deleting records from the APC and invoice tables that have been committed to the database. Fixed the color coding bug where the Ad Special row would get the pending edit color instead of no coloring.

This commit is contained in:
2016-12-16 15:41:17 -06:00
parent 91c2326db2
commit bd586580e6
7 changed files with 520 additions and 34 deletions
+210 -29
View File
@@ -94,6 +94,8 @@ namespace AdvertsingProfitControl
invoicesDataGridView.CellValidating += ValidateInvoicesCellContents;
//Grab the underlying text box object in the ad item cell, and build an auto complete list for the user.
invoicesDataGridView.EditingControlShowing += DisplaySupplierAutoComleteOnEditingShadowControl;
//Subscribe the method to allow the user to delete saved rows from the Invoices table.
invoicesDataGridView.UserDeletingRow += UpdateInvoicesOnRowDeleting;
//Finally build the last DataGridView for the form.
ConstructInvoicesDataGridView();//No weekly sales table is nice.
//Subscribe the comments text box to check if changes have been made on leave.
@@ -333,6 +335,45 @@ namespace AdvertsingProfitControl
autoText.AutoCompleteCustomSource = _supplierCollection;
}
/// <summary>
/// Checks to see if the row that the user is attempting to delete has been saved to the database.
/// If so, this method will try to delete the record, failing that it will cancel the row deletion.
/// </summary>
/// <param name="sender">Invoice table.</param>
/// <param name="e"></param>
private void UpdateInvoicesOnRowDeleting(object sender, DataGridViewRowCancelEventArgs e)
{
var rowIndex = e.Row.Index;
//See if there is an ID number in the ID column.
if (invoicesDataGridView.Rows[rowIndex].Cells[(int) InvoiceTableColumns.Id].EditedFormattedValue.ToString() == "") return;
//Ask the user to make damn sure they want to remove this record.
var result = MessageBox.Show(@"Deleting this row will remove it from the database permanently. Do you wish to continue?", @"Remove Invoice Number " + invoicesDataGridView.Rows[rowIndex].Cells[(int)InvoiceTableColumns.InvoiceNumber].EditedFormattedValue, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
//If so create the database interaction objects.
var dbTracker = new DatabaseTracker();
var dbWriter = new DatabaseWriter(dbTracker.DatabaseConnectionString);
var id =
int.Parse(
invoicesDataGridView.Rows[rowIndex].Cells[(int) InvoiceTableColumns.Id].EditedFormattedValue
.ToString());
if (dbWriter.DeleteInvoiceRow(id))
{
informationLabel.Text = @"Successfully removed row " + (rowIndex + 1) + @" from the database.";
}
else
{
//The operation failed.
errorLabel.Text = @"Failed to delete row " + (rowIndex + 1) + @" from invoices.";
e.Cancel = true;
}
}
else
{
e.Cancel = true;
}
}
#endregion
#region APC DataGridView Events
@@ -477,16 +518,67 @@ namespace AdvertsingProfitControl
{
//Create an object that represents the DataGridView that fired the event.
var dataGridView = (DataGridView)sender;
if (dataGridView.CurrentRow == null) return;
if (dataGridView.CurrentRow == null) return;
//Create the database writer object so rows that are in the database can be deleted.
var dbTracker = new DatabaseTracker();
var dbWriter = new DatabaseWriter(dbTracker.DatabaseConnectionString);
var currentRowIndex = dataGridView.CurrentRow.Index;
//Remove the ad item from the gUsedAdItem collection, if it exists.
if (_adSpecialIndex == -1)
{
//If the ID number is set, i.e. not equal to null then attempt to remove it from the database.
if (dataGridView.Rows[currentRowIndex].Cells[0].EditedFormattedValue.ToString() != "")
{
var result = MessageBox.Show(@"Removing this row will permanently delete this record from the database. Do you wish to continue?", @"Remove " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue, MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
//Attempt to delete the row from the database by its ID number.
var projectionsRowId = int.Parse(projectionsDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
var inventoryRowId = int.Parse(inventoryDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
var actualSalesRowId = int.Parse(actualSalesDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
if (dbWriter.DeleteApcRow(projectionsRowId, inventoryRowId, actualSalesRowId))
{
informationLabel.Text = @"Successfully removed row " + (currentRowIndex + 1) + @" from the database.";
}
else
{
//If the removing failed cancel the row deletion in the DataGridView.
e.Cancel = true;
MessageBox.Show(@"Failed to delete " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue +
@" from the database.", @"Failed to Update Database");
return;
}
}
}
//If the ad item entered in the first cell is in the gUsedAdItems collection, then remove it from there.
_usedAdItems[0].Remove(dataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString());
}
else if (currentRowIndex < _adSpecialIndex)
{
//If the ID number is set, i.e. not equal to null then attempt to remove it from the database.
if (dataGridView.Rows[currentRowIndex].Cells[0].EditedFormattedValue.ToString() != "")
{
var result = MessageBox.Show(@"Removing this row will permanently delete this record from the database. Do you wish to continue?", @"Remove " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue, MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
//Attempt to delete the row from the database by its ID number.
var projectionsRowId = int.Parse(projectionsDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
var inventoryRowId = int.Parse(inventoryDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
var actualSalesRowId = int.Parse(actualSalesDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
if (dbWriter.DeleteApcRow(projectionsRowId, inventoryRowId, actualSalesRowId))
{
informationLabel.Text = @"Successfully removed row " + (currentRowIndex + 1) + @" from the database.";
}
else
{
//If the removing failed cancel the row deletion in the DataGridView.
e.Cancel = true;
MessageBox.Show(@"Failed to delete " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue +
@" from the database.", @"Failed to Update Database");
return;
}
}
}
//If the ad item entered in the first cell is in the gUsedAdItems collection, then remove it from there.
_usedAdItems[0].Remove(dataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString());
//Also decrement the _adSpecialIndex so that it points to the correct row.
@@ -494,12 +586,35 @@ namespace AdvertsingProfitControl
}
else if (currentRowIndex > _adSpecialIndex)
{
//If the ID number is set, i.e. not equal to null then attempt to remove it from the database.
if (dataGridView.Rows[currentRowIndex].Cells[0].EditedFormattedValue.ToString() != "")
{
var result = MessageBox.Show(@"Removing this row will permanently delete this record from the database. Do you wish to continue?", @"Remove " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue, MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
//Attempt to delete the row from the database by its ID number.
var projectionsRowId = int.Parse(projectionsDataGridView.Rows[currentRowIndex].Cells[(int) SalesTableColumns.Id].EditedFormattedValue.ToString());
var inventoryRowId = int.Parse(inventoryDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
var actualSalesRowId = int.Parse(actualSalesDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
if (dbWriter.DeleteApcRow(projectionsRowId, inventoryRowId, actualSalesRowId))
{
informationLabel.Text = @"Successfully removed row " + (currentRowIndex + 1) + @" from the database.";
}
else
{
//If the removing failed cancel the row deletion in the DataGridView.
e.Cancel = true;
MessageBox.Show(@"Failed to delete " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue +
@" from the database.", @"Failed to Update Database");
return;
}
}
}
//If the ad item entered in the first cell is in the gUsedAdItems collection, then remove it from there.
_usedAdItems[1].Remove(dataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString());
}
else if (currentRowIndex == _adSpecialIndex)
{
{
//Handle removing the AdSpecial row.
var result = MessageBox.Show(@"Deleting the Ad Special row will remove all rows beneath it. Do you wish to continue?", @"Clear " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
@@ -514,12 +629,32 @@ namespace AdvertsingProfitControl
//Actual Sales table
actualSalesDataGridView.RowsRemoved -= ActualSalesRowRemoved;
actualSalesDataGridView.UserDeletingRow -= UpdateUsedAdItemCollectionOnRowRemoving;
//Now for-each through each row that is underneath the Ad Special row.
for (var rowIndex = dataGridView.RowCount; currentRowIndex != rowIndex; rowIndex--)
{
//If the ad item entered in the first cell is in the gUsedAdItems collection, then remove it from there.
_usedAdItems[1].Remove(dataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString());
if (projectionsDataGridView.RowCount == inventoryDataGridView.RowCount &&
projectionsDataGridView.RowCount == actualSalesDataGridView.RowCount)
{
if (dataGridView.Rows[currentRowIndex].Cells[(int) SalesTableColumns.Id].EditedFormattedValue.ToString() != "")
{
//Attempt to delete the row from the database by its ID number.
var projectionsRowId = int.Parse(projectionsDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
var inventoryRowId = int.Parse(inventoryDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
var actualSalesRowId = int.Parse(actualSalesDataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString());
if (dbWriter.DeleteApcRow(projectionsRowId, inventoryRowId, actualSalesRowId))
{
informationLabel.Text += @"Successfully removed row " + (currentRowIndex + 1) + @" from the database." + Environment.NewLine;
}
else
{
//If the removing failed cancel the row deletion in the DataGridView.
e.Cancel = true;
MessageBox.Show(@"Failed to delete " + dataGridView.Rows[currentRowIndex].Cells[1].EditedFormattedValue +
@" from the database.", @"Failed to Update Database");
return;
}
}
}
if (projectionsDataGridView.Rows[currentRowIndex].IsNewRow != true)
{
projectionsDataGridView.Rows.RemoveAt(currentRowIndex);
@@ -532,6 +667,8 @@ namespace AdvertsingProfitControl
{
actualSalesDataGridView.Rows.RemoveAt(currentRowIndex);
}
//If the ad item entered in the first cell is in the gUsedAdItems collection, then remove it from there.
_usedAdItems[1].Remove(dataGridView.Rows[currentRowIndex].Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString());
}
//Re-enable all row removal events on both tables.
//Projections table
@@ -668,16 +805,21 @@ namespace AdvertsingProfitControl
//If there is text after all the whitespace has been cleared, clear the error text property regardless of whether or not it is set.
if (!string.IsNullOrEmpty(Regex.Replace(userInput, @"\s+", "")))
{
var parser = new RowParsing();
if (parser.CheckForGroupKeyWord(userInput) != "NoGroupFound")
{
_adSpecialIndex = e.RowIndex;
}
//Clear the error text since there is in fact an item entered.
dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "";
//Send the ad item text through the formatting engine and assign the new value to the cell.
dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = TextFormat.FormatAdItemText(userInput);
dataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
var parser = new RowParsing();
if (parser.CheckForGroupKeyWord(userInput) == "NoGroupFound")
{
dataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
}
else
{
_adSpecialIndex = e.RowIndex;
//Since this is the ad special row don't give it any color coding.
dataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
}
//Force a refresh so the cell's text updates and displays for the user.
dataGridView.RefreshEdit();
return;
@@ -723,7 +865,7 @@ namespace AdvertsingProfitControl
//If the column is the "Sale Price" column try to parse the contents to a Double and apply number formatting to the contents.
//Check for the cost column to see if there are any strings formatted like such:
var regExpression = new Regex(@"^\d+( *)?/( *)?\${0,1}?\d+(\.\d+)?", RegexOptions.IgnoreCase); // [0-9]/($)?[0-9]
//IF the current cell is in the sale price column, check for the string format above, else move to the default method.
//IF the current cell is in the sale price column, check for the string format above, else move to the default method.
if (regExpression.IsMatch(dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString()))
{
//Grab the input and split it at the forward slash (/) for formatting.
@@ -923,8 +1065,16 @@ namespace AdvertsingProfitControl
}
inventoryDataGridView.Rows.Add(inventoryNewRow);
//Set the row headers of the other tables to show up as pending; this row is valid without a doubt.
inventoryDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
actualSalesDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
if (e.RowIndex != _adSpecialIndex)
{
inventoryDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
actualSalesDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
}
else
{
inventoryDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
actualSalesDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
}
}
private void ProjectionRowRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
@@ -1071,16 +1221,21 @@ namespace AdvertsingProfitControl
//If there is text after all the whitespace has been cleared, clear the error text property regardless of whether or not it is set.
if (!string.IsNullOrEmpty(Regex.Replace(userInput, @"\s+", "")))
{
var parser = new RowParsing();
if (parser.CheckForGroupKeyWord(userInput) != "NoGroupFound")
{
_adSpecialIndex = e.RowIndex;
}
//Clear the error text since there is in fact an item entered.
dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "";
//Send the ad item text through the formatting engine and assign the new value to the cell.
dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = TextFormat.FormatAdItemText(userInput);
dataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
var parser = new RowParsing();
if (parser.CheckForGroupKeyWord(userInput) == "NoGroupFound")
{
dataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
}
else
{
_adSpecialIndex = e.RowIndex;
//Since this is the ad special row don't give it any color coding.
dataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
}
//Force a refresh so the cell's text updates and displays for the user.
dataGridView.RefreshEdit();
return;
@@ -1205,9 +1360,18 @@ namespace AdvertsingProfitControl
}
projectionsDataGridView.Rows.Add(rowContents);
actualSalesDataGridView.Rows.Add(rowContents);
//Apply color coding to the respective row headers on the other tables.
projectionsDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
actualSalesDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
if (e.RowIndex != _adSpecialIndex)
{
//Apply color coding to the respective row headers on the other tables.
projectionsDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
actualSalesDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
}
else
{
//Apply color coding to the respective row headers on the other tables.
projectionsDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
actualSalesDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
}
}
private void InventoryRowRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
@@ -1386,9 +1550,19 @@ namespace AdvertsingProfitControl
}
}
inventoryDataGridView.Rows.Add(inventoryNewRow);
//Apply color coding to the respective row headers on the other tables.
projectionsDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
inventoryDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
if (e.RowIndex != _adSpecialIndex)
{
//Apply color coding to the respective row headers on the other tables.
projectionsDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
inventoryDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit;
}
else
{
//Apply color coding to the respective row headers on the other tables.
projectionsDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
inventoryDataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = DefaultBackColor;
}
}
private void ActualSalesRowRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
@@ -1618,7 +1792,6 @@ namespace AdvertsingProfitControl
/// <summary>
/// Allows the user to select all the text in the comments text box.
/// TODO: Fix error chime when using CNTRL+A.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
@@ -1627,6 +1800,8 @@ namespace AdvertsingProfitControl
if (!e.Control || e.KeyCode != Keys.A) return;
commentsTextBox.SelectionStart = 0;
commentsTextBox.SelectionLength = commentsTextBox.Text.Length;
e.Handled = true;
e.SuppressKeyPress = true;
}
/// <summary>
@@ -2834,7 +3009,6 @@ namespace AdvertsingProfitControl
#region Debug Operations
private void idButton_Click(object sender, EventArgs e)
{
if (isCommentDirtyCheckBox.Tag == null)
@@ -2894,7 +3068,14 @@ namespace AdvertsingProfitControl
MessageBox.Show(@"ID cleared from Cost Analysis.", @"Clear ID Debug");
}
}
private void debugMainMenu_Click(object sender, EventArgs e)
{
MessageBox.Show(TextFormat.CapitalizeFirstLetter(projectionsDataGridView.Name.Remove(projectionsDataGridView.Name.Length - 12)));
MessageBox.Show(TextFormat.CapitalizeFirstLetter(inventoryDataGridView.Name.Remove(inventoryDataGridView.Name.Length - 12)));
MessageBox.Show(TextFormat.CapitalizeFirstLetter(actualSalesDataGridView.Name.Remove(actualSalesDataGridView.Name.Length - 12)));
}
#endregion
}
}