mirror of
https://github.com/stokebob/BealeEngineering.git
synced 2026-03-21 07:37:16 +00:00
535 lines
21 KiB
C#
535 lines
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using System.Configuration;
|
|
using BealeEngineering.Core.Data;
|
|
|
|
namespace BealeEngineering.Accounts
|
|
{
|
|
public partial class frmMain : Form
|
|
{
|
|
private string sqlConnectionString;
|
|
private bool isDirtyInvoiceAllocation = true;
|
|
private bool isDirtySaleInvoice = true;
|
|
private bool isDirtyClientPo = true;
|
|
private bool isDirtyProjectWork = true;
|
|
|
|
Core.Logic.Sale.SaleInvoiceAssign assignInvoice;
|
|
|
|
public frmMain()
|
|
{
|
|
InitializeComponent();
|
|
sqlConnectionString = ConfigurationManager.ConnectionStrings["BealeEngSQLDb"].ToString();
|
|
assignInvoice = new Core.Logic.Sale.SaleInvoiceAssign(sqlConnectionString);
|
|
UpdateInvoiceImportText();
|
|
}
|
|
|
|
public List<string> TableData { get; set; }
|
|
|
|
private void Form1_Load(object sender, EventArgs e)
|
|
{
|
|
RefreshTabInvoiceAllocation();
|
|
}
|
|
|
|
private void TabSetAllIsDirty()
|
|
{
|
|
isDirtyInvoiceAllocation = true;
|
|
isDirtySaleInvoice = true;
|
|
isDirtyClientPo = true;
|
|
isDirtyProjectWork = true;
|
|
|
|
tabControl1_SelectedIndexChanged(null, null);
|
|
}
|
|
|
|
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (tabControl1.SelectedTab == tabControl1.TabPages["tabClientPoAllocation"] && isDirtyInvoiceAllocation)
|
|
{
|
|
RefreshTabInvoiceAllocation();
|
|
}
|
|
else if (tabControl1.SelectedTab == tabControl1.TabPages["tabSaleInvoice"] && isDirtySaleInvoice)
|
|
{
|
|
btnRefreshSaleInvoice_Click(null, null);
|
|
}
|
|
else if (tabControl1.SelectedTab == tabControl1.TabPages["tabClientPo"] && isDirtyClientPo)
|
|
{
|
|
btnRefreshClientPo_Click(null, null);
|
|
}
|
|
else if (tabControl1.SelectedTab == tabControl1.TabPages["tabProjectWork"] && isDirtyProjectWork)
|
|
{
|
|
btnRefreshProjectWork_Click(null, null);
|
|
}
|
|
}
|
|
|
|
private void RefreshTabInvoiceAllocation()
|
|
{
|
|
btnRefreshInvAllocation_Click(null, null);
|
|
UpdateInvoiceCombo();
|
|
UpdateInvoiceImportText();
|
|
isDirtyInvoiceAllocation = false;
|
|
}
|
|
|
|
private void cmbInvoicePick_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
var invoiceHeader = (Core.Model.Sale.InvoiceHeader)cmbInvoicePick.SelectedItem;
|
|
if (invoiceHeader != null)
|
|
{
|
|
cmbInvoicePick.Enabled = true;
|
|
txtInvoiceContact.Text = invoiceHeader.ContactName;
|
|
txtInvoiceNetAmount.Text = (invoiceHeader.InvoiceTotal - invoiceHeader.TaxTotal).ToString("F") + " " + invoiceHeader.CurrencyCode;
|
|
txtInvoiceStatus.Text = invoiceHeader.Status;
|
|
}
|
|
else
|
|
{
|
|
cmbInvoicePick.Enabled = false;
|
|
txtInvoiceContact.Text = "";
|
|
txtInvoiceNetAmount.Text = "";
|
|
txtInvoiceStatus.Text = "";
|
|
}
|
|
}
|
|
|
|
private void UpdateInvoiceCombo()
|
|
{
|
|
var idList = new Core.Data.Database.Client.ReadSaleInvoiceAllocation(sqlConnectionString).GetUnallocatedInvoice();
|
|
var readInvoice = new Core.Data.Database.Sale.ReadInvoiceHeader(sqlConnectionString);
|
|
readInvoice.InvoiceNumber = idList;
|
|
|
|
var invoiceHeaderList = readInvoice.Read();
|
|
cmbInvoicePick.DataSource =
|
|
invoiceHeaderList.Where(x => x.Status != "Paid")
|
|
.OrderBy(x => x.SaleInvoiceNumber
|
|
.Substring(x.SaleInvoiceNumber.IndexOf("#") + 1, x.SaleInvoiceNumber.Length - x.SaleInvoiceNumber.IndexOf("#") - 1))
|
|
.ToList();
|
|
|
|
cmbInvoicePick_SelectedIndexChanged(null, null);
|
|
}
|
|
|
|
private void btnOpenInvoice_Click(object sender, EventArgs e)
|
|
{
|
|
int invoiceId = (int)cmbInvoicePick.SelectedValue;
|
|
|
|
var currentSaleInvoice = new Core.Data.Database.Sale.ReadInvoice(sqlConnectionString).BySaleInvoiceId(invoiceId);
|
|
|
|
|
|
var frmInvoice = new frmSaleInvoice(currentSaleInvoice);
|
|
frmInvoice.ShowDialog();
|
|
}
|
|
|
|
private void btnRefreshInvAllocation_Click(object sender, EventArgs e)
|
|
{
|
|
var readData = new Core.Data.Database.Client.ReadPurchaseOrderAllocation(sqlConnectionString);
|
|
var data = readData.Read();
|
|
|
|
purchaseOrderAllocationBindingSource.DataSource = data.OrderBy(x => x.WorkNumber).ThenBy(x => x.PurchaseOrderDate);
|
|
|
|
// high light over invoiced lines
|
|
int facilityIndex = dataGridView1.Columns["PurchaseOrderLineFacility"].Index;
|
|
int lineAmountIndex = dataGridView1.Columns["PurchaseOrderLineNetAmount"].Index;
|
|
for (var i = 0; i < dataGridView1.Rows.Count; i++)
|
|
{
|
|
decimal facility = (decimal)dataGridView1[facilityIndex, i].Value;
|
|
decimal lineAmount = (decimal)dataGridView1[lineAmountIndex, i].Value;
|
|
if (facility == 0)
|
|
{
|
|
// code to grey out line
|
|
dataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Gray;
|
|
dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
else if (facility == lineAmount)
|
|
{
|
|
// code to green
|
|
dataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Green;
|
|
dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
else if (facility < 0)
|
|
{
|
|
// red line
|
|
dataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Red;
|
|
dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
else
|
|
{
|
|
// default
|
|
dataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Black;
|
|
dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.White;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
btnOpenPurchaseOrder_Click(null, null);
|
|
}
|
|
|
|
private void label1_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void splitContainer3_Panel2_Paint(object sender, PaintEventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void testItToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var inst = new Core.Test.Autoexec(sqlConnectionString);
|
|
}
|
|
|
|
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void txtUnallocatedCount_TextChanged(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void xeroInvoiceToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
string fileInputPath = null;
|
|
|
|
using (OpenFileDialog openFileDialog = new OpenFileDialog())
|
|
{
|
|
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\Downloads";
|
|
openFileDialog.Filter = ".csv files (*.csv)|*.csv|All files (*.*)|*.*";
|
|
openFileDialog.FilterIndex = 1;
|
|
openFileDialog.RestoreDirectory = true;
|
|
|
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
//Get the path of specified file
|
|
fileInputPath = openFileDialog.FileName;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (fileInputPath != null)
|
|
{
|
|
var importXeroInvoice = new BealeEngineering.Core.Logic.Import.XeroInvoiceFlatFile(sqlConnectionString);
|
|
try
|
|
{
|
|
Cursor.Current = Cursors.WaitCursor;
|
|
importXeroInvoice.ByFilePath(fileInputPath);
|
|
}
|
|
finally
|
|
{
|
|
Cursor.Current = Cursors.Default;
|
|
}
|
|
|
|
string dialogText = "Import complete." + Environment.NewLine + Environment.NewLine
|
|
+ importXeroInvoice.InvoicesProcessed + " invoice(s) found" + Environment.NewLine
|
|
+ importXeroInvoice.InvoicesCreated + " invoice(s) created" + Environment.NewLine
|
|
+ importXeroInvoice.InvoicesUpdated + " invoice(s) updated" + Environment.NewLine
|
|
+ importXeroInvoice.InvoicesSkipped + " invoice(s) skipped" + Environment.NewLine;
|
|
|
|
MessageBox.Show(dialogText);
|
|
}
|
|
UpdateInvoiceImportText();
|
|
TabSetAllIsDirty();
|
|
}
|
|
|
|
private void xeroInvoiceToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
{
|
|
string filePath =
|
|
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
|
|
+ @"\Dropbox\Beale Engineering Services Ltd\BE Accounts\Xero-Export-Invoices.csv";
|
|
|
|
string dialogText = "Exporting all sales invoices to location: " + Environment.NewLine + Environment.NewLine + filePath;
|
|
|
|
DialogResult dialogResult = MessageBox.Show(dialogText, "Export Xero Invoice flat-file", MessageBoxButtons.OKCancel);
|
|
if (dialogResult == DialogResult.OK)
|
|
{
|
|
var exportXeroInvoice = new BealeEngineering.Core.Logic.Export.ExcelInvoiceFlatFile(sqlConnectionString);
|
|
exportXeroInvoice.FileOutputPath = filePath;
|
|
exportXeroInvoice.Execute();
|
|
|
|
dialogText = "Export complete." + Environment.NewLine + Environment.NewLine
|
|
+ exportXeroInvoice.InvoicesExported + " invoice(s) exported" + Environment.NewLine;
|
|
|
|
MessageBox.Show(dialogText);
|
|
}
|
|
}
|
|
|
|
private void btnAutoMatch_Click(object sender, EventArgs e)
|
|
{
|
|
string dialogText = "Autoallocate unmatched invoices to purchase order lines?";
|
|
|
|
DialogResult dialogResult = MessageBox.Show(dialogText, "Auto allocate", MessageBoxButtons.OKCancel);
|
|
if (dialogResult == DialogResult.OK)
|
|
{
|
|
var autoMatch = new Core.Logic.Client.PurchaseOrderAutoAllocate(sqlConnectionString);
|
|
autoMatch.Execute();
|
|
|
|
dialogText = "Operation complete." + Environment.NewLine + Environment.NewLine
|
|
+ autoMatch.InvoiceMatched + " invoice(s) matched" + Environment.NewLine
|
|
+ autoMatch.InvoiceUnmatched + " invoice(s) unmatched" + Environment.NewLine
|
|
+ autoMatch.InvoiceProcessed + " invoice(s) processed" + Environment.NewLine;
|
|
|
|
MessageBox.Show(dialogText);
|
|
}
|
|
btnRefreshInvAllocation_Click(null, null);
|
|
}
|
|
|
|
private void purchaseOrderAllocationBindingSource_CurrentChanged(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void btnAddPurchaseOrder_Click(object sender, EventArgs e)
|
|
{
|
|
var frmCLient = new frmClientPurchaseOrder(sqlConnectionString, null);
|
|
frmCLient.ShowDialog();
|
|
}
|
|
|
|
private Core.Model.Client.PurchaseOrder GetSelectPurchaseOrder()
|
|
{
|
|
int idIndex = dataGridView1.Columns["PurchaseOrderLineID"].Index;
|
|
int lineId = (int)dataGridView1[idIndex, dataGridView1.CurrentCell.RowIndex].Value;
|
|
return new Core.Data.Database.Client.ReadPurchaseOrder(sqlConnectionString).ByPurchaseOrderLineId(lineId);
|
|
}
|
|
|
|
private void btnOpenPurchaseOrder_Click(object sender, EventArgs e)
|
|
{
|
|
var frmPo = new frmClientPurchaseOrder(sqlConnectionString, GetSelectPurchaseOrder());
|
|
frmPo.ShowDialog();
|
|
btnRefreshInvAllocation_Click(null, null);
|
|
}
|
|
|
|
private void dataGridView2_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
|
|
{
|
|
int inx1 = dataGridView2.Columns["invoiceTotal"].Index;
|
|
int inx2 = dataGridView2.Columns["currencyCode"].Index;
|
|
|
|
if (e.ColumnIndex == dataGridView2.Columns["TotalAndCurrency"].Index)
|
|
{
|
|
decimal sssss = (decimal)dataGridView2[inx1, e.RowIndex].Value;
|
|
e.Value = sssss.ToString("F") + " " + dataGridView2[inx2, e.RowIndex].Value;
|
|
}
|
|
}
|
|
|
|
private void btnRefreshSaleInvoice_Click(object sender, EventArgs e)
|
|
{
|
|
var invoiceRead = new Core.Data.Database.Sale.ReadInvoiceHeader(sqlConnectionString);
|
|
var invoiceData = invoiceRead.Read();
|
|
|
|
bindingSourceSaleInvoice.DataSource =
|
|
invoiceData.OrderByDescending(x => x.SaleInvoiceNumber
|
|
.Substring(x.SaleInvoiceNumber.IndexOf("#") + 1, x.SaleInvoiceNumber.Length - x.SaleInvoiceNumber.IndexOf("#") - 1));
|
|
|
|
isDirtySaleInvoice = false;
|
|
}
|
|
|
|
private void btnAssign_Click(object sender, EventArgs e)
|
|
{
|
|
// invoice import time check
|
|
if (!assignInvoice.ImportTimeCheck())
|
|
{
|
|
var responce = MessageBox.Show("Last Xero invoice import was " + assignInvoice.LastImportDateTime
|
|
+ Environment.NewLine + Environment.NewLine + "Continue?"
|
|
, "Caution"
|
|
, MessageBoxButtons.OKCancel
|
|
, MessageBoxIcon.Exclamation
|
|
, MessageBoxDefaultButton.Button2);
|
|
|
|
if (responce == DialogResult.OK)
|
|
{
|
|
assignInvoice.ImportTimeCheckPostpone();
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
var invoiceHeader = (Core.Model.Sale.InvoiceHeader)cmbInvoicePick.SelectedItem;
|
|
var purchaseOrder = GetSelectPurchaseOrder();
|
|
|
|
if (invoiceHeader.ContactName != purchaseOrder.ContactName)
|
|
{
|
|
var responce = MessageBox.Show("Client on invoice '" + invoiceHeader.ContactName
|
|
+ "' does not match client on purchase order '" + purchaseOrder.ContactName + "'."
|
|
+ Environment.NewLine + Environment.NewLine + "Continue?"
|
|
, "Warning"
|
|
, MessageBoxButtons.OKCancel
|
|
, MessageBoxIcon.Warning
|
|
, MessageBoxDefaultButton.Button2);
|
|
if (responce != DialogResult.OK)
|
|
{ return; }
|
|
}
|
|
|
|
int idIndex = dataGridView1.Columns["PurchaseOrderLineFacility"].Index;
|
|
decimal facility = (decimal)dataGridView1[idIndex, dataGridView1.CurrentCell.RowIndex].Value;
|
|
decimal invoiceNet = invoiceHeader.InvoiceTotal - invoiceHeader.TaxTotal;
|
|
if (facility < invoiceNet)
|
|
{
|
|
var responce = MessageBox.Show("The facility on the select purchase order line (" + facility.ToString("F") + ") is less than the "
|
|
+ "invoice amount (" + invoiceNet.ToString("F") + "). "
|
|
+ Environment.NewLine + Environment.NewLine + "Continue and split the invoice?"
|
|
, "Insurficent facility"
|
|
, MessageBoxButtons.OKCancel
|
|
, MessageBoxIcon.Question
|
|
, MessageBoxDefaultButton.Button2);
|
|
|
|
if (responce != DialogResult.OK)
|
|
{ return; }
|
|
|
|
assignInvoice.SplitInvoice = true;
|
|
}
|
|
|
|
int lineIdIndex = dataGridView1.Columns["PurchaseOrderLineID"].Index;
|
|
int lineId = (int)dataGridView1[lineIdIndex, dataGridView1.CurrentCell.RowIndex].Value;
|
|
try
|
|
{
|
|
Cursor.Current = Cursors.WaitCursor;
|
|
assignInvoice.ToPurchaseOrderLine(invoiceHeader.SaleInvoiceNumber, lineId);
|
|
}
|
|
finally
|
|
{
|
|
Cursor.Current = Cursors.Default;
|
|
}
|
|
|
|
TabSetAllIsDirty();
|
|
}
|
|
|
|
private void UpdateInvoiceImportText()
|
|
{
|
|
txtInvoiceImportDt.Text = new Core.Data.Database.Log.ReadDateTime(sqlConnectionString)
|
|
.ByMatchString("XeroSaleInvoiceFlatFileImport").ToString();
|
|
}
|
|
|
|
private void btnOpenInv_Click(object sender, EventArgs e)
|
|
{
|
|
if (dataGridView2.Rows.Count > 0)
|
|
{
|
|
int invoiceId = (int)dataGridView2.Rows[dataGridView2.CurrentRow.Index].Cells[0].Value;
|
|
|
|
var currentSaleInvoice = new Core.Data.Database.Sale.ReadInvoice(sqlConnectionString).BySaleInvoiceId(invoiceId);
|
|
|
|
var frmInvoice = new frmSaleInvoice(currentSaleInvoice);
|
|
frmInvoice.ShowDialog();
|
|
}
|
|
|
|
isDirtySaleInvoice = true;
|
|
tabControl1_SelectedIndexChanged(null, null);
|
|
}
|
|
|
|
private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void dataGridView2_DoubleClick(object sender, EventArgs e)
|
|
{
|
|
btnOpenInv_Click(null, null);
|
|
}
|
|
|
|
private void btnRefreshClientPo_Click(object sender, EventArgs e)
|
|
{
|
|
var poRead = new Core.Data.Database.Client.ReadPurchaseOrderHeader(sqlConnectionString);
|
|
var poData = poRead.Read();
|
|
|
|
purchaseOrderBindingSource.DataSource=
|
|
poData.OrderByDescending(x => x.PurchaseOrderDate);
|
|
|
|
isDirtyClientPo = false;
|
|
}
|
|
|
|
private void btnOpenPo(object sender, EventArgs e)
|
|
{
|
|
int poId = (int)dataGridView3.Rows[dataGridView3.CurrentRow.Index].Cells[0].Value;
|
|
var po = new Core.Data.Database.Client.ReadPurchaseOrder(sqlConnectionString).ByPurchaseOrderId(poId);
|
|
|
|
var frmPo = new frmClientPurchaseOrder(sqlConnectionString, po);
|
|
frmPo.ShowDialog();
|
|
btnRefreshClientPo_Click(null, null);
|
|
|
|
isDirtyClientPo = true;
|
|
tabControl1_SelectedIndexChanged(null, null);
|
|
}
|
|
|
|
private void btnAddPurchaseOrder_Click_1(object sender, EventArgs e)
|
|
{
|
|
var frmPo = new frmClientPurchaseOrder(sqlConnectionString, null);
|
|
frmPo.ShowDialog();
|
|
|
|
isDirtyClientPo = true;
|
|
tabControl1_SelectedIndexChanged(null, null);
|
|
}
|
|
|
|
private void btnRefreshProjectWork_Click(object sender, EventArgs e)
|
|
{
|
|
dataGridView4.DataSource = new Core.Data.Database.Project.ReadProjectWorkItem(sqlConnectionString).Read();
|
|
|
|
isDirtyProjectWork = false;
|
|
}
|
|
|
|
private void xeroNewInvoiceToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
string newStatus = new Core.Data.SaleInvoiceFormat().ReadStatusStringNew();
|
|
string fileInputPath = null;
|
|
|
|
using (SaveFileDialog openFileDialog = new SaveFileDialog())
|
|
{
|
|
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\Downloads";
|
|
openFileDialog.FileName = "Xero-" + newStatus + "-Invoices.csv";
|
|
openFileDialog.Filter = ".csv files (*.csv)|*.csv|All files (*.*)|*.*";
|
|
openFileDialog.FilterIndex = 1;
|
|
openFileDialog.RestoreDirectory = true;
|
|
|
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
//Get the path of specified file
|
|
fileInputPath = openFileDialog.FileName;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (fileInputPath != null)
|
|
{
|
|
var exportXeroInvoice = new BealeEngineering.Core.Logic.Export.XeroInvoiceFlatFile(sqlConnectionString);
|
|
try
|
|
{
|
|
Cursor.Current = Cursors.WaitCursor;
|
|
exportXeroInvoice.FileOutputPath = fileInputPath;
|
|
exportXeroInvoice.Execute();
|
|
}
|
|
finally
|
|
{
|
|
Cursor.Current = Cursors.Default;
|
|
}
|
|
|
|
MessageBox.Show("Complete. " + exportXeroInvoice.InvoicesExported + " invoice(s) exported.");
|
|
}
|
|
}
|
|
|
|
private void button5_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void button4_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|