Files
ravenqbi/AyaNovaQBI/Map.cs
2022-07-03 21:12:46 +00:00

647 lines
25 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;
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 async 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;
bool SaveIntegration = false;
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<long>();
StringBuilder selectedAyaNovaNames = new StringBuilder();
foreach (DataGridViewRow r in gridAya.SelectedRows)
{
selectedAyaNovaNames.AppendLine(r.Cells[0].Value.ToString());
selectedAyaNovaIds.Add((long)r.Cells[1].Value);
}
//#################################
//LINKING
LinkAyaObjectToQBConfirm d = new LinkAyaObjectToQBConfirm();
d.QBItem = QBItemName;
d.AyaItems = selectedAyaNovaNames.ToString();
if (d.ShowDialog() != DialogResult.OK)
return;
////ok, link away...
foreach (DataGridViewRow r in gridAya.SelectedRows)
{
string AyaName = r.Cells[0].Value.ToString();
long AyaId = (long)r.Cells[1].Value;
//Is AyaNova object already mapped?
IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == AyaId && z.AType == _Type);
if (m != null)
{
//Is it already linked to the selected qb object?
//Yes so do nothing and continue on to the next object
if (m.IntegrationItemId == QBItemId)
continue;
else
{
//No, AyaNova object was mapped elsewhere, prompt user if this is ok
if (MessageBox.Show(
$"AyaNova object: {AyaName}\r\nIs already linked to QuickBooks object: {m.IntegrationItemName}\r\nDo you really want to change the link to the QuickBooks object: {QBItemName}\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...
if (!string.IsNullOrEmpty(QBItemId))//confirm not a removal
{
m.IntegrationItemId = QBItemId;
m.IntegrationItemName = QBItemName;
m.LastSync = System.DateTime.Now;
SaveIntegration = true;
}
else
{
//user is removing mapping so remove the integrationitem entirely from the collection
var didremove=util.QBIntegration.Items.Remove(m);
SaveIntegration = true;
}
}
else
{
if (!string.IsNullOrEmpty(QBItemId))//confirm not a removal
{
//not already present, so add it, easy peasy...
m = new IntegrationItem { AType = _Type, IntegrationItemName = QBItemName, IntegrationItemId = QBItemId, LastSync = System.DateTime.Now, ObjectId = AyaId };
util.QBIntegration.Items.Add(m);
SaveIntegration = true;
}
}
}
if (SaveIntegration)
{
await util.SaveIntegrationObject();
Initialize();
}
//#################################
}
else
{
}
}
#region Initialize stuff
/// <summary>
/// Determine if row should be added to grid or now
/// based on current view preferences and if item is already
/// linked or not
/// </summary>
/// <param name="bLinked"></param>
/// <returns></returns>
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.ObjectId == 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.ObjectId == 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.ObjectId == 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.ObjectId == 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.ObjectId == 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<QBNameID> SelectedQBItems = new List<QBNameID>();
//public class AyaNameID
//{
// public string Name { get; set; }
// public long ID { get; set; }
//}
//List<AyaNameID> SelectedAyaItems = new List<AyaNameID>();
//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<InvoiceableItem> GetInvoiceableItems()
//{
// var random = new Random();
// var l = new List<InvoiceableItem>();
// 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();
//}
*/
}
}