diff --git a/AdvertsingProfitControl/AdvertisingProfitControlTableHelper.cs b/AdvertsingProfitControl/AdvertisingProfitControlTableHelper.cs index a4d259e..f434fee 100644 --- a/AdvertsingProfitControl/AdvertisingProfitControlTableHelper.cs +++ b/AdvertsingProfitControl/AdvertisingProfitControlTableHelper.cs @@ -19,15 +19,18 @@ namespace AdvertsingProfitControl var parser = new RowParsing(); int isHeaderColumn; int isMemberColumn; + int isDirtyColumn; if (dataGridView.Columns.Count == Enum.GetNames(typeof(SalesTableColumns)).Length) { isHeaderColumn = (int) SalesTableColumns.IsHeaderRow; isMemberColumn = (int) SalesTableColumns.IsMemberRow; + isDirtyColumn = (int) SalesTableColumns.IsDirty; } else { isHeaderColumn = (int)InventoryTableColumns.IsHeaderRow; isMemberColumn = (int)InventoryTableColumns.IsMemberRow; + isDirtyColumn = (int) InventoryTableColumns.IsDirty; } //If the current row is an Ad Special Row, the color code it and return as nothing further needs to be done. if (parser.CheckForGroupKeyWord(dataGridView.Rows[startingIndex].Cells[(int) SalesTableColumns.AdItem].EditedFormattedValue.ToString()) != "NoGroupFound") @@ -46,19 +49,35 @@ namespace AdvertsingProfitControl //Then check to see if the next row is a row header. rowStatus = parser.GetRowAttribute(dataGridView.Rows[i + 1]); //IF so, color code this row as White, since it is not a true group header. - if (rowStatus != RowAttribute.HeaderRow) + if (rowStatus == RowAttribute.HeaderRow) { //Clear the current row of its attributes. dataGridView.Rows[i].Cells[isHeaderColumn].Value = false; dataGridView.Rows[i].Cells[isMemberColumn].Value = false; - dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White; + return; } //IF the current row is not the first row in the data grid (index zero)... if (i > 0) { //The start by checking the previous row's status. rowStatus = parser.GetRowAttribute(dataGridView.Rows[i - 1]); + //IF the previous row is a header row AND has color coding saying it is a group header, then clear the previous row's color and apply it to this row (i). + if (rowStatus == RowAttribute.HeaderRow && (bool)dataGridView.Rows[i - 1].Cells[isHeaderColumn].Value) + { + //Clear the previous row of its attributes. + dataGridView.Rows[i - 1].Cells[isHeaderColumn].Value = false; + dataGridView.Rows[i - 1].Cells[isMemberColumn].Value = false; + //This condition means the user changed the members of a group, so the old header row needs to be updated in the database. + dataGridView.Rows[i - 1].Cells[isDirtyColumn].Value = true; + dataGridView.Rows[i - 1].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit; + dataGridView.Rows[i - 1].DefaultCellStyle.BackColor = Color.White; + //Set the current row as a header row. + dataGridView.Rows[i].Cells[isHeaderColumn].Value = true; + dataGridView.Rows[i].Cells[isMemberColumn].Value = false; + dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray; + return; + } //IF the previous row is a header row OR if the previous row is index zero AND a member row, clear its coloring. if (rowStatus == RowAttribute.HeaderRow || rowStatus == RowAttribute.MemberRow && (i - 1) == 0) { @@ -67,18 +86,6 @@ namespace AdvertsingProfitControl dataGridView.Rows[i - 1].Cells[isMemberColumn].Value = false; dataGridView.Rows[i - 1].DefaultCellStyle.BackColor = Color.White; } - //IF the previous row is a header row AND has color coding saying it is a group header, then clear the previous row's color and apply it to this row (i). - else if (rowStatus == RowAttribute.HeaderRow && (bool)dataGridView.Rows[i - 1].Cells[isHeaderColumn].Value) - { - //Clear the previous row of its attributes. - dataGridView.Rows[i - 1].Cells[isHeaderColumn].Value = false; - dataGridView.Rows[i - 1].Cells[isMemberColumn].Value = false; - dataGridView.Rows[i - 1].DefaultCellStyle.BackColor = Color.White; - //Set the current row as a header row. - dataGridView.Rows[i].Cells[isHeaderColumn].Value = true; - dataGridView.Rows[i].Cells[isMemberColumn].Value = false; - dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray; - } //IF previous row is Incomplete, then call the stable PaintRowGroups function. else if (rowStatus == RowAttribute.IncompleteRow) { @@ -108,7 +115,7 @@ namespace AdvertsingProfitControl { //Check the previous row. rowStatus = parser.GetRowAttribute(dataGridView.Rows[i - 1]); - //IF the previous row is a member row AND is the first row in the data grid, then remove the coloring for it and the current row (i). + //IF the previous row is a member row AND is the first row in the data grid, then remove the coloring from it and the current row (i). if (rowStatus == RowAttribute.MemberRow && (i - 1) == 0) { //Clear the previous row of its attributes. @@ -119,9 +126,10 @@ namespace AdvertsingProfitControl dataGridView.Rows[i].Cells[isHeaderColumn].Value = false; dataGridView.Rows[i].Cells[isMemberColumn].Value = false; dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White; + return; } //IF the previous row is a member row AND it also has color coding suggesting that it is a member of a group, then add the current row (i) as well. - else if (rowStatus == RowAttribute.MemberRow && (bool)dataGridView.Rows[i - 1].Cells[isMemberColumn].Value) + if (rowStatus == RowAttribute.MemberRow && (bool)dataGridView.Rows[i - 1].Cells[isMemberColumn].Value) { //Set the current row as a member row. dataGridView.Rows[i].Cells[isHeaderColumn].Value = false; @@ -135,6 +143,7 @@ namespace AdvertsingProfitControl dataGridView.Rows[i].Cells[isHeaderColumn].Value = false; dataGridView.Rows[i].Cells[isMemberColumn].Value = false; dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White; + return; } //IF the previous row is a header row, then color it as a group header and color the current row as a member of said group. else if (rowStatus == RowAttribute.HeaderRow) @@ -143,6 +152,9 @@ namespace AdvertsingProfitControl dataGridView.Rows[i - 1].Cells[isHeaderColumn].Value = true; dataGridView.Rows[i - 1].Cells[isMemberColumn].Value = false; dataGridView.Rows[i - 1].DefaultCellStyle.BackColor = Color.LightGray; + //This condition means the user created a group so the newly made header row will need to be updated in the database as well. + dataGridView.Rows[i - 1].Cells[isDirtyColumn].Value = true; + dataGridView.Rows[i - 1].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit; //Set the current row as a member row. dataGridView.Rows[i].Cells[isHeaderColumn].Value = false; dataGridView.Rows[i].Cells[isMemberColumn].Value = true; diff --git a/AdvertsingProfitControl/AdvertsingProfitControl.csproj b/AdvertsingProfitControl/AdvertsingProfitControl.csproj index 92a6ce2..a01a4af 100644 --- a/AdvertsingProfitControl/AdvertsingProfitControl.csproj +++ b/AdvertsingProfitControl/AdvertsingProfitControl.csproj @@ -106,7 +106,6 @@ - diff --git a/AdvertsingProfitControl/ApcTableStatus.cs b/AdvertsingProfitControl/ApcTableStatus.cs deleted file mode 100644 index 9667c2e..0000000 --- a/AdvertsingProfitControl/ApcTableStatus.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace AdvertsingProfitControl -{ - internal class ApcTableStatus - { - private DbTableWriterStatus _projectionsTableStatus = new DbTableWriterStatus(); - private DbTableWriterStatus _inventoryTableStatus = new DbTableWriterStatus(); - private DbTableWriterStatus _actualSalesStatus = new DbTableWriterStatus(); - - public void SetProjectionsTableStatus(DbTableWriterStatus status) - { - _projectionsTableStatus = status; - } - - public DbTableWriterStatus GetProjectionsStatus() - { - return _projectionsTableStatus; - } - - public void SetInventoryStatus(DbTableWriterStatus status) - { - _inventoryTableStatus = status; - } - - public DbTableWriterStatus GetInventoryStatus() - { - return _inventoryTableStatus; - } - - public void SetActualSalesStatus(DbTableWriterStatus status) - { - _actualSalesStatus = status; - } - - public DbTableWriterStatus GetActualSalesStatus() - { - return _actualSalesStatus; - } - } -} diff --git a/AdvertsingProfitControl/DbTableWriterStatus.cs b/AdvertsingProfitControl/DbTableWriterStatus.cs index a7f53f2..214801c 100644 --- a/AdvertsingProfitControl/DbTableWriterStatus.cs +++ b/AdvertsingProfitControl/DbTableWriterStatus.cs @@ -44,7 +44,9 @@ namespace AdvertsingProfitControl { _rowIds.Remove(key); } - + /// + /// Clears the collection of row IDs. + /// public void ClearRowCollection() { _rowIds.Clear(); @@ -72,7 +74,7 @@ namespace AdvertsingProfitControl /// Gets any error message set by the Insertion/Update operation function. /// If none are set returns an empty string. /// - /// The error message. + /// The error message, string.Empty if no message is set. public string GetErrorMessage() { //If the error message is null then return string.Empty. diff --git a/AdvertsingProfitControl/DbWriterStatus.cs b/AdvertsingProfitControl/DbWriterStatus.cs index 0b637d0..72bc5be 100644 --- a/AdvertsingProfitControl/DbWriterStatus.cs +++ b/AdvertsingProfitControl/DbWriterStatus.cs @@ -9,6 +9,7 @@ namespace AdvertsingProfitControl internal class DbWriterStatus { public string ErrorMessage; + public string Message; public int Id; public WritingOperationStatus Status; } diff --git a/AdvertsingProfitControl/NewAddRecord.cs b/AdvertsingProfitControl/NewAddRecord.cs index f69a127..ed05896 100644 --- a/AdvertsingProfitControl/NewAddRecord.cs +++ b/AdvertsingProfitControl/NewAddRecord.cs @@ -1174,7 +1174,7 @@ namespace AdvertsingProfitControl { //Grab the DataGirdView that fired the event and make it into a local variable. var dataGridView = ((DataGridView)sender); - var userInput = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString(); + var userInput = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString().Trim(); //TODO: Write a custom parsing engine for detecting when bins are entered. var textInfo = new CultureInfo("en-US", false).TextInfo; //Check for isNewRow if it is, return no need to check it for anything. @@ -1246,6 +1246,7 @@ namespace AdvertsingProfitControl else if (userInput != _beginningCellValue) { dataGridView.Rows[e.RowIndex].Cells[(int)InventoryTableColumns.IsDirty].Value = true; + dataGridView.Rows[e.RowIndex].HeaderCell.Style.BackColor = ApplicationColors.PendingEdit; } //Check to see if the current column is the ad item column. switch (e.ColumnIndex) @@ -1278,7 +1279,12 @@ namespace AdvertsingProfitControl break; default: //Purely here for protection against parsing the Boolean columns by mistake. - if (e.ColumnIndex == (int)InventoryTableColumns.Id || e.ColumnIndex >= (int)InventoryTableColumns.IsHeaderRow) { return; } + if (e.ColumnIndex == (int)InventoryTableColumns.Id || e.ColumnIndex >= (int)InventoryTableColumns.IsHeaderRow) return; + if (userInput == string.Empty) + { + dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = userInput; + return; + } //This Reg-ex pattern will match any number followed by the word bin(s), to allow specifying the number of bins of product were ordered. var inventoryStringCheck = new Regex(@"^[0-9]{1,2} \bbin(s){0,1}\b", RegexOptions.IgnoreCase); @@ -1294,7 +1300,7 @@ namespace AdvertsingProfitControl } double parsedNumber; //Try parsing the text entered as a number and if that fails then break out and clear the value entered. - if (userInput != "" && double.TryParse(userInput, out parsedNumber)) + if (userInput != string.Empty && double.TryParse(userInput, out parsedNumber)) { //Add the value to the cell. dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = userInput; @@ -1302,7 +1308,7 @@ namespace AdvertsingProfitControl return; } //Prevent the user from being bombarded by message boxes. All validation has been completed at this point so there's nothing to worry about. - if (userInput != "") + if (userInput != string.Empty) { MessageBox.Show(@"Non numeric characters in column " + (e.ColumnIndex + 1) + @" are not allowed.", @"Invalid Characters Detected"); dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = ""; @@ -2107,14 +2113,6 @@ namespace AdvertsingProfitControl if (dbW.InsertIntoWeekEnding(weekEndingCalendar.SelectionStart.ToString("d"))) { dateId = dbR.RetrieveDateIdByDateString(weekEndingCalendar.SelectionStart.ToString("d"), dbT.DatabaseConnectionString); - //Now if its still zero (0) then that means something went really wrong and failed to insert. - if (dateId == 0) - { - MessageBox.Show( - @"Failed to retrieve date ID after supposedly inserting the date into the database.", - @"Failed To Get Date ID", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } } else { @@ -2465,76 +2463,6 @@ namespace AdvertsingProfitControl return TrimmingOperationResult.FailedToTrim; } } - //Check for repeated ad items in the ad special section - if (_adSpecialIndex != -1 && row.Index > _adSpecialIndex) - { - //Attempt to grab the index of an ad item, if it is not found then the return value is -1. - var repeatedItemIndex = _usedAdItems[0].FindIndex(x => x == row.Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString()); - //Skip checking this row if an index is found, and use the values in the row at the previous index found. - if (repeatedItemIndex != -1) - { - //Add the values to their respective data table. - if (rowIdNumber == 0) - { - //This table is full of data not in the database so the ID column isn't needed. - var newRow = new object[11]; - newRow[0] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.Sold].EditedFormattedValue.ToString();//Sold, is string - newRow[1] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.SalePrice].EditedFormattedValue.ToString();//SalePrice, is string - newRow[2] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString());//TotalSales, must be a number - newRow[3] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString());//Cost, must be a number - newRow[4] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString());//ProfitReturn, must be a number - newRow[5] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString());//TotalProfitReturn, must be a number - newRow[6] = adItemId; - if ((bool)dataGridView.Rows[repeatedItemIndex].Cells[(int) SalesTableColumns.IsHeaderRow].Value) - { - newRow[7] = 1; - } - else if ((bool)dataGridView.Rows[repeatedItemIndex].Cells[(int) SalesTableColumns.IsMemberRow].Value) - { - newRow[7] = 2; - } - else - { - newRow[7] = 0; - } - newRow[8] = adSpecialId; - newRow[9] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. - newRow[10] = dateId; - insertNewTable.Rows.Add(newRow); - continue; - } - else - { - //This table is full of data that is already in the database. - var newRow = new object[11]; - newRow[0] = rowIdNumber; - newRow[1] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.Sold].EditedFormattedValue.ToString();//Sold, is string - newRow[2] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.SalePrice].EditedFormattedValue.ToString();//SalePrice, is string - newRow[3] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString());//TotalSales, must be a number - newRow[4] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString());//Cost, must be a number - newRow[5] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString());//ProfitReturn, must be a number - newRow[6] = dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString());//TotalProfitReturn, must be a number - newRow[7] = adItemId; - if ((bool)dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.IsHeaderRow].Value) - { - newRow[8] = 1; - } - else if ((bool)dataGridView.Rows[repeatedItemIndex].Cells[(int)SalesTableColumns.IsMemberRow].Value) - { - newRow[8] = 2; - } - else - { - newRow[8] = 0; - } - newRow[9] = adSpecialId; - newRow[10] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. - newRow[11] = dateId; - insertNewTable.Rows.Add(newRow); - continue; - } - } - } //Determine the row's attribute. var rowAttribute = 0; //Zero (0) means no grouping, its not a header nor a member. if ((bool)row.Cells[(int)SalesTableColumns.IsHeaderRow].Value && !(bool)row.Cells[(int)SalesTableColumns.IsMemberRow].Value) @@ -2597,13 +2525,6 @@ namespace AdvertsingProfitControl newRow[11] = dateId; updateExistingTable.Rows.Add(newRow); } - //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "Row Dump for row number " + (row.Index + 1) + "."); - //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "ID : " + rowIdNumber + " Sold: " + row.Cells[(int)SalesTableColumns.Sold].EditedFormattedValue); - //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "Sale Price : " + row.Cells[(int)SalesTableColumns.SalePrice].EditedFormattedValue + " Total Sales: " + row.Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue); - //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "Cost: " + row.Cells[(int)SalesTableColumns.Cost].EditedFormattedValue + " Profit Return: " + row.Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue); - //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "Total Profit Return: " + row.Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue + " Ad Item ID: " + adItemId); - //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "Row Attribute: " + rowAttribute + " Ad Special ID: " + adSpecialId); - //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "Row Position: " + row.Index + (_adSpecialIndex != -1 && row.Index > _adSpecialIndex ? 1 : 0) + " Date ID: " + dateId); } if (insertNewTable.Rows.Count == 0 && updateExistingTable.Rows.Count == 0) @@ -2698,76 +2619,6 @@ namespace AdvertsingProfitControl return TrimmingOperationResult.FailedToTrim; } } - //Check for repeated ad items in the ad special section - if (_adSpecialIndex != -1 && row.Index > _adSpecialIndex) - { - //Attempt to grab the index of an ad item, if it is not found then the return value is -1. - var repeatedItemIndex = - _usedAdItems[0].FindIndex(x => x == row.Cells[(int)InventoryTableColumns.AdItem].EditedFormattedValue.ToString()); - //Skip checking this row if an index is found, and use the values in the row at the previous index found. - if (repeatedItemIndex != -1) - { - //Add the values to their respective data table. - if (rowIdNumber == 0) - { - //This table is full of data not in the database so the ID column isn't needed. - //0:Beginning Inventory 1:Received 2:Total Inventory 3:Ending Inventory - //4:AdItemID 5:RowAttribute 6:GroupID 7:RowPosition 8:DateID - var newRow = new object[9]; - newRow[0] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.BeginningInventory].EditedFormattedValue.ToString();//Sold, is string - newRow[1] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.Recieved].EditedFormattedValue.ToString();//SalePrice, is string - newRow[2] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int) InventoryTableColumns.Total].EditedFormattedValue.ToString(); //Total Inventory is string - newRow[3] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.EndingInventory].EditedFormattedValue.ToString();//Ending Inventory, is string - newRow[4] = adItemId; - if ((bool)inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.IsHeaderRow].Value) - { - newRow[5] = 1; - } - else if ((bool)inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.IsMemberRow].Value) - { - newRow[5] = 2; - } - else - { - newRow[5] = 0; - } - newRow[6] = adSpecialId; - newRow[7] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. - newRow[8] = dateId; - insertNewTable.Rows.Add(newRow); - continue; - } - else - { - //This table is full of data that is already in the database. - //0:ID 1:BeginningInventory 2:Received 3:TotalInventory 4:EndingInventory - //5:AdItemID 6:RowAttribute 7:GroupID 8:RowPosition 9:DateID - var newRow = new object[10]; - newRow[0] = rowIdNumber; - newRow[1] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.BeginningInventory].EditedFormattedValue.ToString();//Sold, is string - newRow[2] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.Recieved].EditedFormattedValue.ToString();//SalePrice, is string - newRow[3] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.Total].EditedFormattedValue.ToString(); //Total Inventory is string - newRow[4] = inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.EndingInventory].EditedFormattedValue.ToString();//Ending Inventory, is string - newRow[5] = adItemId; - if ((bool)inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.IsHeaderRow].Value) - { - newRow[6] = 1; - } - else if ((bool)inventoryDataGridView.Rows[repeatedItemIndex].Cells[(int)InventoryTableColumns.IsMemberRow].Value) - { - newRow[6] = 2; - } - else - { - newRow[6] = 0; - } - newRow[7] = adSpecialId; - newRow[8] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. - newRow[9] = dateId; - continue; - } - } - } //Determine the row's attribute. var rowAttribute = 0; //Zero (0) means no grouping, its not a header nor a member. if ((bool)row.Cells[(int)InventoryTableColumns.IsHeaderRow].Value && !(bool)row.Cells[(int)InventoryTableColumns.IsMemberRow].Value) diff --git a/AdvertsingProfitControl/NewModifyRecord.Designer.cs b/AdvertsingProfitControl/NewModifyRecord.Designer.cs index 08b9511..4c87e43 100644 --- a/AdvertsingProfitControl/NewModifyRecord.Designer.cs +++ b/AdvertsingProfitControl/NewModifyRecord.Designer.cs @@ -942,6 +942,7 @@ this.addRecordButton.TabIndex = 26; this.addRecordButton.Text = "Update Record"; this.addRecordButton.UseVisualStyleBackColor = true; + this.addRecordButton.Click += new System.EventHandler(this.addRecordButton_Click); // // NewModifyRecord // diff --git a/AdvertsingProfitControl/NewModifyRecord.cs b/AdvertsingProfitControl/NewModifyRecord.cs index 3af6f9f..e96ab76 100644 --- a/AdvertsingProfitControl/NewModifyRecord.cs +++ b/AdvertsingProfitControl/NewModifyRecord.cs @@ -878,7 +878,7 @@ namespace AdvertsingProfitControl return; } //Otherwise, show an error. - dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Ad Item needed"; + dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "This column can't be blank!"; break; case (int)SalesTableColumns.Sold: //Sold //This Reg-ex pattern will match any number followed by the word bin(s), to allow specifying the number of bins of product were ordered. @@ -1329,11 +1329,16 @@ namespace AdvertsingProfitControl return; } //If column one (1) is blank then cancel cell validating. - dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Ad Item needed"; + dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "This column can't be blank!"; break; default: //Purely here for protection against parsing the Boolean columns by mistake. if (e.ColumnIndex == (int)InventoryTableColumns.Id || e.ColumnIndex >= (int)InventoryTableColumns.IsHeaderRow) { return; } + if (userInput == string.Empty) + { + dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = userInput; + return; + } //This Reg-ex pattern will match any number followed by the word bin(s), to allow specifying the number of bins of product were ordered. var inventoryStringCheck = new Regex(@"^[0-9]{1,2} \bbin(s){0,1}\b", RegexOptions.IgnoreCase); @@ -2525,6 +2530,12 @@ namespace AdvertsingProfitControl } } } + //Set the is dirty cell to false. + var isDirtyCell = new DataGridViewCheckBoxCell + { + Value = false + }; + newRow.Cells.Add(isDirtyCell); projectionsDataGridView.Rows.Add(newRow); } //Manually write the row number to the new row. @@ -2619,7 +2630,13 @@ namespace AdvertsingProfitControl } } } - inventoryDataGridView.Rows.Add(newRow); + //Set the is dirty cell to false. + var isDirtyCell = new DataGridViewCheckBoxCell + { + Value = false + }; + newRow.Cells.Add(isDirtyCell); + inventoryDataGridView.Rows.Add(newRow); } //Manually write the row number to the new row. inventoryDataGridView.Rows[inventoryDataGridView.Rows.Count - 1].HeaderCell.Value = inventoryDataGridView.Rows.Count.ToString(); @@ -2713,6 +2730,12 @@ namespace AdvertsingProfitControl } } } + //Set the is dirty cell to false. + var isDirtyCell = new DataGridViewCheckBoxCell + { + Value = false + }; + newRow.Cells.Add(isDirtyCell); actualSalesDataGridView.Rows.Add(newRow); } //Manually write the row number to the new row. @@ -2755,6 +2778,12 @@ namespace AdvertsingProfitControl cell.Value = invoices.Rows[rowIndex].ItemArray[cellIndex].ToString(); row.Cells.Add(cell); } + //Set the is dirty cell to false. + var isDirtyCell = new DataGridViewCheckBoxCell + { + Value = false + }; + row.Cells.Add(isDirtyCell); invoicesDataGridView.Rows.Add(row); } } @@ -3067,12 +3096,69 @@ namespace AdvertsingProfitControl #region Database Update/Insertion Methods - private bool SaveRecords() + /// + /// Saves all changes made to the form to the database. + /// + /// Whether or not to update the information label with the status. + /// True on success otherwise, false. + private bool SaveRecords(bool displayInformation = true) { var success = false; //Get the date ID for the current active date. - - + var dateId = GetDateId(_currentActiveDate.ToString("d")); + if (dateId == 0) + { + MessageBox.Show(@"Failed to get the date ID number.", @"Invalid ID Number", MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + //Create the database interaction objects. + var dbT = new DatabaseTracker(); + var dbW = new DatabaseWriter(dbT.DatabaseConnectionString); + DataTable newInsertProjectionsTable; + DataTable updateProjectionsTable; + var projectionsTrimmingStatus = ConstructCleanedSalesTable("Projections", dateId, out newInsertProjectionsTable, out updateProjectionsTable); + if (projectionsTrimmingStatus != TrimmingOperationResult.NoChangesRequired && projectionsTrimmingStatus != TrimmingOperationResult.FailedToTrim) + { + //Check to see if the insert table has any items. + if (newInsertProjectionsTable.Rows.Count > 0) + { + var writerResult = dbW.InsertIntoSalesTable(newInsertProjectionsTable, dbT.DatabaseConnectionString); + if (writerResult.GetWritingOperationStatus() != WritingOperationStatus.Failed) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in writerResult.GetRowCollection()) + { + projectionsDataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.Id].Value = rowIndex.Value; + projectionsDataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.IsDirty].Value = false; + projectionsDataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + } + } + //Next check to see if the update table has anything. + if (updateProjectionsTable.Rows.Count > 0) + { + var writerResult = dbW.UpdateSalesTable(updateProjectionsTable, dbT.DatabaseConnectionString); + if (writerResult.GetWritingOperationStatus() != WritingOperationStatus.Failed) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in writerResult.GetRowCollection()) + { + //Only reset the IsDirty value to false since the updates when through. + projectionsDataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.IsDirty].Value = false; + projectionsDataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + } + } + if (displayInformation) informationLabel.Text += @"Successfully saved projections." + Environment.NewLine; + } + else if (projectionsTrimmingStatus == TrimmingOperationResult.NoChangesRequired) + { + if (displayInformation) informationLabel.Text += @"No changes to projections detected." + Environment.NewLine; + } + else + { + errorLabel.Text += @"Failed to process projections." + Environment.NewLine; + } return success; } @@ -3087,29 +3173,528 @@ namespace AdvertsingProfitControl var dbT = new DatabaseTracker(); var dbW = new DatabaseWriter(dbT.DatabaseConnectionString); var dbR = new DatabaseReader(); - var dateId = dbR.RetrieveDateIdByDateString(weekEndingCalendar.SelectionStart.ToString("d"), dbT.DatabaseConnectionString); + var dateId = dbR.RetrieveDateIdByDateString(date, dbT.DatabaseConnectionString); //If the ID is zero (0) that means the date isn't in the database so simply insert it. - if (dateId == 0) + if (dateId != 0) return dateId; + //Try inserting the date string. + if (dbW.InsertIntoWeekEnding(date)) { - //Try inserting the date string. - if (dbW.InsertIntoWeekEnding(weekEndingCalendar.SelectionStart.ToString("d"))) + dateId = dbR.RetrieveDateIdByDateString(date, dbT.DatabaseConnectionString); + } + else + { + //The above method reports that it failed to insert the date into the database. + errorLabel.Text = @"Failed to insert the date '" + date + @"' into the database."; + } + return dateId; + } + + #endregion + + #region Table Trimming Operations + + private TrimmingOperationResult ConstructCleanedSalesTable(string tableName, int dateId, out DataTable newInsertTable, out DataTable updateTable) + { + //Create two DataTables one for the new items to be added to the database + //and one for items that have to be updated. + //New Sales Table Layout (Based on the Database's Physical Layout) + //0:Sold 1:SalePrice 2:TotalSales 3:cost 4:ProfitReturn 5:TotalProfitReturn + //6:FK_AdItemID 7:RowAttribute 8:FK_AdSpecialGroupName (ID) 9:RowPosition (not index based) + //10:FK_DateID + newInsertTable = new DataTable(tableName); + //Update Sales Table Layout (Based on the Database's Physical Layout) + //0:ID 1:Sold 2:SalePrice 3:TotalSales 4:cost 5:ProfitReturn 6:TotalProfitReturn + //7:FK_AdItemID 8:RowAttribute 9:FK_AdSpecialGroupName (ID) 10:RowPosition (not index based) + //11:FK_DateID + updateTable = new DataTable(tableName); + //Create a reference to the DataGridView that will be used (either Projections or Actual Sales). + var dataGridView = tableName == "Projections" ? projectionsDataGridView : actualSalesDataGridView; + //Construct a list of column names for the projections/actual sales DataGridViews and the inventory DataGirdView. + string[] saleColumnNames = + { + "ID", "Sold", "SalePrice", "TotalSales", "Cost", "ProfitReturn", + "TotalProfitReturn", "AdItemID", "RowAttribute", "AdSpecialID", "RowPosition", "DateID" + }; + foreach (var columnName in saleColumnNames) + { + if (columnName == "ID") continue; + var column = new DataColumn(columnName); + newInsertTable.Columns.Add(column); + } + foreach (var columnName in saleColumnNames) + { + var column = new DataColumn(columnName); + updateTable.Columns.Add(column); + } + //Create the database interaction objects. + var databaseTracker = new DatabaseTracker(); + var databaseReader = new DatabaseReader(); + var databaseWriter = new DatabaseWriter(databaseTracker.DatabaseConnectionString); + var adSpecialId = 0; //Entries in the database are not allowed to be zero (unique ID wise that is). + //Grab the ad special ID, assuming there is one. + if (_adSpecialIndex != -1) + { + //An ad special does exist so grab its ID from the database. + int.TryParse(databaseReader.RetrieveGroupIdByString( + dataGridView.Rows[_adSpecialIndex].Cells[(int)SalesTableColumns.AdItem] + .EditedFormattedValue.ToString(), databaseTracker.DatabaseConnectionString), out adSpecialId); + } + //Begin spinning through all the rows in the projections table. + foreach (DataGridViewRow row in dataGridView.Rows) + { + //Always check for new row. + if (row.IsNewRow) break; + //Check to see if the current row is the ad special row. + if (row.Index == _adSpecialIndex) { - dateId = dbR.RetrieveDateIdByDateString(weekEndingCalendar.SelectionStart.ToString("d"), dbT.DatabaseConnectionString); - //Now if its still zero (0) then that means something went really wrong and failed to insert. - if (dateId == 0) + continue; + } + //Check to see if the row is dirty. + if (!(bool)row.Cells[(int)SalesTableColumns.IsDirty].Value) + { + //If it is not then continue on to the next row. + continue; + } + //Try grabbing the row's ID number (the number that it is in the database). + var rowIdNumber = row.Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString() == "" ? 0 : int.Parse(row.Cells[(int)SalesTableColumns.Id].EditedFormattedValue.ToString()); + //Grab the ad item ID. + var adItemId = int.Parse(databaseReader.RetrieveAdItemId(row.Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString(), databaseTracker.DatabaseConnectionString)); + //If the return value is zero (0) then the ad item is not in the database so try to add it. + if (adItemId == 0) + { + //Add the item to the database. + adItemId = databaseWriter.InsertNewAdItem(row.Cells[(int)SalesTableColumns.AdItem].EditedFormattedValue.ToString()); + if (adItemId == 0) { - MessageBox.Show( - @"Failed to retrieve date ID after supposedly inserting the date into the database.", - @"Failed To Get Date ID", MessageBoxButtons.OK, MessageBoxIcon.Error); + //TODO: Throw an exception, this can not be allowed. + //AdItemInsertionFailedException + newInsertTable.Rows.Clear(); //Work around for now + updateTable.Rows.Clear(); + errorLabel.Text = @"Failed to ad item to database."; + return TrimmingOperationResult.FailedToTrim; } } + //Determine the row's attribute. + var rowAttribute = 0; //Zero (0) means no grouping, its not a header nor a member. + if ((bool)row.Cells[(int)SalesTableColumns.IsHeaderRow].Value && !(bool)row.Cells[(int)SalesTableColumns.IsMemberRow].Value) + { + rowAttribute = 1; + } + else if ((bool)row.Cells[(int)SalesTableColumns.IsMemberRow].Value && !(bool)row.Cells[(int)SalesTableColumns.IsHeaderRow].Value) + { + rowAttribute = 2; + } + //Add the values to their respective data table. + if (rowIdNumber == 0) + { + //This table is full of data not in the database so the ID column isn't needed. + var newRow = new object[11]; + newRow[0] = row.Cells[(int)SalesTableColumns.Sold].EditedFormattedValue.ToString();//Sold, is string + newRow[1] = row.Cells[(int)SalesTableColumns.SalePrice].EditedFormattedValue.ToString();//SalePrice, is string + newRow[2] = row.Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString());//TotalSales, must be a number + newRow[3] = row.Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString());//Cost, must be a number + newRow[4] = row.Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString());//ProfitReturn, must be a number + newRow[5] = row.Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString());//TotalProfitReturn, must be a number + newRow[6] = adItemId; + newRow[7] = rowAttribute; + if (_adSpecialIndex != -1 && row.Index > _adSpecialIndex) + { + newRow[8] = adSpecialId; + newRow[9] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. + } + else + { + newRow[8] = 0; + newRow[9] = row.Index + 1; + } + newRow[10] = dateId; + newInsertTable.Rows.Add(newRow); + } else { - //The above method reports that it failed to insert the date into the database. - MessageBox.Show(@"Failed to insert the date '" + weekEndingCalendar.SelectionStart.ToString("d") + @"' into the database.", @"Failed To Get Date ID", MessageBoxButtons.OK, MessageBoxIcon.Error); + //This table is full of data that is already in the database. + var newRow = new object[12]; + newRow[0] = rowIdNumber; + newRow[1] = row.Cells[(int)SalesTableColumns.Sold].EditedFormattedValue.ToString();//Sold, is string + newRow[2] = row.Cells[(int)SalesTableColumns.SalePrice].EditedFormattedValue.ToString();//SalePrice, is string + newRow[3] = row.Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.TotalSales].EditedFormattedValue.ToString());//TotalSales, must be a number + newRow[4] = row.Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.Cost].EditedFormattedValue.ToString());//Cost, must be a number + newRow[5] = row.Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.ProfitReturn].EditedFormattedValue.ToString());//ProfitReturn, must be a number + newRow[6] = row.Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString() == "" ? 0 : double.Parse(row.Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue.ToString());//TotalProfitReturn, must be a number + newRow[7] = adItemId; + newRow[8] = rowAttribute; + if (_adSpecialIndex != -1 && row.Index > _adSpecialIndex) + { + newRow[9] = adSpecialId; + newRow[10] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. + } + else + { + newRow[9] = 0; + newRow[10] = row.Index + 1; + } + newRow[11] = dateId; + updateTable.Rows.Add(newRow); } } - return dateId; + + if (newInsertTable.Rows.Count == 0 && updateTable.Rows.Count == 0) + { + return TrimmingOperationResult.NoChangesRequired; + } + if (newInsertTable.Rows.Count > 0 && updateTable.Rows.Count == 0) + { + return TrimmingOperationResult.CreatedNewInsertionTable; + } + if (newInsertTable.Rows.Count == 0 && updateTable.Rows.Count > 0) + { + return TrimmingOperationResult.CreatedUpdateTable; + } + return TrimmingOperationResult.CreatedNewInsertionAndUpdateTables; + } + + private TrimmingOperationResult ConstructCleanedInventoryTable(int dateId, out DataTable newInsertTable, out DataTable updateTable) + { + //Create two DataTables one for the new items to be added to the database + //and one for items that have to be updated. + //New inventory Table Layout (Based on the Database's Physical Layout) + //0:Beginning Inventory 1:Received 2:Total Inventory 3:Ending Inventory + //4:AdItemID 5:RowAttribute 6:GroupID 7:RowPosition 8:DateID + newInsertTable = new DataTable("Inventory"); + //Update Sales Table Layout (Based on the Database's Physical Layout) + //0:ID 1:BeginningInventory 2:Received 3:TotalInventory 4:EndingInventory + //5:AdItemID 6:RowAttribute 7:GroupID 8:RowPosition 9:DateID + updateTable = new DataTable("Inventory"); + //Construct a list of column names for the projections/actual sales DataGridViews and the inventory DataGirdView. + string[] saleColumnNames = + { + "ID", "Sold", "SalePrice", "TotalSales", "Cost", "ProfitReturn", + "TotalProfitReturn", "AdItemID", "RowAttribute", "AdSpecialID", "RowPosition", "DateID" + }; + foreach (var columnName in saleColumnNames) + { + if (columnName == "ID") continue; + var column = new DataColumn(columnName); + newInsertTable.Columns.Add(column); + } + foreach (var columnName in saleColumnNames) + { + var column = new DataColumn(columnName); + updateTable.Columns.Add(column); + } + //Create the database interaction objects. + var databaseTracker = new DatabaseTracker(); + var databaseReader = new DatabaseReader(); + var databaseWriter = new DatabaseWriter(databaseTracker.DatabaseConnectionString); + var adSpecialId = 0; //Entries in the database are not allowed to be zero (unique ID wise that is). + //Grab the ad special ID, assuming there is one. + if (_adSpecialIndex != -1) + { + //An ad special does exist so grab its ID from the database. + int.TryParse(databaseReader.RetrieveGroupIdByString( + inventoryDataGridView.Rows[_adSpecialIndex].Cells[(int)InventoryTableColumns.AdItem] + .EditedFormattedValue.ToString(), databaseTracker.DatabaseConnectionString), out adSpecialId); + } + //Begin spinning through all the rows in the projections table. + foreach (DataGridViewRow row in inventoryDataGridView.Rows) + { + //Always check for new row. + if (row.IsNewRow) break; + //Check to see if the current row is the ad special row. + if (row.Index == _adSpecialIndex) + { + //LogConsole.WriteToLog(FrmLogConsole.Level.Verbose, "Ad Special Row found at index " + row.Index + "."); + continue; + } + //Check to see if the row is dirty. + if (!(bool)row.Cells[(int)InventoryTableColumns.IsDirty].Value) + { + //If it is not then continue on to the next row. + continue; + } + //Try grabbing the row's ID number (the number that it is in the database). + var rowIdNumber = row.Cells[(int)InventoryTableColumns.Id].EditedFormattedValue.ToString() == "" ? 0 : int.Parse(row.Cells[(int)InventoryTableColumns.Id].EditedFormattedValue.ToString()); + //Grab the ad item ID. + var adItemId = int.Parse(databaseReader.RetrieveAdItemId(row.Cells[(int)InventoryTableColumns.AdItem].EditedFormattedValue.ToString(), databaseTracker.DatabaseConnectionString)); + //If the return value is zero (0) then the ad item is not in the database so try to add it. + if (adItemId == 0) + { + //Add the item to the database. + adItemId = databaseWriter.InsertNewAdItem(row.Cells[(int)InventoryTableColumns.AdItem].EditedFormattedValue.ToString()); + if (adItemId == 0) + { + //TODO: Throw an exception, this can not be allowed. + //AdItemInsertionFailedException + newInsertTable.Rows.Clear(); //Work around for now + updateTable.Rows.Clear(); + return TrimmingOperationResult.FailedToTrim; + } + } + //Determine the row's attribute. + var rowAttribute = 0; //Zero (0) means no grouping, its not a header nor a member. + if ((bool)row.Cells[(int)InventoryTableColumns.IsHeaderRow].Value && !(bool)row.Cells[(int)InventoryTableColumns.IsMemberRow].Value) + { + rowAttribute = 1; + } + else if ((bool)row.Cells[(int)InventoryTableColumns.IsMemberRow].Value && !(bool)row.Cells[(int)InventoryTableColumns.IsHeaderRow].Value) + { + rowAttribute = 2; + } + //Add the values to their respective data table. + if (rowIdNumber == 0) + { + //This table is full of data not in the database so the ID column isn't needed. + var newRow = new object[9]; + newRow[0] = row.Cells[(int)InventoryTableColumns.BeginningInventory].EditedFormattedValue.ToString();//Beginning inventory, is string + newRow[1] = row.Cells[(int)InventoryTableColumns.Recieved].EditedFormattedValue.ToString();//Received, is string + newRow[2] = row.Cells[(int)InventoryTableColumns.Total].EditedFormattedValue.ToString();//Total inventory. is string + newRow[3] = row.Cells[(int)InventoryTableColumns.EndingInventory].EditedFormattedValue.ToString(); //Ending inventory, is string + newRow[4] = adItemId; + newRow[5] = rowAttribute; + if (_adSpecialIndex != -1 && row.Index > _adSpecialIndex) + { + newRow[6] = adSpecialId; + newRow[7] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. + } + else + { + newRow[6] = 0; + newRow[7] = row.Index + 1; + } + newRow[8] = dateId; + newInsertTable.Rows.Add(newRow); + } + else + { + //This table is full of data that is already in the database. + var newRow = new object[10]; + newRow[0] = rowIdNumber; + newRow[1] = row.Cells[(int)InventoryTableColumns.BeginningInventory].EditedFormattedValue.ToString();//Beginning inventory, is string + newRow[2] = row.Cells[(int)InventoryTableColumns.Recieved].EditedFormattedValue.ToString();//Received, is string + newRow[3] = row.Cells[(int)InventoryTableColumns.Total].EditedFormattedValue.ToString();//Total inventory. is string + newRow[4] = row.Cells[(int)InventoryTableColumns.EndingInventory].EditedFormattedValue.ToString(); //Ending inventory, is string + newRow[5] = adItemId; + newRow[6] = rowAttribute; + if (_adSpecialIndex != -1 && row.Index > _adSpecialIndex) + { + newRow[7] = adSpecialId; + newRow[8] = row.Index; //"Subtract" one since we don't need to acknowledge the Ad Special Row's existence. + } + else + { + newRow[7] = 0; + newRow[8] = row.Index + 1; + } + newRow[9] = dateId; + updateTable.Rows.Add(newRow); + } + } + + if (newInsertTable.Rows.Count == 0 && updateTable.Rows.Count == 0) + { + return TrimmingOperationResult.NoChangesRequired; + } + if (newInsertTable.Rows.Count > 0 && updateTable.Rows.Count == 0) + { + return TrimmingOperationResult.CreatedNewInsertionTable; + } + if (newInsertTable.Rows.Count == 0 && updateTable.Rows.Count > 0) + { + return TrimmingOperationResult.CreatedUpdateTable; + } + return TrimmingOperationResult.CreatedNewInsertionAndUpdateTables; + } + + private bool ProcessTrimmingStatusResult(DataGridView dataGridView, string tableName, TrimmingOperationResult operationStatus, DataTable trimmedTable, DataTable updateTable) + { + //Create the database interaction objects. + var dbT = new DatabaseTracker(); + var dbW = new DatabaseWriter(dbT.DatabaseConnectionString); + DbTableWriterStatus dbWriterStatus; + var successful = false; + switch (operationStatus) + { + case TrimmingOperationResult.NoChangesRequired: + informationLabel.Text += @"No changes to the " + TextFormat.AddSpacesToSentence(tableName, false) + @" table detected." + Environment.NewLine; + successful = true; + break; + case TrimmingOperationResult.CreatedNewInsertionTable: + dbWriterStatus = dbW.InsertIntoSalesTable(trimmedTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + dataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.Id].Value = rowIndex.Value; + dataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.IsDirty].Value = false; + dataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += TextFormat.AddSpacesToSentence(tableName, false) + @" table successfully added to the database." + Environment.NewLine; + successful = true; + } + else + { + errorLabel.Text = @"Failed to insert " + trimmedTable + @" into the database." + Environment.NewLine; + } + break; + case TrimmingOperationResult.CreatedUpdateTable: + dbWriterStatus = dbW.UpdateSalesTable(updateTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + //Only reset the IsDirty value to false since the updates when through. + dataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.IsDirty].Value = false; + dataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += TextFormat.AddSpacesToSentence(tableName, false) + @" table successfully updated." + Environment.NewLine; + successful = true; + } + else + { + errorLabel.Text = @"Failed to update the " + trimmedTable + @" table." + Environment.NewLine; + } + break; + case TrimmingOperationResult.CreatedNewInsertionAndUpdateTables: + //Insert the new values... + dbWriterStatus = dbW.InsertIntoSalesTable(trimmedTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + //Add the ID numbers to the first column since these are new additions to the database. + dataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.Id].Value = rowIndex.Value; + dataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.IsDirty].Value = false; + dataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += TextFormat.AddSpacesToSentence(tableName, false) + @" table successfully added to the database." + Environment.NewLine; + } + else + { + errorLabel.Text = @"Failed to insert " + trimmedTable + @" into the database." + Environment.NewLine; + } + //... and update the existing values. + dbWriterStatus = dbW.UpdateSalesTable(updateTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + //Only reset the IsDirty value to false since the updates when through. + dataGridView.Rows[rowIndex.Key - 1].Cells[(int)SalesTableColumns.IsDirty].Value = false; + dataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += TextFormat.AddSpacesToSentence(tableName, false) + @" table successfully updated." + Environment.NewLine; + successful = true; + } + else + { + errorLabel.Text = @"Failed to update the " + trimmedTable + @" table." + Environment.NewLine; + } + break; + } + return successful; + } + + private bool ProcessTrimmingStatusForInventory(TrimmingOperationResult operationStatus, DataTable trimmedTable, DataTable updateTable) + { + //Create the database interaction objects. + var dbT = new DatabaseTracker(); + var dbW = new DatabaseWriter(dbT.DatabaseConnectionString); + DbTableWriterStatus dbWriterStatus; + var successful = false; + switch (operationStatus) + { + case TrimmingOperationResult.NoChangesRequired: + informationLabel.Text += @"No changes to the Inventory table detected." + Environment.NewLine; + successful = true; + break; + case TrimmingOperationResult.CreatedNewInsertionTable: + dbWriterStatus = dbW.InsertIntoInventoryTable(trimmedTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + inventoryDataGridView.Rows[rowIndex.Key - 1].Cells[(int)InventoryTableColumns.Id].Value = rowIndex.Value; + inventoryDataGridView.Rows[rowIndex.Key - 1].Cells[(int)InventoryTableColumns.IsDirty].Value = false; + inventoryDataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += @"Inventory table successfully added to the database." + Environment.NewLine; + successful = true; + } + else + { + errorLabel.Text = @"Failed to insert Inventory table into the database." + Environment.NewLine; + } + break; + case TrimmingOperationResult.CreatedUpdateTable: + dbWriterStatus = dbW.UpdateInventoryTable(updateTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + //Only reset the IsDirty value to false since the updates when through. + inventoryDataGridView.Rows[rowIndex.Key - 1].Cells[(int)InventoryTableColumns.IsDirty].Value = false; + inventoryDataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += @"Inventory table successfully updated." + Environment.NewLine; + successful = true; + } + else + { + errorLabel.Text = @"Failed to update the changes in the Inventory table." + Environment.NewLine; + } + break; + case TrimmingOperationResult.CreatedNewInsertionAndUpdateTables: + //Insert the new values... + dbWriterStatus = dbW.InsertIntoInventoryTable(trimmedTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + //Add the ID numbers to the first column since these are new additions to the database. + inventoryDataGridView.Rows[rowIndex.Key - 1].Cells[(int)InventoryTableColumns.Id].Value = rowIndex.Value; + inventoryDataGridView.Rows[rowIndex.Key - 1].Cells[(int)InventoryTableColumns.IsDirty].Value = false; + inventoryDataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += @"Inventory table successfully added to the database." + Environment.NewLine; + successful = true; + } + else + { + errorLabel.Text = @"Failed to insert Inventory table into the database." + Environment.NewLine; + } + dbWriterStatus = dbW.UpdateInventoryTable(updateTable, dbT.DatabaseConnectionString); + if (dbWriterStatus.GetErrorMessage() == string.Empty) + { + //Spin through the collection and update the affected rows. + foreach (var rowIndex in dbWriterStatus.GetRowCollection()) + { + //Only reset the IsDirty value to false since the updates when through. + inventoryDataGridView.Rows[rowIndex.Key - 1].Cells[(int)InventoryTableColumns.IsDirty].Value = false; + inventoryDataGridView.Rows[rowIndex.Key - 1].HeaderCell.Style.BackColor = ApplicationColors.EditingSaved; + } + informationLabel.Text += @"Inventory table successfully updated." + Environment.NewLine; + successful = true; + } + else + { + errorLabel.Text = @"Failed to update the changes in the Inventory table." + Environment.NewLine; + } + break; + } + inventoryDataGridView.RefreshEdit(); + return successful; + } + + private void addRecordButton_Click(object sender, EventArgs e) + { + SaveRecords(); } #endregion diff --git a/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.application b/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.application index d0b0acc..f57c758 100644 --- a/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.application +++ b/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.application @@ -14,7 +14,7 @@ - ahFX/ECRCn2uEoELdC76I+/TVakX4bXkbfjNul+1+Ow= + 7F/RAhUMV4Hdn8Z9v/Nt+yIctA8A8oX18FGf/FPA/ic= diff --git a/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.exe.manifest b/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.exe.manifest index f2311fc..839738e 100644 --- a/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.exe.manifest +++ b/AdvertsingProfitControl/bin/Debug/AdvertsingProfitControl.vshost.exe.manifest @@ -43,14 +43,14 @@ - + - i7aAPQL6YXJt+3MW8a9abkTz7+KcsRjrBy8WabqjtVw= + 9SCbSUpZiztSoLlr90+nJ7hNTimDeyfaAkBthVk+33U=