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; namespace AyaNovaQBI { public partial class Map : Form { private AyaType _Type = AyaType.Customer; private DataTable _aya; private DataTable _qb; //private VendorTypes _currentVendorType = 0; private viewtypes _currentView = viewtypes.All; //private RateTypes _currentRateType = 0; //private long _MostLikelyRateUnitChargeDescriptionID = 0; private enum viewtypes { All, Unlinked, Linked } public Map() { InitializeComponent(); this.Icon = AyaNovaQBI.Properties.Resources.logo; _aya = new DataTable("AyaNova"); _aya.Columns.Add("name", typeof(string)); _aya.Columns.Add("id", typeof(long)); _aya.Columns.Add("linked", typeof(bool)); //Case 339 _aya.DefaultView.Sort = "name asc"; gridAya.DataSource = _aya; _qb = new DataTable("QuickBooks"); _qb.Columns.Add("name", typeof(string)); _qb.Columns.Add("id", typeof(string)); _qb.Columns.Add("linked", typeof(bool)); //Case 339 _qb.DefaultView.Sort = "name asc"; gridQB.DataSource = _qb; } private void Map_Load(object sender, EventArgs e) { Initialize(); gridAya.ClearSelection(); gridQB.ClearSelection(); } private void importSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e) { } private void linkSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e) { bool IsAyaGrid = false; if (gridAya.SelectedRows.Count == 0 && gridQB.SelectedRows.Count == 0) return; IsAyaGrid = gridAya.SelectedRows.Count > 0; if (IsAyaGrid) { //we have selection now get qb item MapSelectQBItem s = new MapSelectQBItem(); s.QBItems = _qb; if (s.ShowDialog() == DialogResult.Cancel) return; var QBItemName = s.SelectedQBItemName; var QBItemId = s.SelectedQBItemId; s.Dispose(); var selectedAyaNovaIds = new List(); StringBuilder selectedAyaNovaNames = new StringBuilder(); foreach (DataGridViewRow r in gridAya.SelectedRows) { selectedAyaNovaNames.AppendLine(r.Cells[1].Value.ToString()); selectedAyaNovaIds.Add((long)r.Cells[1].Value); } //todo: here we need to update the linking (and save right away or wait??) //################################# //LINKING LinkAyaObjectToQBConfirm d = new LinkAyaObjectToQBConfirm(); d.QBItem = QBItemName; d.AyaItems = selectedAyaNovaNames.ToString(); if (d.ShowDialog() != DialogResult.OK) return; //// //// QBNameID q=(QBNameID)moveData.Rows[0]; //// if(MessageBox.Show( //// "Link the AyaNova object(s): " + q.Name + "\r\n" + //// "to the QuickBooks object: " + + "\r\n\r\n" + //// "Are you sure?","Link QuickBooks object",MessageBoxButtons.YesNo,MessageBoxIcon.Question) //// ==DialogResult.No) return; ////ok, link away... //foreach (object o in moveData.Rows) //{ // //qb listid // string dropID = rowdrop.Cells["ID"].Value.ToString(); // string dropName = rowdrop.Cells["Name"].Value.ToString(); // IntegrationMap m = null; // //Is AyaNova object already mapped? // if (Util.QBI.Maps.Contains(((AyaNameID)o).ID)) // { // //Get the mapping // m = Util.QBI.Maps[((AyaNameID)o).ID]; // //Is it already linked to the selected qb object? // //Yes so do nothing and continue on to the next object // if (m.ForeignID == dropID) // continue; // else // { // //No, AyaNova object was mapped elsewhere, prompt user if this is ok // if (MessageBox.Show( // "AyaNova object: " + ((AyaNameID)o).Name + "\r\n" + // "Is already linked to QuickBooks object: " + m.Name + "\r\n" + // "Do you really want to change the link to the QuickBooks object: " + dropName + "\r\n", // "Change link?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) // == DialogResult.No) continue; // } // //If we're here it's because the object is already mapped // //but the users has signified they want to change the map to another object so... // m.ForeignID = dropID; // m.Name = rowdrop.Cells["Name"].Value.ToString(); // m.LastSync = System.DateTime.Now; // } // else // { // //not already present, so add it, easy peasy... // m = Util.QBI.Maps.Add(Util.QBI); // m.RootObjectID = ((AyaNameID)o).ID; // m.RootObjectType = _Type; // m.ForeignID = dropID; // m.Name = dropName; // m.LastSync = System.DateTime.Now; // } //} //Util.QBI = (Integration)Util.QBI.Save(); Initialize(); //################################# } else { } } #region Initialize stuff /// /// Determine if row should be added to grid or now /// based on current view preferences and if item is already /// linked or not /// /// /// private bool DisplayRow(bool bLinked) { switch (_currentView) { case viewtypes.All: return true; case viewtypes.Linked: return bLinked; case viewtypes.Unlinked: return !bLinked; } return true; } private void Initialize() { //clear both lists _aya.Rows.Clear(); _qb.Rows.Clear(); //Case 147 updateAyaNovaPricesToolStripMenuItem.Visible = false; switch (_Type) { case AyaType.Customer: #region client /* foreach(ClientPickList.ClientPickListInfo i in Util.AyaClientList) { if(i.Active) { bool bLinked=Util.QBI.Maps.Contains(i.ID); if(DisplayRow(bLinked)) _aya.Rows.Add(new object[] {i.ID,i.Name,bLinked}); } } //Fill QB table with QB Customers from prefetched table foreach(DataRow dr in Util.QBClients.Rows) { bool bLinked=Util.QBI.Maps.Contains(dr["ID"].ToString(),RootObjectTypes.Client); if(DisplayRow(bLinked)) _qb.Rows.Add(new object[] {dr["ID"].ToString(),dr["FullName"].ToString(),bLinked}); } */ foreach (var i in util.AyaClientList) { if (i.Active) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.Id == i.Id); if (DisplayRow(bLinked)) { var qbItem = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.Id == i.Id); if (qbItem == null) { qbItem = new IntegrationItem(); } _aya.Rows.Add(new object[] { i.Name, i.Id, bLinked }); } } } //Fill QB table foreach (DataRow dr in util.QBClients.Rows) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString()); if (DisplayRow(bLinked)) _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked }); } #endregion client break; case AyaType.Vendor: #region Vendor foreach (var i in util.AyaVendorList) { if (i.Active) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.Id == i.Id); if (DisplayRow(bLinked)) { var qbItem = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.Id == i.Id); _aya.Rows.Add(new object[] { i.Name, i.Id, bLinked }); } } } //Fill QB table foreach (DataRow dr in util.QBVendors.Rows) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString()); if (DisplayRow(bLinked)) _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked }); } #endregion Vendor break; case AyaType.ServiceRate: #region Service rates //_MostLikelyRateUnitChargeDescriptionID = 0; foreach (var i in util.AyaServiceRateList) { if (i.Active) { // //Determine the most likely description for purposes // //of importing a rate from QB later by picking the first one // //in the existing rate list that is non-empty // //typically this will just be hours and every rate will // //probably use the same one or for travel "miles" or "km's" etc // if(_MostLikelyRateUnitChargeDescriptionID==Guid.Empty && i.RateUnitChargeDescriptionID!=Guid.Empty) // _MostLikelyRateUnitChargeDescriptionID=i.RateUnitChargeDescriptionID; //After discussion we decided to not us any rate unit charge description //so leaving the code in but defaulted to guid.empty for now. bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.Id == i.Id); if (DisplayRow(bLinked)) { var qbItem = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.Id == i.Id); _aya.Rows.Add(new object[] { i.Name, i.Id, bLinked }); } } } //Fill QB table with QB items from prefetched table foreach (DataRow dr in util.QBItems.Rows) { if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Service || (util.qbitemtype)dr["Type"] == util.qbitemtype.OtherCharge) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString()); if (DisplayRow(bLinked)) _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked }); } } #endregion Rate break; case AyaType.TravelRate: #region TravelRate rates //_MostLikelyRateUnitChargeDescriptionID = 0; foreach (var i in util.AyaTravelRateList) { if (i.Active) { // //Determine the most likely description for purposes // //of importing a rate from QB later by picking the first one // //in the existing rate list that is non-empty // //typically this will just be hours and every rate will // //probably use the same one or for travel "miles" or "km's" etc // if(_MostLikelyRateUnitChargeDescriptionID==Guid.Empty && i.RateUnitChargeDescriptionID!=Guid.Empty) // _MostLikelyRateUnitChargeDescriptionID=i.RateUnitChargeDescriptionID; //After discussion we decided to not us any rate unit charge description //so leaving the code in but defaulted to guid.empty for now. bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.Id == i.Id); if (DisplayRow(bLinked)) { var qbItem = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.Id == i.Id); _aya.Rows.Add(new object[] { i.Name, i.Id, bLinked }); } } } //Fill QB table with QB items from prefetched table foreach (DataRow dr in util.QBItems.Rows) { if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Service || (util.qbitemtype)dr["Type"] == util.qbitemtype.OtherCharge) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString()); if (DisplayRow(bLinked)) _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked }); } } #endregion Rate break; case AyaType.Part: #region Service parts //case 632 //gridQB.DisplayLayout.Rows.TemplateAddRow.Hidden=true; //Case 147 updateAyaNovaPricesToolStripMenuItem.Visible = true; foreach (var i in util.AyaPartList) { if (i.Active) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.Id == i.Id); if (DisplayRow(bLinked)) { var qbItem = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.Id == i.Id); _aya.Rows.Add(new object[] { i.Name, i.Id, bLinked }); } } } //Fill QB table with QB items from prefetched table foreach (DataRow dr in util.QBItems.Rows) { if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Inventory || (util.qbitemtype)dr["Type"] == util.qbitemtype.NonInventory || (util.qbitemtype)dr["Type"] == util.qbitemtype.Assembly) { bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString()); if (DisplayRow(bLinked)) _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked }); } } #endregion Part break; } } #endregion init #region menu utility stuff private void showSubItemToolStripMenuItem_Click(object sender, EventArgs e) { // Set the current clicked item to item ToolStripMenuItem item = sender as ToolStripMenuItem; // Loop through all items in the subMenu and uncheck them but do check the clicked item foreach (ToolStripMenuItem tempItemp in showToolStripMenuItem.DropDownItems) { if (tempItemp == item) tempItemp.Checked = true; else tempItemp.Checked = false; } } private void customersToolStripMenuItem_Click(object sender, EventArgs e) { handleCheckOfObjectTypeMenuItem(sender, e); if (_Type == AyaType.Customer) return; _Type = AyaType.Customer; this.Text = "Map / Import - Customers"; Initialize(); } private void serviceRatesToolStripMenuItem_Click(object sender, EventArgs e) { handleCheckOfObjectTypeMenuItem(sender, e); if (_Type == AyaType.ServiceRate) return; _Type = AyaType.ServiceRate; this.Text = "Map / Import - Service rates"; Initialize(); } private void travelRatesToolStripMenuItem_Click(object sender, EventArgs e) { handleCheckOfObjectTypeMenuItem(sender, e); if (_Type == AyaType.TravelRate) return; _Type = AyaType.TravelRate; this.Text = "Map / Import - Travel rates"; Initialize(); } private void partsToolStripMenuItem_Click(object sender, EventArgs e) { handleCheckOfObjectTypeMenuItem(sender, e); if (_Type == AyaType.Part) return; _Type = AyaType.Part; this.Text = "Map / Import - Parts"; Initialize(); if (!util.QBIntegration.Items.Any(z => z.AType == AyaType.Vendor)) { MessageBox.Show( "If you plan on importing QuickBooks items into AyaNova parts\r\n" + "we recommend you import or link QuickBooks vendors first.\r\n\r\n" + "This will ensure items in QuickBooks with a preferred vendor\r\n" + "are imported into AyaNova as parts with their Wholesaler field \r\n" + "set in AyaNova to a matching QuickBooks vendor", "No QuickBooks vendors are linked"); } } private void vendorsToolStripMenuItem_Click(object sender, EventArgs e) { handleCheckOfObjectTypeMenuItem(sender, e); if (_Type == AyaType.Vendor) return; _Type = AyaType.Vendor; this.Text = "Map / Import - Vendors"; Initialize(); } private void handleCheckOfObjectTypeMenuItem(object sender, EventArgs e) { // Set the current clicked item to item ToolStripMenuItem item = sender as ToolStripMenuItem; // Loop through all items in the subMenu and uncheck them but do check the clicked item foreach (ToolStripMenuItem tempItemp in objectToolStripMenuItem.DropDownItems) { if (tempItemp == item) tempItemp.Checked = true; else tempItemp.Checked = false; } } //public class QBNameID //{ // public string Name { get; set; } // public string ID { get; set; } //} //List SelectedQBItems = new List(); //public class AyaNameID //{ // public string Name { get; set; } // public long ID { get; set; } //} //List SelectedAyaItems = new List(); //private bool m_dragging = false; //Rectangle dragBoxFromMouseDown; //int rowIndexFromMouseDown; //int rowIndexOfItemUnderMouseToDrop; //private void gridAya_MouseDown(object sender, MouseEventArgs e) //{ // if (e.Button != MouseButtons.Left) // return; // //Only do this if the user is positioned over a row // rowIndexFromMouseDown = gridAya.HitTest(e.X, e.Y).RowIndex; // if ((rowIndexFromMouseDown != -1)) // { // SelectedAyaItems.Clear(); // if (gridAya.SelectedRows.Count > 0 && !gridAya.SelectedRows[0].IsNewRow) // { // foreach (DataGridViewRow r in gridAya.SelectedRows) // { // SelectedAyaItems.Add(new AyaNameID { Name = (string)r.Cells[0].Value, ID = (long)r.Cells[1].Value }); // } // //Size dragSize = SystemInformation.DragSize; // //dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize); // m_dragging = true; // } // } // else // { // // dragBoxFromMouseDown = Rectangle.Empty; // } //} #endregion menu utility stuff private void gridAya_CellClick(object sender, DataGridViewCellEventArgs e) { } private void gridQB_CellClick(object sender, DataGridViewCellEventArgs e) { } private void gridQB_SelectionChanged(object sender, EventArgs e) { var hasSelection = gridQB.SelectedRows.Count > 0; if (hasSelection) gridAya.ClearSelection(); } private void gridAya_SelectionChanged(object sender, EventArgs e) { var hasSelection = gridAya.SelectedRows.Count > 0; if (hasSelection) gridQB.ClearSelection(); } /* * Simplified, no drag and drop just pick and choose with clicks * A menu to select the ayanova object type which then populates the ayanova items grid of that type showing: A single grid showing all ayanova items of the selected type with their name in the first column and a second column showing what they are mapped to in qb item name, easy peasy, no drag and drop User can select one or more items when one or more are selected a menu item appears saying "MAP Selected items" when they select they can pick a qb item of the type they want and accept in a popup dialog which also shows how many ayanova items are selected a menyu tiem apepars saying UNMAP selected items when they select it it removes the mapping after confirmation dialog from all selected items //public static List GetInvoiceableItems() //{ // var random = new Random(); // var l = new List(); // for (int i = 1; i < random.Next(25, 100); i++) // l.Add(new InvoiceableItem { Customer = $"Customer {random.Next(1, 5)}", Linked = random.Next(2) == 1, Project = $"project {i}", ServiceDate = DateTime.Now.ToString("g"), ServiceNumber = (40 + i).ToString(), Status = $"Waiting to be invoiced", StatusColor = "FF00FFAA", WorkorderId = 4 }); // return l.OrderBy(x => x.Customer) // .ThenBy(x => x.ServiceNumber) // .ThenBy(x => x.ServiceDate) // .ToList(); //} */ } }