Marked as 'AdvertsingProfitControl v 0.8.5' by its folder name. The 'Add Records' form has been finshed to at least include all the information the Advertising Profit Control sheet had.
This commit is contained in:
+632
-127
@@ -1,169 +1,674 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Data.OleDb;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AdvertsingProfitControl
|
||||
{
|
||||
public partial class frmMain : Form
|
||||
{
|
||||
private AutoCompleteStringCollection dateSuggestions = new AutoCompleteStringCollection();
|
||||
//private string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=apcDatabase.accdb;Persist Security Info=False";
|
||||
private double _gActualTotaSalesCalculatedTotal = 0;
|
||||
private double _gActualTotalProfitReturnCalculatedTotal = 0;
|
||||
private double _gCostOfSalesCalculatedTotal = 0;
|
||||
private List<string> _gDateStringCollection = new List<string>();
|
||||
readonly LogConsole _console = LogConsole.GetStaticInstance;
|
||||
|
||||
public frmMain()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
//Set the maximum and minimum sizes for the form.
|
||||
MaximumSize = new Size(1200, 650);
|
||||
MinimumSize = new Size(1000, 550);
|
||||
}
|
||||
|
||||
private void frmMain_Load(object sender, EventArgs e)
|
||||
{
|
||||
//connect to the database on form load | eh?
|
||||
BuildUITables();
|
||||
addRecordToolStripMenuItem.PerformClick();
|
||||
FillDateSuggestionComboBoxes();
|
||||
BuildAndFillDataGridTables();
|
||||
CalculateProfitAnalysis();
|
||||
CalculateGrossProfit();
|
||||
|
||||
_console.Show();
|
||||
}
|
||||
|
||||
private void UpdateDataGridViewInformation(object sender, EventArgs e)
|
||||
{
|
||||
string dateString = monthComboBox.Text + "/" + dayComboBox.Text + "/" + yearComboBox.Text;
|
||||
BuildAndFillDataGridTables(dateString);
|
||||
CalculateProfitAnalysis();
|
||||
CalculateGrossProfit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function re-orders the DataGridView to fit the
|
||||
/// column scheme of the Advertising Profit Control sheet,
|
||||
/// because SQL doesn't appear to return the columns in
|
||||
/// the desired order.
|
||||
/// Builds and fills the DataGridView tables on the main form
|
||||
/// from the either the most recent date or the date specified in the parameter.
|
||||
/// </summary>
|
||||
/// <param name="dataGrid"></param>
|
||||
private void ReorderDataGridView(DataGridView dataGrid)
|
||||
/// <param name="dateString">The date of records to display to the user, if no date is specified then the most recent date is used.</param>
|
||||
private void BuildAndFillDataGridTables(string dateString = "")
|
||||
{
|
||||
foreach (DataGridViewColumn column in dataGrid.Columns)
|
||||
//Deprecated
|
||||
var dataBaseReader = new RetrieveFromDatabase();
|
||||
//
|
||||
var dateId = "";
|
||||
|
||||
//Check to see if a parameter has been passed.
|
||||
if (dateString == "")
|
||||
{
|
||||
if (!column.Name.Contains("ID"))
|
||||
//IF non were, then grab the most recent date ID from the database and use that.
|
||||
dateId = dataBaseReader.RetrieveMostRecentDateId();
|
||||
_console.WriteToLog(LogConsole.Level.Info, dateId != "-1" ? "Most recent date ID is " + dateId : "Most recent date ID is unavailable.");
|
||||
}
|
||||
else
|
||||
{
|
||||
//ELSE IF one was passed, then use it's ID to build the tables.
|
||||
dateId = dataBaseReader.RetrieveDateIdByDateString(dateString);
|
||||
_console.WriteToLog(LogConsole.Level.Info, dateId != "-1" ? "Date ID for " + dateString + " is resolved to have the ID of " + dateId + "." : "The date " + dateString + " could not be found in the database.");
|
||||
if (dateId == "-1")
|
||||
{
|
||||
switch (column.Name.ToLower())
|
||||
_gDateStringCollection.Remove(dateString);
|
||||
}
|
||||
}
|
||||
//Now check to make sure there were no errors grabbing the ID, IF there were return.
|
||||
if (dateId == "-1") return;
|
||||
//Clear the class global variables to prevents calculation mishaps.
|
||||
_gActualTotaSalesCalculatedTotal = 0;
|
||||
_gActualTotalProfitReturnCalculatedTotal = 0;
|
||||
_gCostOfSalesCalculatedTotal = 0;
|
||||
//Clear all DataGridViews since the date supplied is valid and in the database.
|
||||
projectedSalesMainDataGrid.DataSource = null;
|
||||
inventoryDataGridView.DataSource = null;
|
||||
actualSalesMainDataGidView.DataSource = null;
|
||||
suppliersDataGridView.DataSource = null;
|
||||
weeklySalesDataGridView.DataSource = null;
|
||||
var indexOfAdSpecialRow = -1;
|
||||
var regexGroupCategoryparser = new Regex(@"^(\d)?\|\d");
|
||||
//Begin by grabbing the Projections table
|
||||
var tempTable = dataBaseReader.ReturnProjectionsTable(dateId);
|
||||
if (tempTable.Rows.Count > 0)
|
||||
{
|
||||
projectedSalesMainDataGrid.DataSource = SumSalesTable(tempTable);
|
||||
string adCategory = "";
|
||||
for (var i = 0; i < projectedSalesMainDataGrid.Rows.Count; i++)
|
||||
{
|
||||
int castedValue = 0;
|
||||
if ((string)projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue == "1")
|
||||
{
|
||||
//---Begin AdItem Table check-------------------
|
||||
case "aditem":
|
||||
column.DisplayIndex = 0;
|
||||
column.HeaderText = "Ad Item";
|
||||
break;
|
||||
//---End AdItem Table check---------------------
|
||||
//---Begin Projected Sales Table check----------
|
||||
case "prsold":
|
||||
column.DisplayIndex = 1;
|
||||
column.HeaderText = "Sold";
|
||||
break;
|
||||
case "prsaleprice":
|
||||
column.DisplayIndex = 2;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Sale Price";
|
||||
break;
|
||||
case "prtotalsales":
|
||||
column.DisplayIndex = 3;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Total Sales";
|
||||
break;
|
||||
case "prcost":
|
||||
column.DisplayIndex = 4;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Cost";
|
||||
break;
|
||||
case "prprofitreturn":
|
||||
column.DisplayIndex = 5;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Profit Return";
|
||||
break;
|
||||
case "prtotalprofitreturn":
|
||||
column.DisplayIndex = 6;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Total Profit Return";
|
||||
break;
|
||||
//---End Projected Sales Table check------------
|
||||
//---Begin Inventory Table check----------------
|
||||
case "invbegininginventory":
|
||||
column.DisplayIndex = 1;
|
||||
column.HeaderText = "Beginning inventory";
|
||||
break;
|
||||
case "invrecieved":
|
||||
column.DisplayIndex = 2;
|
||||
column.HeaderText = "Received";
|
||||
break;
|
||||
case "invtotal":
|
||||
column.DisplayIndex = 3;
|
||||
column.HeaderText = "Total";
|
||||
break;
|
||||
case "invending":
|
||||
column.DisplayIndex = 4;
|
||||
column.HeaderText = "Ending Inventory";
|
||||
break;
|
||||
//---End Inventory Table check------------------
|
||||
//---Begin Actual Sales Table check-------------
|
||||
case "acsold":
|
||||
column.DisplayIndex = 8;
|
||||
column.HeaderText = "Sold";
|
||||
break;
|
||||
case "acsaleprice":
|
||||
column.DisplayIndex = 9;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Sale Price";
|
||||
break;
|
||||
case "actotalsales":
|
||||
column.DisplayIndex = 10;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Total Sales";
|
||||
break;
|
||||
case "accost":
|
||||
column.DisplayIndex = 11;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Cost";
|
||||
break;
|
||||
case "acprofitreturn":
|
||||
column.DisplayIndex = 12;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Profit Return";
|
||||
break;
|
||||
case "actotalprofitreturn":
|
||||
column.DisplayIndex = 13;
|
||||
column.DefaultCellStyle.Format = "c";
|
||||
column.HeaderText = "Total Profit Return";
|
||||
break;
|
||||
//---End Actual Table check---------------------
|
||||
default:
|
||||
MessageBox.Show("This message box should never appear but if it does record this information:\n" + "Column Name: " + column.Name + "\nColumn Type: " + column.ValueType, "Unknown Column Detected", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
break;
|
||||
projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
|
||||
}else if ((string) projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue == "2")
|
||||
{
|
||||
projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
||||
}
|
||||
else if (
|
||||
regexGroupCategoryparser.IsMatch(
|
||||
(string) projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue))
|
||||
{
|
||||
string[] spam = new string[2];
|
||||
spam = ParseAdSpecialRows(projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue.ToString());
|
||||
if (spam.Length > 1)
|
||||
{
|
||||
adCategory = spam[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
adCategory = spam[0];
|
||||
}
|
||||
if (indexOfAdSpecialRow == -1)
|
||||
{
|
||||
indexOfAdSpecialRow = i;
|
||||
}
|
||||
|
||||
if (spam[0] == "1")
|
||||
{
|
||||
projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
|
||||
}else if (spam[0] == "2")
|
||||
{
|
||||
projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//The column was an ID field therefore we won't bother showing it to the user.
|
||||
column.Visible = false;
|
||||
}
|
||||
var dataGridViewColumn = projectedSalesMainDataGrid.Columns["FK_GroupID"];
|
||||
if (dataGridViewColumn != null)
|
||||
dataGridViewColumn.Visible = false;
|
||||
}
|
||||
}//End of ReorderDataGridView() function
|
||||
|
||||
private void BuildUITables()
|
||||
{
|
||||
RetrieveTables tableData = new RetrieveTables();
|
||||
DataGridView finalWICTable = new DataGridView();
|
||||
string[] comments;
|
||||
|
||||
projectedSalesMainDataGrid.DataSource = tableData.APCProjectionSaleTable();
|
||||
ReorderDataGridView(projectedSalesMainDataGrid);
|
||||
actualSalesInvMainDataGidView.DataSource = tableData.APCActualSalesTable();
|
||||
ReorderDataGridView(actualSalesInvMainDataGidView);
|
||||
finalWICTable.DataSource = tableData.WICTable();
|
||||
comments = tableData.Comment();
|
||||
foreach (string comment in comments)
|
||||
//Grabbing the Inventory table
|
||||
tempTable = dataBaseReader.ReturnInventoryTable(dateId);
|
||||
if (tempTable.Rows.Count > 0)
|
||||
{
|
||||
commentsMainLabel.Text = comment + "\n";
|
||||
inventoryDataGridView.DataSource = tempTable;
|
||||
string adCategory = "";
|
||||
for (var i = 0; i < inventoryDataGridView.Rows.Count; i++)
|
||||
{
|
||||
int castedValue = 0;
|
||||
if ((string)inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue == "1")
|
||||
{
|
||||
inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
|
||||
}
|
||||
else if ((string)inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue == "2")
|
||||
{
|
||||
inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
||||
}
|
||||
else if (
|
||||
regexGroupCategoryparser.IsMatch(
|
||||
(string)inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue))
|
||||
{
|
||||
string[] spam = new string[2];
|
||||
spam = ParseAdSpecialRows(inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue.ToString());
|
||||
if (spam.Length > 1)
|
||||
{
|
||||
adCategory = spam[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
adCategory = spam[0];
|
||||
}
|
||||
|
||||
if (spam[0] == "1")
|
||||
{
|
||||
inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
|
||||
}
|
||||
else if (spam[0] == "2")
|
||||
{
|
||||
inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
||||
}
|
||||
}
|
||||
}
|
||||
var dataGridViewColumn = inventoryDataGridView.Columns["FK_GroupID"];
|
||||
if (dataGridViewColumn != null)
|
||||
dataGridViewColumn.Visible = false;
|
||||
}
|
||||
|
||||
//And the Actual Sales table
|
||||
tempTable = dataBaseReader.ReturnActualSales(dateId);
|
||||
if (tempTable.Rows.Count > 0)
|
||||
{
|
||||
actualSalesMainDataGidView.DataSource = SumSalesTable(tempTable);
|
||||
string adCategory = "";
|
||||
for (var i = 0; i < actualSalesMainDataGidView.Rows.Count; i++)
|
||||
{
|
||||
int castedValue = 0;
|
||||
if ((string)actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue == "1")
|
||||
{
|
||||
actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
|
||||
}
|
||||
else if ((string)actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue == "2")
|
||||
{
|
||||
actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
||||
}
|
||||
else if (
|
||||
regexGroupCategoryparser.IsMatch(
|
||||
(string)actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue))
|
||||
{
|
||||
string[] spam = new string[2];
|
||||
spam = ParseAdSpecialRows(actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue.ToString());
|
||||
if (spam.Length > 1)
|
||||
{
|
||||
adCategory = spam[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
adCategory = spam[0];
|
||||
}
|
||||
|
||||
if (spam[0] == "1")
|
||||
{
|
||||
actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
|
||||
}
|
||||
else if (spam[0] == "2")
|
||||
{
|
||||
actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
|
||||
}
|
||||
}
|
||||
}
|
||||
var year = actualSalesMainDataGidView.Columns["FK_GroupID"];
|
||||
if (year != null)
|
||||
year.Visible = false;
|
||||
}
|
||||
|
||||
//Next the Invoices table
|
||||
tempTable = dataBaseReader.ReturnInvoiceTable(dateId);
|
||||
if (tempTable.Rows.Count > 0)
|
||||
{
|
||||
suppliersDataGridView.DataSource = SumCostOfSales(tempTable);
|
||||
}
|
||||
|
||||
//And finally the weekly sales
|
||||
tempTable = dataBaseReader.ReturnWeeklySalesFromDateID(dateId);
|
||||
if (tempTable.Rows.Count > 0)
|
||||
{
|
||||
weeklySalesDataGridView.DataSource = tempTable;
|
||||
}
|
||||
|
||||
commentsTextBox.Text = dataBaseReader.RetrieveComments(dateId);
|
||||
}
|
||||
|
||||
private void CalculateProfitAnalysis(double shrink = 0.30)
|
||||
{
|
||||
if (Math.Abs(_gActualTotaSalesCalculatedTotal) < 1 || Math.Abs(_gActualTotalProfitReturnCalculatedTotal) < 1)
|
||||
{
|
||||
//Clear the labels...
|
||||
if (weeklySalesDataGridView.Rows.Count == 0 || weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString() == "0.0000")
|
||||
{
|
||||
departmentSalesLabel.Text = "Department Sales: No Weekly Sales Found.";
|
||||
departmentSalesLabel.ForeColor = Color.Red;
|
||||
}
|
||||
|
||||
if (_gActualTotaSalesCalculatedTotal == 0)
|
||||
{
|
||||
salesProducedLabel.Text = "Sales Produced By Ad Items (A): No Values to Total.";
|
||||
salesProducedLabel.ForeColor = Color.Red;
|
||||
}
|
||||
|
||||
remainingSalesLabel.Text = "Remaining Sales: ";
|
||||
if (_gActualTotalProfitReturnCalculatedTotal == 0)
|
||||
{
|
||||
totalProfitFromAdItemsLabel.Text = "Total Profit Return From Ad Items (B): No Values to Total.";
|
||||
totalProfitFromAdItemsLabel.ForeColor = Color.Red;
|
||||
}
|
||||
|
||||
totalProfitReturnFromRemaingLabel.Text = "Total Profit Return From Remaining Sales: ";
|
||||
totalProfitReturnLabel.Text = "Total Profit Return: ";
|
||||
return;
|
||||
}
|
||||
double departmentSales = 0;
|
||||
Double.TryParse(weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString(), out departmentSales);
|
||||
//Since there are department sales, change the label's color to make sure it doesn't appear as an error.
|
||||
departmentSalesLabel.ForeColor = Color.Black;
|
||||
departmentSalesLabel.Text = "Department Sales: " + departmentSales.ToString("C");
|
||||
//Assume that the sales produced is larger then zero (0).
|
||||
salesProducedLabel.ForeColor = Color.Black;
|
||||
salesProducedLabel.Text = "Sales Produced By Ad Items (A): " + _gActualTotaSalesCalculatedTotal.ToString("C");
|
||||
|
||||
double remainingSales = departmentSales - _gActualTotaSalesCalculatedTotal;
|
||||
remainingSalesLabel.Text = "Remaining Sales: " + remainingSales.ToString("C");
|
||||
//Again assume the total profit return is larger then zero (0).
|
||||
totalProfitFromAdItemsLabel.ForeColor = Color.Black;
|
||||
totalProfitFromAdItemsLabel.Text = "Total Profit Return From Ad Items (B): " + _gActualTotalProfitReturnCalculatedTotal.ToString("C");
|
||||
//Shrink is being used as a place holder for Cross Profit % which is obtained by dividing gActualTotalProfitReturnCalculatedTotal by the department weekly retail sales.
|
||||
double totalProfitReturnFromRemainingSales = shrink * remainingSales;
|
||||
//
|
||||
totalProfitReturnFromRemaingLabel.Text = "Total Profit Return From Remaining Sales: " + totalProfitReturnFromRemainingSales.ToString("C");
|
||||
double totalProfitReturn = _gActualTotalProfitReturnCalculatedTotal + totalProfitReturnFromRemainingSales;
|
||||
totalProfitReturnLabel.Text = "Total Profit Return: " + totalProfitReturn.ToString("C");
|
||||
}
|
||||
|
||||
private void CalculateCostOfSales()
|
||||
{
|
||||
//?
|
||||
}
|
||||
|
||||
private void CalculateGrossProfit()
|
||||
{
|
||||
if (Math.Abs(_gCostOfSalesCalculatedTotal) < 1)
|
||||
{
|
||||
//IF Cost of Sales hasn't been calculated, then clear labels and return.
|
||||
if (weeklySalesDataGridView.Rows.Count == 0 || weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString() == "0.0000")
|
||||
{
|
||||
grossProfitTotalSales.Text = "Total Sales: No Weekly Sales Found.";
|
||||
grossProfitTotalSales.ForeColor = Color.Red;
|
||||
}
|
||||
grossProfitLessCostOfSales.Text = "Less Cost of Sales: ";
|
||||
grossProfitDollarGrossProfitLabel.Text = "Dollar Gross Profit: ";
|
||||
perfectGrossProfitLabel.Text = "Percent Gross Profit: ";
|
||||
return;
|
||||
}
|
||||
|
||||
double totalSales = Convert.ToDouble(weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString());
|
||||
grossProfitTotalSales.ForeColor = Color.Black;
|
||||
grossProfitTotalSales.Text = "Total Sales: " + totalSales.ToString("C");
|
||||
grossProfitLessCostOfSales.Text = "Less Cost of Sales: " + _gCostOfSalesCalculatedTotal.ToString("C");
|
||||
double dollarGrossProfit = totalSales - _gCostOfSalesCalculatedTotal;
|
||||
grossProfitDollarGrossProfitLabel.Text = "Dollar Gross Profit: " + dollarGrossProfit.ToString("C");
|
||||
double grossProfitPercent = dollarGrossProfit / totalSales;
|
||||
perfectGrossProfitLabel.Text = "Percent Gross Profit: " + grossProfitPercent.ToString("P");
|
||||
}
|
||||
|
||||
private void addRecordToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
frmAddRecord recordForm = new frmAddRecord();
|
||||
recordForm.ShowDialog();
|
||||
BuildUITables();
|
||||
FillDateSuggestionComboBoxes();
|
||||
BuildAndFillDataGridTables();
|
||||
CalculateProfitAnalysis();
|
||||
CalculateGrossProfit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a new "Totals" row to the end of the DataTable that is passed in
|
||||
/// and sums up the Total Sales and Total Profit Return columns as well as
|
||||
/// storing the Total Sales and Total Profit Return in their respective
|
||||
/// class wide variables for use with other functions.
|
||||
/// </summary>
|
||||
/// <param name="table">The sales table to be summed up.</param>
|
||||
/// <returns></returns>
|
||||
private DataTable SumSalesTable(DataTable table)
|
||||
{
|
||||
//IF the table is null OR has an invalid column count then return.
|
||||
if (table == null || table.Columns.Count < 7) return table;
|
||||
|
||||
//Both Projections and Actual tables have the Total Sales and Total Profit Return columns in the same position,
|
||||
//indexes three (3) and six (6) respectively.
|
||||
double totalSalesSum = 0;
|
||||
double totalProfitReturnSum = 0;
|
||||
|
||||
for (var i = 0; i < table.Rows.Count; i++)
|
||||
{
|
||||
totalSalesSum += Convert.ToDouble(table.Rows[i][3]);
|
||||
totalProfitReturnSum += Convert.ToDouble(table.Rows[i][6]);
|
||||
}
|
||||
|
||||
//Once the totals have been calculated store them in the class wide variables so other methods can use them.
|
||||
_gActualTotaSalesCalculatedTotal = totalSalesSum;
|
||||
_gActualTotalProfitReturnCalculatedTotal = totalProfitReturnSum;
|
||||
//Create an object array to store the summed values and add them at the end to the table before returning it.
|
||||
object[] rowContents = new object[table.Columns.Count];
|
||||
rowContents[0] = "Total";
|
||||
rowContents[3] = totalSalesSum;
|
||||
rowContents[6] = totalProfitReturnSum;
|
||||
table.Rows.Add(rowContents);
|
||||
return table;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a new "Totals" row to the end of the Invoice table that is passed in
|
||||
/// and sums up the Net Cost of Invoices column as well as storing the total Costs of Sales
|
||||
/// into the class wide variable for use with other functions.
|
||||
/// </summary>
|
||||
/// <param name="invoiceTable">The Invoice table to summed.</param>
|
||||
/// <returns></returns>
|
||||
private DataTable SumCostOfSales(DataTable invoiceTable)
|
||||
{
|
||||
//Check for a null parameter OR if the column count is less then six (6) as any less means the database isn't returning correctly.
|
||||
if(invoiceTable == null || invoiceTable.Columns.Count < 6) return invoiceTable;
|
||||
double costOfSalesSum = 0;
|
||||
|
||||
for (var i = 0; i < invoiceTable.Rows.Count; i++)
|
||||
{
|
||||
costOfSalesSum += Convert.ToDouble(invoiceTable.Rows[i][4]);
|
||||
}
|
||||
|
||||
_gCostOfSalesCalculatedTotal = costOfSalesSum;
|
||||
|
||||
object[] invoiceTotalRow = new object[invoiceTable.Columns.Count];
|
||||
invoiceTotalRow[0] = "Total Purchases";
|
||||
invoiceTotalRow[4] = costOfSalesSum;
|
||||
invoiceTable.Rows.Add(invoiceTotalRow);
|
||||
|
||||
return invoiceTable;
|
||||
}
|
||||
|
||||
private void showHideConsoleHelpMainMenu_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_console.IsVisable)
|
||||
{
|
||||
_console.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
_console.Show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Grabs all dates from the database and splits the returned strings
|
||||
/// into months, days, and years and stores them in their respective
|
||||
/// combo boxes to display to the user. Also stores the list of dates
|
||||
/// inside a class wide variable.
|
||||
/// </summary>
|
||||
private void FillDateSuggestionComboBoxes()
|
||||
{
|
||||
//Create a connection to the database retrieval class.
|
||||
var dbReader = new RetrieveFromDatabase();
|
||||
//Grab the most recent date in the database.
|
||||
var mostRecentDateTime = dbReader.ReturnMostRecentDateString();
|
||||
var mostRecentDateString = mostRecentDateTime.ToString("MM/dd/yyyy");
|
||||
//Check to see if the return value is null and IF so log the error and return.
|
||||
if(mostRecentDateString == ""){ _console.WriteToLog(LogConsole.Level.Error, "No dates could be found in the database."); return;}
|
||||
//Otherwise, if there was a return date, split it into a array.
|
||||
var mostRecentDateParts = mostRecentDateString.Split('/');
|
||||
//Grab only the most recent years in the database (only say 2015) and fill a table with the dates. Indexes are as follows: [0] is Month, [1] is Day and [2] is Year.
|
||||
DataTable oneYearDatesTable = dbReader.ReturnDateStringsLike(mostRecentDateParts[0] + "/" + mostRecentDateParts[1] + "/" + mostRecentDateParts[2]);
|
||||
//Suspend the control's drawing so the user doesn't see any ugly enumeration and index changing.
|
||||
DrawingControl.SuspendDrawing(dateSelectorPanel);
|
||||
//Considering there was a return value for the most recent date, its safe to assume there is at least one date in the database, so clear the class's date collection.
|
||||
_gDateStringCollection.Clear();
|
||||
monthComboBox.Items.Clear();
|
||||
dayComboBox.Items.Clear();
|
||||
yearComboBox.Items.Clear();
|
||||
monthComboBox.SelectedIndexChanged -= UpdateDaysOfMonth;
|
||||
dayComboBox.SelectedIndexChanged -= UpdateDataGridViewInformation;
|
||||
yearComboBox.SelectedIndexChanged -= UpdateDaysOfMonthByYear;
|
||||
//Now spin through the oneYearDatesTable and fill the class wide object with all the dates for the most recent year.
|
||||
for (var i = 0; i < oneYearDatesTable.Rows.Count; i ++)
|
||||
{
|
||||
var fullDateTime = (DateTime) oneYearDatesTable.Rows[i][0];
|
||||
var fullDateString = fullDateTime.ToString("MM/dd/yyyy");
|
||||
//Check for nulls just to be paranoid.
|
||||
if (fullDateString == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
//IF the date string collection already contains the date, then continue to the next iteration.
|
||||
if (_gDateStringCollection.Contains(fullDateString))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_gDateStringCollection.Add(fullDateString);
|
||||
}
|
||||
|
||||
var dayBasedOnMonthAndYeaRegex = new Regex("^0?" + mostRecentDateParts[0] + @"/\d{2}/" + mostRecentDateParts[2]);
|
||||
var monthBasedOnYearRegex = new Regex(@"^\d{2}/\d{2}/" + mostRecentDateParts[2]);
|
||||
for (var i = 0; i < _gDateStringCollection.Count; i++)
|
||||
{
|
||||
string[] dateArray = _gDateStringCollection[i].Split('/');
|
||||
var month = dateArray[0];
|
||||
var day =dateArray[1];
|
||||
|
||||
if (dayBasedOnMonthAndYeaRegex.IsMatch(_gDateStringCollection[i]))
|
||||
{
|
||||
dayComboBox.Items.Add(day);
|
||||
}
|
||||
if (monthBasedOnYearRegex.IsMatch(_gDateStringCollection[i]))
|
||||
{
|
||||
if (!monthComboBox.Items.Contains(month))
|
||||
{
|
||||
monthComboBox.Items.Add(month);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var yearsInDatabase = dbReader.ReturnUniqueYearsList();
|
||||
|
||||
foreach (var year in yearsInDatabase)
|
||||
{
|
||||
yearComboBox.Items.Add(year);
|
||||
}
|
||||
|
||||
if (dayComboBox.Items.Count >= 1 && yearComboBox.Items.Count >= 1 && monthComboBox.Items.Count >= 1)
|
||||
{
|
||||
monthComboBox.SelectedIndex = monthComboBox.Items.Count - 1;
|
||||
dayComboBox.SelectedIndex = dayComboBox.Items.Count - 1;
|
||||
yearComboBox.SelectedIndex = yearComboBox.Items.Count - 1;
|
||||
monthComboBox.Enabled = true;
|
||||
dayComboBox.Enabled = true;
|
||||
yearComboBox.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
monthComboBox.Enabled = false;
|
||||
dayComboBox.Enabled = false;
|
||||
yearComboBox.Enabled = false;
|
||||
}
|
||||
monthComboBox.SelectedIndexChanged += UpdateDaysOfMonth;
|
||||
dayComboBox.SelectedIndexChanged += UpdateDataGridViewInformation;
|
||||
yearComboBox.SelectedIndexChanged += UpdateDaysOfMonthByYear;
|
||||
DrawingControl.ResumeDrawing(dateSelectorPanel);
|
||||
}
|
||||
|
||||
private void UpdateDaysOfMonth(object sender, EventArgs e)
|
||||
{
|
||||
if (yearComboBox.SelectedIndex == -1) return;
|
||||
var year = yearComboBox.SelectedItem.ToString();
|
||||
var month = monthComboBox.SelectedItem.ToString();
|
||||
var dateParserPattern = new Regex("^" + month + @"\/\d{2}\/" + year);
|
||||
|
||||
dayComboBox.Items.Clear();
|
||||
|
||||
for (var i = 0; i < _gDateStringCollection.Count; i++)
|
||||
{
|
||||
if (dateParserPattern.IsMatch(_gDateStringCollection[i]))
|
||||
{
|
||||
var dateArray = _gDateStringCollection[i].Split('/');
|
||||
var day = dateArray[1];
|
||||
dayComboBox.Items.Add(day);
|
||||
}
|
||||
}
|
||||
|
||||
if (dayComboBox.Items.Count > 0)
|
||||
{
|
||||
dayComboBox.SelectedIndex = dayComboBox.Items.Count - 1;
|
||||
}
|
||||
|
||||
CalculateProfitAnalysis();
|
||||
CalculateGrossProfit();
|
||||
}
|
||||
/// <summary>
|
||||
/// Fires when the Year combo box's index changes.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void UpdateDaysOfMonthByYear(object sender, EventArgs e)
|
||||
{
|
||||
//Obligatory database retrieval call...
|
||||
var dbReader = new RetrieveFromDatabase();
|
||||
//First, grab the year and the month from their respective combo boxes.
|
||||
var year = yearComboBox.SelectedItem.ToString();
|
||||
var month = monthComboBox.SelectedItem.ToString();
|
||||
//Since we can more or less be certain that nothing is null, clear the current date collection.
|
||||
_gDateStringCollection.Clear();
|
||||
var months = dbReader.ReturnUniqueMonthsList(month + "/" + dayComboBox.SelectedItem + "/" + year);
|
||||
var mostRecentMonth = months.Max();
|
||||
if (mostRecentMonth.Length == 1)
|
||||
{
|
||||
mostRecentMonth = "0" + mostRecentMonth;
|
||||
}
|
||||
var selectedYearDates = dbReader.ReturnDateStringsLike(month + "/" + dayComboBox.SelectedItem + "/" + year);
|
||||
|
||||
for (var i = 0; i < selectedYearDates.Rows.Count; i++)
|
||||
{
|
||||
var trimmedDateString = (DateTime) selectedYearDates.Rows[i][0];
|
||||
_gDateStringCollection.Add(trimmedDateString.ToString("MM/dd/yyyy"));
|
||||
}
|
||||
|
||||
//Clear the month and day combo boxes and unregister their event handlers.
|
||||
dayComboBox.Items.Clear();
|
||||
monthComboBox.Items.Clear();
|
||||
monthComboBox.SelectedIndexChanged -= UpdateDaysOfMonth;
|
||||
dayComboBox.SelectedIndexChanged -= UpdateDataGridViewInformation;
|
||||
for (var i = 0; i < _gDateStringCollection.Count; i ++)
|
||||
{
|
||||
var dateArray = _gDateStringCollection[i].Split('/');
|
||||
month = dateArray[0];
|
||||
//Declare the patterns to look for when enumerating the combo boxes.
|
||||
var dayBasedOnMonthAndYeaRegex = new Regex(@"^(" + mostRecentMonth + @"\/\d{2}\/" + year + ")"); //Only allows days that are actually part of the month and year.
|
||||
var day = dateArray[1];
|
||||
|
||||
if (dayBasedOnMonthAndYeaRegex.IsMatch(_gDateStringCollection[i]))
|
||||
{
|
||||
dayComboBox.Items.Add(day);
|
||||
}
|
||||
|
||||
if (!monthComboBox.Items.Contains(month))
|
||||
{
|
||||
monthComboBox.Items.Add(month);
|
||||
}
|
||||
}
|
||||
|
||||
if (dayComboBox.Items.Count > 0)
|
||||
{
|
||||
dayComboBox.SelectedIndex = dayComboBox.Items.Count - 1;
|
||||
}
|
||||
if (monthComboBox.Items.Count > 0)
|
||||
{
|
||||
monthComboBox.SelectedIndex = monthComboBox.Items.Count - 1;
|
||||
}
|
||||
|
||||
//Now re-register the event handlers
|
||||
monthComboBox.SelectedIndexChanged += UpdateDaysOfMonth;
|
||||
dayComboBox.SelectedIndexChanged += UpdateDataGridViewInformation;
|
||||
|
||||
BuildAndFillDataGridTables(monthComboBox.SelectedItem + "/" + dayComboBox.SelectedItem + "/" + year);
|
||||
CalculateProfitAnalysis();
|
||||
CalculateGrossProfit();
|
||||
}
|
||||
|
||||
private string[] ParseAdSpecialRows(string groupIdentifier)
|
||||
{
|
||||
var groupCategory = new string[2];
|
||||
var dbReader = new RetrieveFromDatabase();
|
||||
var patternForOnlyPipeAndAdSpecial = new Regex(@"^\|\d{1}");
|
||||
var patternForBothNumbersOnPipe = new Regex(@"^\d{1}\|\d{1}");
|
||||
|
||||
if (patternForOnlyPipeAndAdSpecial.IsMatch(groupIdentifier))
|
||||
{
|
||||
groupCategory[0] = groupIdentifier;
|
||||
if (groupIdentifier[0].ToString() != "")
|
||||
{
|
||||
groupCategory[0] = groupCategory[0].Replace("|", "");
|
||||
groupCategory[0] = dbReader.ReturnGroupNameFromGroupId(groupCategory[0]);
|
||||
}
|
||||
}else if (patternForBothNumbersOnPipe.IsMatch(groupIdentifier))
|
||||
{
|
||||
string[] temp = groupIdentifier.Split('|');
|
||||
groupCategory[0] = temp[0];
|
||||
groupCategory[1] = temp[1];
|
||||
|
||||
groupCategory[1] = dbReader.ReturnGroupNameFromGroupId(groupCategory[1]);
|
||||
}
|
||||
|
||||
return groupCategory;
|
||||
}
|
||||
|
||||
private void adSpecialKeyWordsToolsMainMenu_Click(object sender, EventArgs e)
|
||||
{
|
||||
var keyWordRegister = new frmAdSpecialRegister();
|
||||
keyWordRegister.ShowDialog();
|
||||
}
|
||||
|
||||
private void deleteRecordsMainMenu_Click(object sender, EventArgs e)
|
||||
{
|
||||
var frmDeleteRecord = new frmDeleteRecord();
|
||||
frmDeleteRecord.ShowDialog();
|
||||
FillDateSuggestionComboBoxes();
|
||||
BuildAndFillDataGridTables();
|
||||
CalculateProfitAnalysis();
|
||||
CalculateGrossProfit();
|
||||
}
|
||||
}
|
||||
|
||||
//http://stackoverflow.com/questions/487661/how-do-i-suspend-painting-for-a-control-and-its-children
|
||||
class DrawingControl
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
|
||||
|
||||
private const int WM_SETREDRAW = 11;
|
||||
|
||||
public static void SuspendDrawing(Control parent)
|
||||
{
|
||||
SendMessage(parent.Handle, WM_SETREDRAW, false, 0);
|
||||
}
|
||||
|
||||
public static void ResumeDrawing(Control parent)
|
||||
{
|
||||
SendMessage(parent.Handle, WM_SETREDRAW, true, 0);
|
||||
parent.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user