using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AyaNovaQBI { public partial class MainForm : Form { public MainForm() { InitializeComponent(); //InitDataSet(); Icon = AyaNovaQBI.Properties.Resources.logo; } private async void MainForm_Load(object sender, EventArgs e) { //Initialize StringBuilder initErrors = new StringBuilder(); if (await util.InitializeQBI(initErrors) == false) { if (initErrors.Length > 0) { if (util.LOG_AVAILABLE) await util.IntegrationLog(initErrors.ToString()); await Task.Run(() => MessageBox.Show($"AyaNova QBI was unable to start:\r\n{initErrors.ToString()}")); } Close(); return; } //Confirm main settings and set any that are missing: if (await util.ValidateSettings(false) == util.pfstat.Cancel) { await util.IntegrationLog("PFC: User settings not completed, user selected cancel"); Close(); return; } Text = "AyaNova QBI - " + util.QCompanyName; //See if there are *any* data mappings, if not then we will prompt the user to start that process if (util.QBIntegration.Items.Count == 0) { //show message about mapping MessageBox.Show( "AyaNova QBI now needs you to map data between QuickBooks and AyaNova.", "Setup mapping", MessageBoxButtons.OK, MessageBoxIcon.Information); Map m = new Map(); if (m.ShowDialog() == DialogResult.Abort) Close(); } //Display billable workorders await InitInvoices(); grid.Visible = true; menuStrip1.Enabled = true; } private void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.ColumnIndex == grid.Columns["Status"].Index && e.Value != null) { var isLinked = (bool)grid.Rows[e.RowIndex].Cells["linked"].Value; if (!isLinked) { grid.Rows[e.RowIndex].ErrorText = "Not invoiceable: use \"Work orders\" -> \"Fix problems\" to resolve"; } else { grid.Rows[e.RowIndex].ErrorText = null; } } } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Close(); } private void multipleWorkordersPerInvoiceToolStripMenuItem_Click(object sender, EventArgs e) { if (grid.SelectedRows.Count < 1) { MessageBox.Show("There are no rows selected, select one or more rows to invoice"); return; } MessageBox.Show($"STUB: MULTIPLEwoperinvoice {grid.SelectedRows.Count} rows selected"); } private void oneWorkOrderPerInvoiceToolStripMenuItem_Click(object sender, EventArgs e) { if (grid.SelectedRows.Count < 1) { MessageBox.Show("There are no rows selected, select one or more rows to invoice"); return; } MessageBox.Show($"STUB: onwoperinvoice {grid.SelectedRows.Count} rows selected"); } private void fixProblemsToolStripMenuItem_Click(object sender, EventArgs e) { FixInvoiceProblems d = new FixInvoiceProblems(); d.MisMatches = _MisMatches; d.PartPriceOverrides = _PartPriceOverrides; d.ShowDialog(); if (d.ChangesMade) InitInvoices(); d.Dispose(); } private async void refreshInvoicesToolStripMenuItem_Click(object sender, EventArgs e) { await InitInvoices(); } private async void preferencesToolStripMenuItem_Click(object sender, EventArgs e) { await util.ValidateSettings(true); } private async void mapAndImportToolStripMenuItem_Click(object sender, EventArgs e) { Map m = new Map(); if (m.ShowDialog() == DialogResult.Abort) Close(); else { m.Dispose(); await InitInvoices(); } } private void aboutToolStripMenuItem_Click(object sender, EventArgs e) { Assembly a = Assembly.GetExecutingAssembly(); string sVersion = "AyaNova QBI version " + util.DisplayVersion(a.GetName().Version) + "\r\n"; System.Diagnostics.FileVersionInfo fileVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(a.Location); if (fileVersion.FileBuildPart > 0) sVersion += " (Patch " + fileVersion.FileBuildPart.ToString() + ")\r\n"; sVersion += "Copyright 2000-2022 Ground Zero Tech-Works Inc.\r\n"; MessageBox.Show(sVersion, "About"); } private void onlineManualToolStripMenuItem_Click(object sender, EventArgs e) { util.OpenWebURL("https://ayanova.com/qbi/docs"); } private async void refreshCachedDataToolStripMenuItem_Click(object sender, EventArgs e) { await util.PopulateQBListCache(); await util.PopulateAyaListCache(); } private async void invoiceDescriptiveTextTemplateToolStripMenuItem_Click(object sender, EventArgs e) { InvoiceTemplateBuilder b = new InvoiceTemplateBuilder(); b.ShowDialog(); if (util.QDat.IsDirty) await util.SaveIntegrationObject(); b.Dispose(); } #region Main workorder grid /// /// Adjusts main form display to either show a list of billable workorders /// or a status indicating there are none and why /// private async Task SetState() { fixProblemsToolStripMenuItem.Enabled = _MisMatches.Count > 0; if (grid.Rows.Count > 0) { grid.Visible = true; lblStatus.Visible = false; } else { StringBuilder sb = new StringBuilder(); sb.Append("No invoiceable work orders found in AyaNova\r\n\r\n"); sb.Append("A work order is invoiceable and will be listed here if it has:\r\n"); sb.Append(" - \"Invoice number\" field empty\r\n"); if (util.QDat.PreWOStatus != 0) { sb.Append(" - \"Work order status\" field set to: "); var r = await util.GetAsync($"work-order-status/{util.QDat.PreWOStatus}"); var status = r.ObjectResponse["data"].ToObject(); if (status != null) sb.Append(status.Name); else sb.Append("UNKNOWN / MISSING STATUS - recently deleted?"); sb.Append("\r\n"); sb.Append(" (You can change this status under Tools->Preferences in the menu)"); } else sb.Append(" - any \"Locked\" type of Work order status set\r\n"); lblStatus.Text = sb.ToString(); grid.Visible = false; lblStatus.Visible = true; } } private DataTable _GridTable = null; private List _MisMatches = new List(); private List _PartPriceOverrides = new List(); /// /// Initialize invoices dataset /// from scratch. If a previous /// initialize was done, wipe it and /// repopulate from scratch /// private async Task InitInvoices() { Waiting w = new Waiting(); w.Show(); w.Ops = "Validating invoices..."; try { if (_GridTable == null) { //datatable is required to support sorting in dgv without writing a lot of extra code _GridTable = new DataTable(); _GridTable.Columns.Add(new DataColumn("CustomerName")); _GridTable.Columns.Add(new DataColumn("Serial", typeof(long))); _GridTable.Columns.Add(new DataColumn("ServiceDate", typeof(DateTime))); _GridTable.Columns.Add(new DataColumn("WorkorderStatusName")); _GridTable.Columns.Add(new DataColumn("ProjectName")); _GridTable.Columns.Add(new DataColumn("Color")); _GridTable.Columns.Add(new DataColumn("CustomerId", typeof(long))); _GridTable.Columns.Add(new DataColumn("Id", typeof(long))); _GridTable.Columns.Add(new DataColumn("Linked", typeof(bool))); } else { _GridTable.Clear(); } _MisMatches.Clear(); //[HttpGet("accounting-list-billable/{workOrderStatusId}")] var r = await util.GetAsync($"workorder/accounting-list-billable/{util.QDat.PreWOStatus}"); var v = r.ObjectResponse["data"].ToObject>(); foreach (WorkOrderAccountingListItem z in v) { w.Step = "WO: " + z.Serial; DataRow row = _GridTable.NewRow(); row["CustomerName"] = z.CustomerName; row["Serial"] = z.Serial; row["ServiceDate"] = z.ServiceDate; row["WorkorderStatusName"] = z.WorkorderStatusName; row["ProjectName"] = z.ProjectName; row["Color"] = z.Color; row["CustomerId"] = z.CustomerId; row["Id"] = z.Id; row["Linked"]= await util.ScanLinksOK(z.Id, _MisMatches, _PartPriceOverrides); _GridTable.Rows.Add(row); } grid.DataSource = _GridTable; } finally { w.Close(); } await SetState(); } ///// ///// Helper for grouping workorders by client ///// ///// ///// null if not found else datarow containing invoice for client //private DataRow InvoiceRowForClientID(Guid ClientID) //{ // foreach (DataRow r in dsInvoices.Tables["Invoices"].Rows) // { // if ((Guid)r["ClientID"] == ClientID) // { // return r; // } // } // return null; //} //private void grid_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e) //{ // if (e.Row.Band.Index == 0) // { // //Prepare invoice row // if ((bool)e.Row.Cells["Linked"].Value == true) // { // e.Row.Cells["Client"].Appearance.Image = Util.AyaImage("OK16");//Util.Image("OK16.png"); // } // else // { // e.Row.Cells["Client"].Appearance.Image = Util.AyaImage("Cancel16");//Util.Image("Cancel16.png"); // } // } // else // { // //prepare workorder row // //if backcolor==0 that means no color was set // int nColor = (int)e.Row.Cells["StatusARGB"].Value; // if (nColor != 0) // { // e.Row.Cells["Status"].Appearance.BackColor = Color.FromArgb(nColor); // e.Row.Cells["Status"].Appearance.ForeColor = Util.InvertColor(Color.FromArgb(nColor)); // } // //flag whether billable (linked) or not // if ((bool)e.Row.Cells["Linked"].Value == true) // { // e.Row.Cells["ServiceNumber"].Appearance.Image = Util.AyaImage("OK16"); // } // else // { // e.Row.Cells["ServiceNumber"].Appearance.Image = Util.AyaImage("Cancel16"); // } // } //} #endregion }//eoc }//eons