317 lines
18 KiB
C#
317 lines
18 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
|
|
namespace AdvertsingProfitControl
|
|
{
|
|
internal class AdvertisingProfitControlTableHelper
|
|
{
|
|
/// <summary>
|
|
/// Paints rows according to their RowAttribute and detects whether or not they are part of a group.
|
|
/// This function offers a faster method of determining all of this by starting at the row index that
|
|
/// fired the row leave even. As opposed to the PaintRowGroups function which spins through all the
|
|
/// DataGridView's rows.
|
|
/// </summary>
|
|
/// <param name="startingIndex">The starting index (the row that fired the RowLeave event)</param>
|
|
/// <param name="dataGridView">The DataGridView to parse.</param>
|
|
public void PaintRowGroupsFromIndex(int startingIndex, DataGridView dataGridView)
|
|
{
|
|
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")
|
|
{
|
|
dataGridView.Rows[startingIndex].DefaultCellStyle.BackColor = Color.Silver;
|
|
return;
|
|
}
|
|
//Spin through the dataGridView rows starting at the row that fired the event.
|
|
for (var i = startingIndex; i < (dataGridView.RowCount - 1); i++)
|
|
{
|
|
//Get the status of the current row.
|
|
var rowStatus = parser.GetRowAttribute(dataGridView.Rows[i]);
|
|
//IF the current row is a header row...
|
|
if (rowStatus == RowAttribute.HeaderRow)
|
|
{
|
|
//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)
|
|
{
|
|
//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)
|
|
{
|
|
//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;
|
|
}
|
|
//IF previous row is Incomplete, then call the stable PaintRowGroups function.
|
|
else if (rowStatus == RowAttribute.IncompleteRow)
|
|
{
|
|
PaintRowGroups(dataGridView);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Then check to see if the next row is a member row
|
|
rowStatus = parser.GetRowAttribute(dataGridView.Rows[i + 1]);
|
|
if (rowStatus == RowAttribute.MemberRow)
|
|
{
|
|
//Set the previous 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;
|
|
//Set the next row as a member row.
|
|
dataGridView.Rows[i + 1].Cells[isHeaderColumn].Value = false;
|
|
dataGridView.Rows[i + 1].Cells[isMemberColumn].Value = true;
|
|
dataGridView.Rows[i + 1].DefaultCellStyle.BackColor = Color.LightBlue;
|
|
}
|
|
}
|
|
}
|
|
else if (rowStatus == RowAttribute.MemberRow)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
//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 from it and the current row (i).
|
|
if (rowStatus == RowAttribute.MemberRow && (i - 1) == 0)
|
|
{
|
|
//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;
|
|
//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 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.
|
|
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;
|
|
dataGridView.Rows[i].Cells[isMemberColumn].Value = true;
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
|
}
|
|
//IF the previous row is simply a member row with no coloring at all, then remove the coloring from the current row (i).
|
|
else if (rowStatus == RowAttribute.MemberRow || rowStatus == RowAttribute.AdSpecialRow)
|
|
{
|
|
//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 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 && !(bool)dataGridView.Rows[i - 1].Cells[isHeaderColumn].Value)
|
|
{
|
|
//Set the previous row as a header row.
|
|
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;
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
|
}
|
|
//IF the previous row is incomplete, then call the stable PaintRowGroups function.
|
|
else if (rowStatus == RowAttribute.IncompleteRow)
|
|
{
|
|
PaintRowGroups(dataGridView);
|
|
}
|
|
}
|
|
//ELSE the current row is the first row in the data grid, therefore it can't be a member row so remove all coloring.
|
|
else
|
|
{
|
|
//Clear the current row of its attributes.
|
|
dataGridView.Rows[0].Cells[isHeaderColumn].Value = false;
|
|
dataGridView.Rows[0].Cells[isMemberColumn].Value = false;
|
|
dataGridView.Rows[0].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void PaintRowGroups(DataGridView dataGridView)
|
|
{
|
|
var parser = new RowParsing();
|
|
var incompleteRowsFound = 0;
|
|
var lastHeaderIndex = -1;
|
|
var i = 0;
|
|
var adSpecialIndex = -1;
|
|
|
|
foreach (DataGridViewRow row in dataGridView.Rows)
|
|
{
|
|
//Get the current row's status.
|
|
var rowType = parser.GetRowAttribute(row);
|
|
//If the current row is not a group header, the first row in the grid, or a new row and in fact a member row...
|
|
if (i != 0 && rowType == RowAttribute.MemberRow && !row.IsNewRow && rowType != RowAttribute.IncompleteRow)
|
|
{
|
|
//Remove all coloring on the current row.
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
|
|
//Check to make sure the numbers are within bounds, errors occurs when an incomplete row is found at index zero (0), and the current row is one (1).
|
|
if ((i - (1 + incompleteRowsFound)) > 0)
|
|
{
|
|
//Check to see if the previous row is a header row by subtracting the number of rows that are (incomplete + 1) from the total number of rows (i).
|
|
//Adding one (1) to the incomplete count allows for checking the row right before the first incomplete row found so far to see if it's a header row.
|
|
if (parser.GetRowAttribute(dataGridView.Rows[i - (1 + incompleteRowsFound)]) == RowAttribute.HeaderRow)
|
|
{
|
|
row.DefaultCellStyle.BackColor = Color.LightBlue; //Group member
|
|
dataGridView.Rows[lastHeaderIndex].DefaultCellStyle.BackColor = Color.LightGray; //Group header
|
|
}
|
|
//Else if a header row was not found from the previous operation but a header row is set, then its safe to assume that this row can be a member.
|
|
else if (lastHeaderIndex >= 0)
|
|
{
|
|
//Check to make sure that the last header index is underneath the Ad Special Row OR that the current row (i) is before the Ad Special Index.
|
|
if (lastHeaderIndex > adSpecialIndex || i < adSpecialIndex)
|
|
{
|
|
//Assume that the current row is a member of that group header and color it as such.
|
|
row.DefaultCellStyle.BackColor = Color.LightBlue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//If the current row is a potential group header AND the next row is as well remove the coloring from the current row, no need for checks.
|
|
else if (rowType == RowAttribute.HeaderRow && parser.GetRowAttribute(dataGridView.Rows[i + 1]) == RowAttribute.HeaderRow)
|
|
{
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
//Check to see if this row is the first row, a header index row, AND the next row is a MemberRow.
|
|
else if (rowType == RowAttribute.HeaderRow && parser.GetRowAttribute(dataGridView.Rows[i + 1]) == RowAttribute.MemberRow && i == 0)
|
|
{
|
|
//IF so, set the last header index, and color code of this row along with the next row which is a MemberRow.
|
|
lastHeaderIndex = 0;
|
|
dataGridView.Rows[0].DefaultCellStyle.BackColor = Color.LightGray;
|
|
dataGridView.Rows[i + 1].DefaultCellStyle.BackColor = Color.LightBlue;
|
|
}
|
|
//Check to see if this row is a group header.
|
|
else if (rowType == RowAttribute.HeaderRow)
|
|
{
|
|
//If so, reset the incomplete rows found count, set the lastHeaderIndex to this row's index (i) and change it's color to white.
|
|
incompleteRowsFound = 0;
|
|
lastHeaderIndex = i;
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
//If the current row is the first row in the grid AND is not a group header then remove all color from it, since its not allowed to be a header or a member.
|
|
else if (i == 0 && rowType == RowAttribute.MemberRow)
|
|
{
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
//Mark an incomplete row to determine whether or not we found one and remove any coloring it may have, incomplete rows are not allowed to be members or headers.
|
|
if (rowType == RowAttribute.IncompleteRow)
|
|
{
|
|
incompleteRowsFound++;
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
//
|
|
if (rowType == RowAttribute.AdSpecialRow)
|
|
{
|
|
adSpecialIndex = i;
|
|
dataGridView.Rows[i].DefaultCellStyle.BackColor = Color.Silver;
|
|
}
|
|
i++;
|
|
}//end for-each
|
|
dataGridView.Refresh();
|
|
}//End PaintRowGroups
|
|
}
|
|
|
|
public enum SalesTableColumns
|
|
{
|
|
Id = 0,
|
|
AdItem = 1,
|
|
Sold = 2,
|
|
SalePrice = 3,
|
|
TotalSales = 4,
|
|
Cost = 5,
|
|
ProfitReturn = 6,
|
|
TotalProfitReturn = 7,
|
|
IsHeaderRow = 8,
|
|
IsMemberRow = 9,
|
|
IsDirty = 10
|
|
}
|
|
|
|
public enum InventoryTableColumns
|
|
{
|
|
Id = 0,
|
|
AdItem = 1,
|
|
BeginningInventory = 2,
|
|
Recieved = 3,
|
|
Total = 4,
|
|
EndingInventory = 5,
|
|
IsHeaderRow = 6,
|
|
IsMemberRow = 7,
|
|
IsDirty = 8
|
|
}
|
|
|
|
public enum InvoiceTableColumns
|
|
{
|
|
Id = 0,
|
|
InvoiceDate = 1,
|
|
Supplier = 2,
|
|
InvoiceNumber = 3,
|
|
InvoiceNetAmountAtCost = 4,
|
|
InvoiceNetAmount = 5,
|
|
InvoiceNote = 6,
|
|
IsDirty = 7
|
|
}
|
|
|
|
/// <summary>
|
|
/// TODO: Push into a stand alone object.
|
|
/// </summary>
|
|
public enum TrimmingOperationResult
|
|
{
|
|
FailedToTrim = 0,
|
|
CreatedNewInsertionTable = 1,
|
|
CreatedUpdateTable = 2,
|
|
CreatedNewInsertionAndUpdateTables = 3,
|
|
NoChangesRequired = 4
|
|
}
|
|
}
|