From d0c6ce5e42a0094882954b56c59492d105d78dc8 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Thu, 10 Nov 2016 13:35:47 -0600 Subject: [PATCH] First version of the Inventory insertion and update methods, untested. --- AdvertsingProfitControl/APCDatabase.accdb | Bin 2932736 -> 2932736 bytes AdvertsingProfitControl/DatabaseWriter.cs | 182 +++++++++++++++++++++- AdvertsingProfitControl/NewAddRecord.cs | 12 +- 3 files changed, 182 insertions(+), 12 deletions(-) diff --git a/AdvertsingProfitControl/APCDatabase.accdb b/AdvertsingProfitControl/APCDatabase.accdb index 33a1f0b7314bd4c937966d79140522ce2dd3ffee..7a2529dc17e25496bd9de77a2e35ef97e5135268 100644 GIT binary patch delta 280 zcmZo@*vtsR8<_YwXUXhjVq#=uWZW#s_nvXG0v}tGz%~KK6MU?P-MFMDO+PEgD9L>0 zG}H8Z`5a2^-13a=-11D@x#gKRUSJe$-}|1qeeZjg_Py^}+xNa_Yv22xy?yU{j`qFp zIotQX=W5^kp1XbTd!F{a?|IwzzUOP-`<}mj?|Xsvz3&Cv_r4cu-}_#;eeZjb_Py^x zW{I`$eJ|d=_q{~>-uII2d*4g7?|m=bzW2RM``-7m?R($LweNi|-@f;~Li^tLitT&f zE4A-^uiU=(y-NGu_p0rC->bFneXriW_q|5@-uIgAd*5qq-}_$M^#G3|mrt0Z4+8@O k!&!#y0vmM77^f=;uqthD+o+d(Svofsd_8V4DEr2|iYJS&xF6>1X8_C7Jh} zW}1F4pF^pgTb{97* zrS`q=mD~5eS83n-UbTJid$snx@73G)zSn5q`(Cqs?|ZH7d*5rj9^i50@(FYFVPIfj i*vqh8V1rHtDLeqY_JFJa diff --git a/AdvertsingProfitControl/DatabaseWriter.cs b/AdvertsingProfitControl/DatabaseWriter.cs index 1463fa8..4509b31 100644 --- a/AdvertsingProfitControl/DatabaseWriter.cs +++ b/AdvertsingProfitControl/DatabaseWriter.cs @@ -27,14 +27,13 @@ namespace AdvertsingProfitControl /// Supports rolling back the database to prevent corruption. /// /// The data table that contains the data to be inserted. - /// - /// + /// A string pointing to the database. + /// A DbWriterStatus object that contains a status, rows added and an error message if necessary. public DbWriterStatus InsertIntoSalesTable(DataTable salesTable, string connectionString) { var rowIndex = 0; var writerStatus = new DbWriterStatus(); var oleDbConnection = new OleDbConnection(connectionString); - //IDs from the database can not be zero (0), so this will be the default value (no group). var oleDbCommand = new OleDbCommand { Connection = oleDbConnection @@ -124,13 +123,19 @@ namespace AdvertsingProfitControl } return writerStatus; } - + /// + /// Updates existing records in the database for either the Projections + /// table or the Actual Sales table. + /// Supports database rollback. + /// + /// The data table that contains the data to be inserted. + /// A string pointing to the database. + /// A DbWriterStatus object that contains a status, rows added and an error message if necessary. public DbWriterStatus UpdateSalesTable(DataTable salesTable, string connectionString) { var updateStatus = new DbWriterStatus(); var rowIndex = 0; var oleDbConnection = new OleDbConnection(connectionString); - //IDs from the database can not be zero (0), so this will be the default value (no group). var oleDbCommand = new OleDbCommand { Connection = oleDbConnection @@ -204,6 +209,173 @@ namespace AdvertsingProfitControl return updateStatus; } + /// + /// Inserts new records into the Inventory table. + /// Supports database rollback. + /// + /// The data table that contains the data to be inserted. + /// A string pointing to the database. + /// A DbWriterStatus object that contains a status, rows added and an error message if necessary. + public DbWriterStatus InsertIntoInventoryTable(DataTable table, string connectionString) + { + var status = new DbWriterStatus(); + var rowIndex = 0; + var oleDbConnection = new OleDbConnection(connectionString); + var oleDbCommand = new OleDbCommand + { + Connection = oleDbConnection + }; + OleDbTransaction oleDbTransaction = null; + try + { + oleDbTransaction = oleDbConnection.BeginTransaction(); + _oleDbConnection.Open(); + oleDbCommand.Transaction = oleDbTransaction; + for (var i = 0; i < table.Rows.Count; i++) + { + oleDbCommand.CommandText = + "INSERT INTO " + table.TableName + " (BeginningInventory, Received, TotalInventory, EndingInventory, FK_AdItemID, RowAttribute, FK_AdSpecialGroupName, RowPosition, FK_DateID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + //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 + oleDbCommand.Parameters.AddWithValue("BegnningInventory", table.Rows[i][0]); + oleDbCommand.Parameters.AddWithValue("Received", table.Rows[i][1]); + oleDbCommand.Parameters.AddWithValue("TotalInventory", table.Rows[i][2]); + oleDbCommand.Parameters.AddWithValue("EndingInventory", table.Rows[i][3]); + oleDbCommand.Parameters.AddWithValue("AdItemID", table.Rows[i][4]); + oleDbCommand.Parameters.AddWithValue("RowAttribute", table.Rows[i][5]); + oleDbCommand.Parameters.AddWithValue("FK_AdSpecialGroup", table.Rows[i][6]); + oleDbCommand.Parameters.AddWithValue("RowPosition", table.Rows[i][7]); + oleDbCommand.Parameters.AddWithValue("DateID", table.Rows[i][8]); + oleDbCommand.ExecuteNonQuery(); + oleDbCommand.Parameters.Clear(); + //Row index is only used to keep track of what row failed to update. + rowIndex++; + } + oleDbTransaction.Commit(); + foreach (DataRow row in table.Rows) + { + var rowId = RetrieveRowId(table.TableName, int.Parse(row[4].ToString()), int.Parse(row[8].ToString())); + if (int.Parse(row[6].ToString()) != 0) + { + //Account for the ad special row. + //Index 8 of the row indicates that this row is an ad special member row + //so we must add one to the row position to offset the fact that a row + //is "missing" from this DataTable. + //Row[7] is its row position, which is not zero index based. + status.AddRowId(int.Parse(row[7].ToString()) + 1, rowId); + } + else + { + //The ad special row doesn't exist so no need to offset it. + status.AddRowId(int.Parse(row[7].ToString()), rowId); + } + } + status.SetStatus(WritingOperationStatus.InsertionSuccessful); + } + catch (OleDbException e) + { + status.SetStatus(WritingOperationStatus.Failed); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Failed to update the database for " + table.TableName + ": " + e.Message); + if (rowIndex <= 0) + { + _logConsole.WriteToLog(FrmLogConsole.Level.Error, + "Failed to begin parsing data rows, var dump of erroneous row unavailable."); + status.SetErrorMessage("Failed to begin parsing rows."); + } + else + { + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Failed on row " + (rowIndex + 1) + " due to the above error. Dumping contents of row " + (rowIndex + 1) + " from " + table.TableName + "."); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Ad Item ID: \"" + table.Rows[rowIndex][4] + "\" Beginning Inventory: \"" + table.Rows[rowIndex][0]); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Received: \"" + table.Rows[rowIndex][1] + "\" Total Inventory: \"" + table.Rows[rowIndex][2] + "\" Ending Inventory: \"" + table.Rows[rowIndex][3] + "\""); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Row Attribute: \"" + table.Rows[rowIndex][5] + "\" Ad Special ID: \"" + table.Rows[rowIndex][7] + "\""); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Date ID: \"" + table.Rows[rowIndex][8] + "\""); + status.SetErrorMessage("Failed to write to the database on row " + (rowIndex + 1) + "."); + } + oleDbTransaction?.Rollback(); + _logConsole.WriteToLog(FrmLogConsole.Level.Critical, "Rollback completed successfully, " + table.TableName + " table failed on update."); + } + finally + { + _oleDbConnection.Close(); + } + + return status; + } + /// + /// Updates the Inventory table using the supplied DataTable + /// Supports rolling back the database. + /// + /// The table with the changes to be made. + /// A string pointing to the database. + /// A DbWriterStatus object that contains a status, rows added and an error message if necessary. + public DbWriterStatus UpdateInventoryTable(DataTable table, string connectionString) + { + var status = new DbWriterStatus(); + var rowIndex = 0; + var oleDbConnection = new OleDbConnection(connectionString); + var oleDbCommand = new OleDbCommand + { + Connection = oleDbConnection + }; + OleDbTransaction oleDbTransaction = null; + try + { + oleDbTransaction = oleDbConnection.BeginTransaction(); + _oleDbConnection.Open(); + oleDbCommand.Transaction = oleDbTransaction; + for (var i = 0; i < table.Rows.Count; i++) + { + oleDbCommand.CommandText = + "UPDATE " + table.TableName + " SET BeginningInventory = ?, Received =? , TotalInventory = ?, EndingInventory = ?, FK_AdItemID = ?, RowAttribute = ?, FK_AdSpecialGroupName = ?, RowPosition = ? WHERE ID = ?"; + //0:ID 1:BeginningInventory 2:Received 3:TotalInventory 4:EndingInventory + //5:AdItemID 6:RowAttribute 7:GroupID 8:RowPosition 9:DateID + oleDbCommand.Parameters.AddWithValue("BegnningInventory", table.Rows[i][1]); + oleDbCommand.Parameters.AddWithValue("Received", table.Rows[i][2]); + oleDbCommand.Parameters.AddWithValue("TotalInventory", table.Rows[i][3]); + oleDbCommand.Parameters.AddWithValue("EndingInventory", table.Rows[i][4]); + oleDbCommand.Parameters.AddWithValue("AdItemID", table.Rows[i][5]); + oleDbCommand.Parameters.AddWithValue("RowAttribute", table.Rows[i][6]); + oleDbCommand.Parameters.AddWithValue("FK_AdSpecialGroup", table.Rows[i][7]); + oleDbCommand.Parameters.AddWithValue("RowPosition", table.Rows[i][8]); + oleDbCommand.Parameters.AddWithValue("ID", table.Rows[i][0]); + oleDbCommand.ExecuteNonQuery(); + oleDbCommand.Parameters.Clear(); + //Row index is only used to keep track of what row failed to update. + rowIndex++; + } + oleDbTransaction.Commit(); + status.SetStatus(WritingOperationStatus.InsertionSuccessful); + } + catch (OleDbException e) + { + status.SetStatus(WritingOperationStatus.Failed); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Failed to update the database for " + table.TableName + ": " + e.Message); + if (rowIndex <= 0) + { + _logConsole.WriteToLog(FrmLogConsole.Level.Error, + "Failed to begin parsing data rows, var dump of erroneous row unavailable."); + status.SetErrorMessage("Failed to begin parsing rows."); + } + else + { + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Failed on row " + (rowIndex + 1) + " due to the above error. Dumping contents of row " + (rowIndex + 1) + " from " + table.TableName + "."); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Ad Item ID: \"" + table.Rows[rowIndex][4] + "\" Beginning Inventory: \"" + table.Rows[rowIndex][0]); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Received: \"" + table.Rows[rowIndex][1] + "\" Total Inventory: \"" + table.Rows[rowIndex][2] + "\" Ending Inventory: \"" + table.Rows[rowIndex][3] + "\""); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Row Attribute: \"" + table.Rows[rowIndex][5] + "\" Ad Special ID: \"" + table.Rows[rowIndex][7] + "\""); + _logConsole.WriteToLog(FrmLogConsole.Level.Error, "Date ID: \"" + table.Rows[rowIndex][8] + "\""); + status.SetErrorMessage("Failed to write to the database on row " + (rowIndex + 1) + "."); + } + oleDbTransaction?.Rollback(); + _logConsole.WriteToLog(FrmLogConsole.Level.Critical, "Rollback completed successfully, " + table.TableName + " table failed on update."); + } + finally + { + _oleDbConnection.Close(); + } + + return status; + } /// /// Inserts a new ad item into the database and returns the new item's ID number. diff --git a/AdvertsingProfitControl/NewAddRecord.cs b/AdvertsingProfitControl/NewAddRecord.cs index 9692812..d6ea3bf 100644 --- a/AdvertsingProfitControl/NewAddRecord.cs +++ b/AdvertsingProfitControl/NewAddRecord.cs @@ -2143,15 +2143,13 @@ namespace AdvertsingProfitControl { //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 + //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 insertNewTable = new DataTable("Projections"); //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 + //0:ID 1:BeginningInventory 2:Received 3:TotalInventory 4:EndingInventory + //5:AdItemID 6:RowAttribute 7:GroupID 8:RowPosition 9:DateID updateExistingTable = new DataTable("Projections"); //Construct a list of column names for the projections/actual sales DataGridViews and the inventory DataGirdView. string[] saleColumnNames =