diff --git a/AdvertsingProfitControl/FrmMain.cs b/AdvertsingProfitControl/FrmMain.cs index 259e0b5..f5a135d 100644 --- a/AdvertsingProfitControl/FrmMain.cs +++ b/AdvertsingProfitControl/FrmMain.cs @@ -1,5 +1,4 @@ using System; -using System.Data.Entity.Core; using System.Data.Entity.Infrastructure; using System.Drawing; using System.Drawing.Printing; @@ -651,11 +650,13 @@ namespace AdvertsingProfitControl invoicesDataGridView.Rows[index].Cells[1].Value = invoice.Supplier.Name; invoicesDataGridView.Rows[index].Cells[2].Value = invoice.InvoiceNumber; invoicesDataGridView.Rows[index].Cells[3].Value = $@"{invoice.InvoiceNetAmountAtCost:N2}"; + //Net Amount Extended Retail is not the required field. + if (invoice.InvoiceNetAmountAtCost != null) _totalInvoicePurchases += (decimal)invoice.InvoiceNetAmountAtCost; invoicesDataGridView.Rows[index].Cells[4].Value = $@"{invoice.InvoiceNetAmount:N2}"; - if (invoice.InvoiceNetAmount != null) _totalInvoicePurchases += (decimal) invoice.InvoiceNetAmount; invoicesDataGridView.Rows[index].Cells[5].Value = invoice.InvoiceNote; } //Add the total purchases row to the invoice table. + if(invoicesDataGridView.RowCount == 0) return; var totalPurchaesRow = new DataGridViewRow(); invoicesDataGridView.Rows.Add(totalPurchaesRow); invoicesDataGridView.Rows[invoicesDataGridView.Rows.Count - 1].Cells[0].Value = @"Total Purchases"; @@ -933,6 +934,12 @@ namespace AdvertsingProfitControl } + private void DebugViewLogFiles(object sender, EventArgs e) + { + var form = new FrmLogFileViewer(); + form.ShowDialog(); + } + #endregion private void ClearActiveDateYearRecords(object sender, EventArgs e) @@ -1100,10 +1107,5 @@ namespace AdvertsingProfitControl #endregion - private void DebugViewLogFiles(object sender, EventArgs e) - { - var form = new FrmLogFileViewer(); - form.ShowDialog(); - } } } \ No newline at end of file diff --git a/AdvertsingProfitControl/GlobalClasses.cs b/AdvertsingProfitControl/GlobalClasses.cs index f9dc8db..1a83371 100644 --- a/AdvertsingProfitControl/GlobalClasses.cs +++ b/AdvertsingProfitControl/GlobalClasses.cs @@ -10,9 +10,13 @@ namespace AdvertsingProfitControl public static void LogError(object sender, System.Threading.ThreadExceptionEventArgs e) { + if (!Directory.Exists(LogFilePath)) + { + Directory.CreateDirectory(LogFilePath); + } using ( var file = - new StreamWriter(@"C:\Users\" + Environment.UserName + @"\AppData\Local\APC\" + DateTime.Now.ToString("MM-dd-yyyy") + ".log", true)) + new StreamWriter(@"C:\Users\" + Environment.UserName + @"\AppData\Local\APC\" + DateTime.Now.ToString("d") + ".log", true)) { file.WriteLine(DateTime.Now + ": Unhandled Thread Exception:\n" + e.Exception.Message + Environment.NewLine); MessageBox.Show(@"An unhandled thread exception has occurred. Advertising Profit Control will be forced to exit.", @@ -23,9 +27,11 @@ namespace AdvertsingProfitControl public static void LogError(object sender, UnhandledExceptionEventArgs e) { - using ( - var file = - new StreamWriter(@"C:\Users\" + Environment.UserName + @"\AppData\Local\APC\" + DateTime.Now.ToString("MM-dd-yyyy") + ".log", true)) + if (!Directory.Exists(LogFilePath)) + { + Directory.CreateDirectory(LogFilePath); + } + using (var file = new StreamWriter(@"C:\Users\" + Environment.UserName + @"\AppData\Local\APC\" + DateTime.Now.ToString("d") + ".log", true)) { file.WriteLine(DateTime.Now + ": An unhandled exception occurred. \nException Object: " + e.ExceptionObject + Environment.NewLine); MessageBox.Show(@"And unknown error has occurred. Advertising Profit Control will be forced to exit.", @@ -36,9 +42,12 @@ namespace AdvertsingProfitControl public static void WriteToLog(string message) { + if (!Directory.Exists(LogFilePath)) + { + Directory.CreateDirectory(LogFilePath); + } using ( -var file = -new StreamWriter(@"C:\Users\" + Environment.UserName + @"\AppData\Local\APC\Information.log", true)) + var file = new StreamWriter(@"C:\Users\" + Environment.UserName + @"\AppData\Local\APC\Information.log", true)) { file.WriteLine(message); } diff --git a/AdvertsingProfitControl/Holiday.cs b/AdvertsingProfitControl/Holiday.cs index 182e580..c285dd8 100644 --- a/AdvertsingProfitControl/Holiday.cs +++ b/AdvertsingProfitControl/Holiday.cs @@ -73,6 +73,24 @@ namespace AdvertsingProfitControl } return holiday; } + + //Source: http://stackoverflow.com/questions/2510383/how-can-i-calculate-what-date-good-friday-falls-on-given-a-year + public static DateTime EasterSunday(int year) + { + var g = year % 19; + var c = year / 100; + var h = (c - c / 4 - (8 * c + 13) / 25 + 19 * g + 15) % 30; + var i = h - h / 28 * (1 - h / 28 * (29 / (h + 1)) * ((21 - g) / 11)); + + var day = i - ((year + year / 4 + i + 2 - c + c / 4) % 7) + 28; + var month = 3; + + if (day <= 31) return new DateTime(year, month, day); + month++; + day -= 31; + + return new DateTime(year, month, day); + } } public enum Holidays { diff --git a/AdvertsingProfitControl/NewModifyRecord.cs b/AdvertsingProfitControl/NewModifyRecord.cs index 7c316c1..ef31508 100644 --- a/AdvertsingProfitControl/NewModifyRecord.cs +++ b/AdvertsingProfitControl/NewModifyRecord.cs @@ -41,6 +41,9 @@ namespace AdvertsingProfitControl private bool _isFormDirty; // private bool _isModifyingRecord; + + private int _selectedRowIndex = -1; + public NewModifyRecord(DateTime date) { InitializeComponent(); @@ -105,6 +108,10 @@ namespace AdvertsingProfitControl projectionsDataGridView.CellEnter += StoreBeginningCellValue; inventoryDataGridView.CellEnter += StoreBeginningCellValue; actualSalesDataGridView.CellEnter += StoreBeginningCellValue; + //Update the selected row index field. + projectionsDataGridView.RowEnter += UpdateSelectedRowIndexOnEnter; + inventoryDataGridView.RowEnter += UpdateSelectedRowIndexOnEnter; + actualSalesDataGridView.RowEnter += UpdateSelectedRowIndexOnEnter; //Update the contents of the used as item list on row leave. projectionsDataGridView.RowLeave += UpdateUsedAdItemCollectionOnRowLeave; inventoryDataGridView.RowLeave += UpdateUsedAdItemCollectionOnRowLeave; @@ -472,6 +479,18 @@ namespace AdvertsingProfitControl _beginningCellValue = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString(); } + /// + /// Keeps track of the currently selected row index in the APC DataGridView that has focus. + /// This is used by the key down event handler in the cell's text box to determine what auto-complete + /// list to use. + /// + /// + /// + private void UpdateSelectedRowIndexOnEnter(object sender, DataGridViewCellEventArgs e) + { + _selectedRowIndex = e.RowIndex; + } + /// /// Event Used: OnRowLeave /// Adds the ad items to the used ad item collection if they are not already in the collection. @@ -816,7 +835,7 @@ namespace AdvertsingProfitControl if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.S) { - if (_adSpecialIndex == -1) + if (_adSpecialIndex == -1 || _adSpecialIndex == _selectedRowIndex) { textBox.AutoCompleteCustomSource = _adSpecialList; informationLabel.Text = @"Auto complete mode changed to Ad Special."; @@ -824,7 +843,7 @@ namespace AdvertsingProfitControl else { textBox.AutoCompleteCustomSource = _trimmedAdItemCollection; - informationLabel.Text = @"An Ad Special row already exists, auto complete mode\n can not be changed."; + informationLabel.Text = @"An Ad Special row already exists;" + Environment.NewLine + @"auto complete mode can not be changed."; } } else if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.A) @@ -2754,6 +2773,8 @@ namespace AdvertsingProfitControl if (projection.FkAdSpecialId != null && adSpecialIndex == -1) { adSpecialIndex = index; + //Set the form's ad special index field. + _adSpecialIndex = index; projectionsDataGridView.Rows.Insert(index, 1); //Apply the ad special text. projectionsDataGridView.Rows[index].DefaultCellStyle.BackColor = ApplicationColors.AdSpecial; @@ -3297,7 +3318,7 @@ namespace AdvertsingProfitControl { //If the row is a new row or is not dirty then continue to the next row if applicable. if (row.IsNewRow) continue; - if (!(bool) row.Cells[(int) SalesTableColumns.IsDirty].EditedFormattedValue) continue; + if (!(bool) row.Cells[(int) SalesTableColumns.IsDirty].EditedFormattedValue && row.Index != _adSpecialIndex) continue; //Obtain the ad item. var adItem = new AdItem(); //Sadly, LINQ doesn't like calls to the ToString method so we create a temp variable. @@ -3420,6 +3441,7 @@ namespace AdvertsingProfitControl : decimal.Parse( row.Cells[(int) SalesTableColumns.TotalProfitReturn].EditedFormattedValue .ToString()); + projection.FkAdSpecialId = adSpecial.Id == 0 ? (int?) null : adSpecial.Id; projection.FkAdItemId = adItem.Id; projection.RowAttribute = rowAttribute; projection.RowPosition = row.Index + 1; @@ -3469,7 +3491,7 @@ namespace AdvertsingProfitControl { //If the row is a new row or is not dirty then continue to the next row if applicable. if (row.IsNewRow) continue; - if (!(bool)row.Cells[(int)InventoryTableColumns.IsDirty].EditedFormattedValue) continue; + if (!(bool)row.Cells[(int)InventoryTableColumns.IsDirty].EditedFormattedValue && row.Index != _adSpecialIndex) continue; //Obtain the ad item. var adItem = new AdItem(); //Sadly, LINQ doesn't like calls to the ToString method so we create a temp variable. @@ -3554,6 +3576,7 @@ namespace AdvertsingProfitControl row.Cells[(int)InventoryTableColumns.Total].EditedFormattedValue.ToString(); inventory.EndingInventory = row.Cells[(int)InventoryTableColumns.EndingInventory].EditedFormattedValue.ToString(); + inventory.FkAdSpecialId = adSpecial.Id == 0 ? (int?)null : adSpecial.Id; inventory.FkAdItemId = adItem.Id; inventory.RowAttribute = rowAttribute; inventory.RowPosition = row.Index + 1; @@ -3603,7 +3626,7 @@ namespace AdvertsingProfitControl { //If the row is a new row or is not dirty then continue to the next row if applicable. if (row.IsNewRow) continue; - if (!(bool)row.Cells[(int)SalesTableColumns.IsDirty].EditedFormattedValue) continue; + if (!(bool)row.Cells[(int)SalesTableColumns.IsDirty].EditedFormattedValue && row.Index != _adSpecialIndex) continue; //Obtain the ad item. var adItem = new AdItem(); //Sadly, LINQ doesn't like calls to the ToString method so we create a temp variable. @@ -3726,6 +3749,7 @@ namespace AdvertsingProfitControl : decimal.Parse( row.Cells[(int)SalesTableColumns.TotalProfitReturn].EditedFormattedValue .ToString()); + actualSale.FkAdSpecialId = adSpecial.Id == 0 ? (int?)null : adSpecial.Id; actualSale.FkAdItemId = adItem.Id; actualSale.RowAttribute = rowAttribute; actualSale.RowPosition = row.Index + 1; @@ -4458,6 +4482,5 @@ namespace AdvertsingProfitControl } } } - } } diff --git a/AdvertsingProfitControl/Properties/AssemblyInfo.cs b/AdvertsingProfitControl/Properties/AssemblyInfo.cs index 4f627a1..22ecc79 100644 --- a/AdvertsingProfitControl/Properties/AssemblyInfo.cs +++ b/AdvertsingProfitControl/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.10.0.0")] -[assembly: AssemblyFileVersion("1.10.0.0")] +[assembly: AssemblyVersion("2.0.1.16")] +[assembly: AssemblyFileVersion("2.0.1.16")] diff --git a/SetupProject/Product.wxs b/SetupProject/Product.wxs index bbff367..54edb20 100644 --- a/SetupProject/Product.wxs +++ b/SetupProject/Product.wxs @@ -1,6 +1,6 @@ - + @@ -37,7 +37,7 @@ - +