using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Windows.Forms; using static AyaNovaQBI.util; namespace AyaNovaQBI { public partial class FixInvoiceProblems : Form { public List MisMatches { get; set; } public List PartPriceOverrides { get; set; } public bool ChangesMade { get; set; } = false; public FixInvoiceProblems() { InitializeComponent(); } private void FixInvoiceProblems_Load(object sender, EventArgs e) { BindDataSource(); btnOK.Text = util.AyaTranslations["OK"]; } private void BindDataSource() { var bindingList = new BindingList(MisMatches); var source = new BindingSource(bindingList, null); grid.DataSource = source; } private void btnOK_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; Close(); } private async void grid_CellContentClick(object sender, DataGridViewCellEventArgs e) { var senderGrid = (DataGridView)sender; if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn) { var mm = MisMatches[e.RowIndex];//grid event index is same row as collection index so this saves hassles with rows and accessors switch (mm.Reason) { case util.MisMatchReason.NothingToInvoice: MessageBox.Show("Nothing to invoice"); break; case util.MisMatchReason.PriceDifferent: { try { #region price problem FixPriceDifference d = new FixPriceDifference(); d.OptionTitle = mm.Name + "\r\n" + "Price on work order: " + mm.AyaPrice.ToString("c") + "\r\n" + "Price in QuickBooks: " + mm.QBPrice.ToString("c"); if (d.ShowDialog() == DialogResult.Cancel) return; //Fixup price here switch (d.SelectedResolution) { case "AYAONCE": //Add to price override list so price on workorder item part record is used PartPriceOverrides.Add(mm.WorkOrderItemPartId); break; case "QBONCE": { //Change the workorder item part price only //to the quickbooks price, don't touch the default aya part price var a = await util.GetAsync($"workorder/{mm.WorkOrderId}"); WorkOrder w = a.ObjectResponse["data"].ToObject(); if (w == null) throw new Exception($"FixInvoiceProblems:QBONCE:PRICE: WorkOrder with id {mm.WorkOrderId} was not found in AyaNova and may have just been deleted.\r\nUnable to update wo."); var wip = w.Items.First(z => z.Id == mm.WorkOrderItemId).Parts.First(z => z.Id == mm.WorkOrderItemPartId); wip.PriceOverride = mm.QBPrice; await PutAsync("workorder/items/parts", Newtonsoft.Json.JsonConvert.SerializeObject(wip)); } break; case "CHANGEAYA": { //Change this workorder item parts price to the qb price //and change ayanova's default price for this part to the qb price var a = await util.GetAsync($"workorder/{mm.WorkOrderId}"); WorkOrder w = a.ObjectResponse["data"].ToObject(); if (w == null) throw new Exception($"FixInvoiceProblems:CHANGEAYA:PRICE: WorkOrder with id {mm.WorkOrderId} was not found in AyaNova and may have just been deleted.\r\nUnable to update wo."); var wip = w.Items.First(z => z.Id == mm.WorkOrderItemId).Parts.First(z => z.Id == mm.WorkOrderItemPartId); long PartId = wip.PartId; wip.PriceOverride = mm.QBPrice; await PutAsync("workorder/items/parts", Newtonsoft.Json.JsonConvert.SerializeObject(wip)); if (PartId != 0) { var partResponse = await util.GetAsync($"part/{PartId}"); Part p = partResponse.ObjectResponse["data"].ToObject(); if (w == null) throw new Exception($"FixInvoiceProblems:CHANGEAYA:PRICE: Part with id {PartId} was not found in AyaNova and may have just been deleted.\r\nUnable to update Part."); p.Retail = mm.QBPrice; await util.PostAsync("part", Newtonsoft.Json.JsonConvert.SerializeObject(p)); } } break; case "CHANGEQB": //Change the QB price to use the price on this workorder item part await util.ChangeQBItemPrice(mm.QBListID, mm.AyaPrice); break; } //remove the object from the grid as it's now dealt with MisMatches.RemoveAt(e.RowIndex); ChangesMade = true; //If all done then close up if (MisMatches.Count == 0) Close(); } catch (Exception ex) { await util.CrackDisplayAndIntegrationLogException(ex, "FixInvoiceProblems:PRICE"); } #endregion price prob. } break; case util.MisMatchReason.NotLinkedToQB: { #region link problem LinkOrImportAyaObject d = new LinkOrImportAyaObject(); try { // d.AyaItem = e.Cell.Row.Cells["Name"].Value.ToString(); d.AyaItemName = mm.Name; //Default for an import //otherwise in a link is just reset to the qb item name selected string QBItemName = mm.Name; //Attempt a link or import //in any case of failure or new link not required //bails inside switch switch (mm.ObjectType) { case AyaType.Customer: d.CanImport = true; d.QBItems = util.QBClients; if (d.ShowDialog() == DialogResult.Cancel) return; if (d.Choice == "IMPORT") { ArrayList alErrors = new ArrayList(); await util.ImportAyaCustomer(mm.ObjectId, alErrors); //display errors if any if (alErrors.Count != 0) { StringBuilder sb = new StringBuilder(); sb.Append("Import failed with error:\r\n\r\n"); foreach (object o in alErrors) { sb.Append((string)o); sb.Append("\r\n************\r\n"); } CopyableMessageBox cb = new CopyableMessageBox(sb.ToString()); cb.ShowDialog(); cb.Dispose(); return; } else goto REMOVEITEMS; } else { //it's a link by default if (string.IsNullOrWhiteSpace(d.SelectedQBItemId) || !util.QBClients.Rows.Contains(d.SelectedQBItemId)) return; QBItemName = d.SelectedQBItemName; } break; case AyaType.ServiceRate: d.CanImport = false; d.QBItems = util.QBItems; if (d.ShowDialog() == DialogResult.Cancel) return; if (string.IsNullOrWhiteSpace(d.SelectedQBItemId) || !util.QBItems.Rows.Contains(d.SelectedQBItemId)) return; QBItemName = d.SelectedQBItemName; break; case AyaType.TravelRate://ADDED DUPE OF ABOVE d.CanImport = false; d.QBItems = util.QBItems; if (d.ShowDialog() == DialogResult.Cancel) return; if (string.IsNullOrWhiteSpace(d.SelectedQBItemId) || !util.QBItems.Rows.Contains(d.SelectedQBItemId)) return; QBItemName = d.SelectedQBItemName; break; case AyaType.Part: d.CanImport = false; d.QBItems = util.QBItems; if (d.ShowDialog() == DialogResult.Cancel) return; if (string.IsNullOrWhiteSpace(d.SelectedQBItemId) || !util.QBItems.Rows.Contains(d.SelectedQBItemId)) return; QBItemName = d.SelectedQBItemName; break; case AyaType.WorkOrderItemOutsideService: d.CanImport = false; d.QBItems = util.QBItems; if (d.ShowDialog() == DialogResult.Cancel) return; if (string.IsNullOrWhiteSpace(d.SelectedQBItemId) || !util.QBItems.Rows.Contains(d.SelectedQBItemId)) return; util.QDat.OutsideServiceChargeAs = d.SelectedQBItemId; await util.SaveIntegrationObject(); goto REMOVEITEMS; case AyaType.WorkOrderItemLoan: d.CanImport = false; d.QBItems = util.QBItems; if (d.ShowDialog() == DialogResult.Cancel) return; if (string.IsNullOrWhiteSpace(d.SelectedQBItemId) || !util.QBItems.Rows.Contains(d.SelectedQBItemId)) return; util.QDat.WorkorderItemLoanChargeAs = d.SelectedQBItemId; await util.SaveIntegrationObject(); goto REMOVEITEMS; case AyaType.WorkOrderItemExpense: d.CanImport = false; d.QBItems = util.QBItems; if (d.ShowDialog() == DialogResult.Cancel) return; if (string.IsNullOrWhiteSpace(d.SelectedQBItemId) || !util.QBItems.Rows.Contains(d.SelectedQBItemId)) return; util.QDat.MiscExpenseChargeAs = d.SelectedQBItemId; await util.SaveIntegrationObject(); goto REMOVEITEMS; } //add the new link util.QBIntegration.Items.Add(new IntegrationItem { AType = mm.ObjectType, IntegrationItemName = QBItemName, IntegrationItemId = d.SelectedQBItemId, LastSync = DateTime.Now, ObjectId = mm.ObjectId }); await util.SaveIntegrationObject(); REMOVEITEMS: //remove the object from the grid as it's now dealt with // grid.Rows.RemoveAt(e.RowIndex); //grid.DataSource = typeof(List); MisMatches.RemoveAt(e.RowIndex); BindDataSource(); ChangesMade = true; //If all done then close up if (MisMatches.Count == 0) Close(); } catch (Exception ex) { await util.CrackDisplayAndIntegrationLogException(ex, "FixInvoiceProblems:NOTLINKED"); } finally { d.Dispose(); } #endregion link problem } break; } } }//eof }//eoc }//eons