diff --git a/AyaNovaQBI/AyaNovaQBI.csproj b/AyaNovaQBI/AyaNovaQBI.csproj index 6eabd9d..46d4f11 100644 --- a/AyaNovaQBI/AyaNovaQBI.csproj +++ b/AyaNovaQBI/AyaNovaQBI.csproj @@ -91,6 +91,7 @@ CopyableMessageBox.cs + Form @@ -126,9 +127,11 @@ + + Form @@ -196,8 +199,10 @@ tfa.cs + + Form diff --git a/AyaNovaQBI/Customer.cs b/AyaNovaQBI/Customer.cs new file mode 100644 index 0000000..9f22d6b --- /dev/null +++ b/AyaNovaQBI/Customer.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AyaNovaQBI +{ + public class Customer + { + public long Id { get; set; } + public uint Concurrency { get; set; } + + + public string Name { get; set; } + public bool Active { get; set; } + public string Notes { get; set; } + public string Wiki { get; set; } + public string CustomFields { get; set; } + public List Tags { get; set; } + + + public string WebAddress { get; set; } + public string AlertNotes { get; set; } + public bool BillHeadOffice { get; set; } + public long? HeadOfficeId { get; set; } + + public string HeadOfficeViz { get; set; } + public string TechNotes { get; set; } + public string AccountNumber { get; set; } + //public bool UsesBanking { get; set; } + public long? ContractId { get; set; } + + public string ContractViz { get; set; } + public DateTime? ContractExpires { get; set; } + + public long? LastWorkOrderViz { get; set; } + + public DateTime? LastServiceDateViz { get; set; } + public string Phone1 { get; set; } + public string Phone2 { get; set; } + public string Phone3 { get; set; } + public string Phone4 { get; set; } + public string Phone5 { get; set; } + public string EmailAddress { get; set; } + + //POSTAL ADDRESS + public string PostAddress { get; set; } + public string PostCity { get; set; } + public string PostRegion { get; set; } + public string PostCountry { get; set; } + public string PostCode { get; set; } + + //PHYSICAL ADDRESS + public string Address { get; set; } + public string City { get; set; } + public string Region { get; set; } + public string Country { get; set; } + public decimal? Latitude { get; set; } + public decimal? Longitude { get; set; } + + + public Customer() + { + Tags = new List(); + BillHeadOffice = false; + //UsesBanking = false; + } + + + }//eoc +} diff --git a/AyaNovaQBI/Part.cs b/AyaNovaQBI/Part.cs new file mode 100644 index 0000000..85a559e --- /dev/null +++ b/AyaNovaQBI/Part.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AyaNovaQBI +{ + public class Part + { + public long Id { get; set; } + public uint Concurrency { get; set; } + public string Name { get; set; }//was partnumber in v7 + public bool Active { get; set; } + public string Description { get; set; }//was "name" in v7 + public string Notes { get; set; } + public string Wiki { get; set; } + public string CustomFields { get; set; } + public List Tags { get; set; } + + + public long? ManufacturerId { get; set; } + public string ManufacturerViz { get; set; } + public string ManufacturerNumber { get; set; } + public long? WholeSalerId { get; set; } + public string WholeSalerViz { get; set; } + public string WholeSalerNumber { get; set; } + public long? AlternativeWholeSalerId { get; set; } + public string AlternativeWholeSalerViz { get; set; } + public string AlternativeWholeSalerNumber { get; set; } + public decimal Cost { get; set; } + public decimal Retail { get; set; } + public string UnitOfMeasure { get; set; } + public string UPC { get; set; } + public string PartSerialsViz { get; set; } + + + public Part() + { + Tags = new List(); + Active = true; + Cost = 0m; + Retail = 0m; + } + + + + }//eoc +} diff --git a/AyaNovaQBI/ServiceRate.cs b/AyaNovaQBI/ServiceRate.cs new file mode 100644 index 0000000..c5b2942 --- /dev/null +++ b/AyaNovaQBI/ServiceRate.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AyaNovaQBI +{ + public class ServiceRate + { + public long Id { get; set; } + public uint Concurrency { get; set; } + public string Name { get; set; } + public bool Active { get; set; } + public string Notes { get; set; } + public string Wiki { get; set; } + public string CustomFields { get; set; } + public List Tags { get; set; } + + public string AccountNumber { get; set; } + public decimal Cost { get; set; } + public decimal Charge { get; set; } + public string Unit { get; set; } + public bool ContractOnly { get; set; } + + + + public ServiceRate() + { + Tags = new List(); + } + + }//eoc +} diff --git a/AyaNovaQBI/TravelRate.cs b/AyaNovaQBI/TravelRate.cs new file mode 100644 index 0000000..90ad8c8 --- /dev/null +++ b/AyaNovaQBI/TravelRate.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AyaNovaQBI +{ + public class TravelRate + { + public long Id { get; set; } + public uint Concurrency { get; set; } + public string Name { get; set; } + public bool Active { get; set; } + public string Notes { get; set; } + public string Wiki { get; set; } + public string CustomFields { get; set; } + public List Tags { get; set; } + + public string AccountNumber { get; set; } + public decimal Cost { get; set; } + public decimal Charge { get; set; } + public string Unit { get; set; } + public bool ContractOnly { get; set; } + + + public TravelRate() + { + Tags = new List(); + } + + + }//eoc +} diff --git a/AyaNovaQBI/Vendor.cs b/AyaNovaQBI/Vendor.cs new file mode 100644 index 0000000..3689559 --- /dev/null +++ b/AyaNovaQBI/Vendor.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AyaNovaQBI +{ + public class Vendor + { + public long Id { get; set; } + public uint Concurrency { get; set; } + + + public string Name { get; set; } + public bool Active { get; set; } + public string Notes { get; set; } + public string Wiki { get; set; } + public string CustomFields { get; set; } + public List Tags { get; set; } + + public string Contact { get; set; } + public string ContactNotes { get; set; } + public string AlertNotes { get; set; } + public string WebAddress { get; set; } + public string AccountNumber { get; set; } + public string Phone1 { get; set; } + public string Phone2 { get; set; } + public string Phone3 { get; set; } + public string Phone4 { get; set; } + public string Phone5 { get; set; } + public string EmailAddress { get; set; } + + + //POSTAL ADDRESS + public string PostAddress { get; set; } + public string PostCity { get; set; } + public string PostRegion { get; set; } + public string PostCountry { get; set; } + public string PostCode { get; set; } + + //PHYSICAL ADDRESS + public string Address { get; set; } + public string City { get; set; } + public string Region { get; set; } + public string Country { get; set; } + public decimal? Latitude { get; set; } + public decimal? Longitude { get; set; } + + + + public Vendor() + { + Tags = new List(); + } + + + + }//eoc +} diff --git a/AyaNovaQBI/util.cs b/AyaNovaQBI/util.cs index e0dcd7f..c42af42 100644 --- a/AyaNovaQBI/util.cs +++ b/AyaNovaQBI/util.cs @@ -3340,6 +3340,1970 @@ namespace AyaNovaQBI #endregion exception helper + + + #region Import / refresh to AyaNova + + #region Import / refresh customer + + #region Refresh Customer + + + public static void RefreshAyaNovaClientFromQB(List objectIDList) + { + PopulateQBClientCache(); + foreach (Guid g in objectIDList) + { + try + { + Client c = Client.GetItemNoMRU(g); + RefreshAyaNovaClientFromQB(c); + if (c.IsSavable) + c.Save(); + } + catch { }; + } + + } + + public static async void RefreshAyaNovaClientFromQB(Client c) + { + await PopulateQBClientCacheAsync(); + IntegrationMap im = QBI.Maps[c.ID]; + if (im == null) return;//this client is not linked + + DataRow dr = _dtQBClients.Rows.Find(im.ForeignID); + if (dr == null) return; //QBListID not found in client list? + + CopyQBCustomerInfoToAyaNovaClient(dr, c); + + string sName = dr["FullName"].ToString(); + if (sName.Length > 255) + sName = sName.Substring(0, 255); + + c.Name = sName; + + } + + + #endregion refresh customer + + #region Import customer + /// + /// Import the indicated customer + /// to an AyaNova client record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportQBCustomer(string QuickBooksID, ArrayList alErrors) + { + + DataRow dr = _dtQBClients.Rows.Find(QuickBooksID); + //QBListID not found in client list? + if (dr == null) + { + alErrors.Add("ImportQBCustomer: ID not found " + QuickBooksID); + return; + } + + string sName = dr["FullName"].ToString(); + if (sName.Length > 255) + { + alErrors.Add("ImportQBCustomer: QuickBooks customer name exceeds 255 character limit for AyaNova\r\n" + + "Name: " + dr["FullName"].ToString() + "\r\n" + + "was imported as: " + sName); + sName = sName.Substring(0, 255); + } + try + { + //already a client by that name + if (Client.Exists(Guid.Empty, dr["FullName"].ToString())) + { + alErrors.Add("ImportQBCustomer: " + dr["FullName"].ToString() + " already exists in AyaNova"); + return; + } + + //Import seems safe... + + Client c = Client.NewItem(); + c.Name = sName;//1 + + CopyQBCustomerInfoToAyaNovaClient(dr, c); + + if (!c.IsSavable) + { + alErrors.Add("ImportQBCustomer: AyaNova won't allow import of " + c.Name + "\r\n" + + "Due to the following broken rules:\r\n" + c.GetBrokenRulesString()); + return; + } + + c = (Client)c.Save(); + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Client; + m.LastSync = DateTime.Now; + m.ForeignID = QuickBooksID; + QBI = (Integration)QBI.Save(); + + } + catch (Exception ex) + { + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + + alErrors.Add("ImportQBCustomer: AyaNova won't allow import / link of " + sName + "\r\n" + + "Due to the following error:\r\n" + CrackException(ex)); + + } + } + #endregion Import customer + + #region Copy QB Customer info to AyaNova client + public static void CopyQBCustomerInfoToAyaNovaClient(DataRow dr, Client c) + { + Address a = (Address)dr["MailAddress"]; + c.MailToAddress.DeliveryAddress = a.DeliveryAddress;//2 + c.MailToAddress.City = a.City;//3 + c.MailToAddress.StateProv = a.StateProv;//4 + c.MailToAddress.Country = a.Country;//5 + c.MailToAddress.Postal = a.Postal;//6 + + a = (Address)dr["StreetAddress"]; + c.GoToAddress.DeliveryAddress = a.DeliveryAddress;//7 + c.GoToAddress.City = a.City;//8 + c.GoToAddress.StateProv = a.StateProv;//9 + c.GoToAddress.Country = a.Country;//10 + c.GoToAddress.Postal = a.Postal;//11 + + //Case 518 + c.PopulateBothAddresses(); + + //Contact cn=c.Contacts.Add(RootObjectTypes.Client,c.ID); + + c.Contact = dr["Contact"].ToString(); + + + //Phone field + if (dr["Phone"].ToString() != "") + { + c.Phone1 = dr["Phone"].ToString(); + } + + //Fax field + if (dr["Fax"].ToString() != "") + { + c.Phone2 = dr["Fax"].ToString();//15 + } + + //AltPhone field + if (dr["AltPhone"].ToString() != "") + { + c.Phone3 = dr["AltPhone"].ToString();//16 + } + + //Email field + if (dr["Email"].ToString() != "") + { + c.Email = dr["Email"].ToString();//17 + } + + //Account number field + if (dr["Account"].ToString() != "") + { + c.AccountNumber = dr["Account"].ToString();//18 + } + + + + } + + #endregion copy qb customer info to aya client + + #endregion import refresh customer + + #region Vendor + + /// + /// Import the indicated Vendor + /// to an AyaNova vendor record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportQBVendor(string QuickBooksID, VendorTypes AsVendorType, ArrayList alErrors) + { + + DataRow dr = _dtQBVendors.Rows.Find(QuickBooksID); + //QBListID not found in Vendor list? + if (dr == null) + { + alErrors.Add("ImportQBVendor: ID not found " + QuickBooksID); + return; + } + + string sName = dr["FullName"].ToString(); + if (sName.Length > 255) + { + alErrors.Add("ImportQBVendor: QuickBooks Vendor name exceeds 255 character limit for AyaNova\r\n" + + "Name: " + dr["FullName"].ToString() + "\r\n" + + "was imported as: " + sName); + sName = sName.Substring(0, 255); + } + try + { + //already a Vendor by that name + if (Vendor.Exists(Guid.Empty, dr["FullName"].ToString())) + { + alErrors.Add("ImportQBVendor: " + dr["FullName"].ToString() + " already exists in AyaNova"); + return; + } + + //Import seems safe... + + Vendor c = Vendor.NewItem(); + c.VendorType = AsVendorType; + c.Name = sName; + + + Address a = (Address)dr["MailAddress"]; + c.MailToAddress.DeliveryAddress = a.DeliveryAddress; + c.MailToAddress.City = a.City; + c.MailToAddress.StateProv = a.StateProv; + c.MailToAddress.Country = a.Country; + c.MailToAddress.Postal = a.Postal; + + a = (Address)dr["StreetAddress"]; + c.GoToAddress.DeliveryAddress = a.DeliveryAddress; + c.GoToAddress.City = a.City; + c.GoToAddress.StateProv = a.StateProv; + c.GoToAddress.Country = a.Country; + c.GoToAddress.Postal = a.Postal; + + + //Contact cn=c.Contacts.Add(RootObjectTypes.Vendor,c.ID); + + c.Contact = dr["Contact"].ToString(); + ////if it's completely empty we'll substitute the word Contact instead + //if(qbcontact=="") + // cn.FirstName="Contact"; + //else + //{ + // //default it first + // cn.FirstName=qbcontact; + + // string [] contactnames=null; + // if(qbcontact.IndexOf(" ")!=-1) + // contactnames=qbcontact.Replace(",","").Split(' ');//replace any commas if present + // else + // if(qbcontact.IndexOf(",")!=-1) + // contactnames=qbcontact.Split(','); + + // //Quickbooks just has one field for contact so + // //we'll assume the english speaking tradition of firstname space lastname + // //if there is a space otherwise we'll assume it's just a first name if there are no spaces in it + // if(contactnames!=null && contactnames.GetLength(0)>1) + // { + // cn.FirstName=contactnames[0]; + // cn.LastName=contactnames[1]; + // } + + //} + + //Phone field + if (dr["Phone"].ToString() != "") + { + //ContactPhone cp=cn.Phones.Add(cn); + //cp.ContactPhoneType=ContactPhoneTypes.Business; + c.Phone1 = dr["Phone"].ToString(); + //case 124 + //cp.PhoneDefault=true; + } + + //Fax field + if (dr["Fax"].ToString() != "") + { + //ContactPhone cp=cn.Phones.Add(cn); + //cp.ContactPhoneType=ContactPhoneTypes.Fax; + c.Phone2 = dr["Fax"].ToString(); + } + + //AltPhone field + if (dr["AltPhone"].ToString() != "") + { + //ContactPhone cp=cn.Phones.Add(cn); + //cp.ContactPhoneType=ContactPhoneTypes.Business; + c.Phone3 = dr["AltPhone"].ToString(); + } + + //Email field + if (dr["Email"].ToString() != "") + { + c.Email = dr["Email"].ToString(); + } + + //Account number + if (dr["Account"].ToString() != "") + { + c.AccountNumber = dr["Account"].ToString(); + } + + if (!c.IsSavable) + { + alErrors.Add("ImportQBVendor: AyaNova won't allow import of " + c.Name + "\r\n" + + "Due to the following broken rules:\r\n" + c.GetBrokenRulesString()); + return; + } + + + c = (Vendor)c.Save(); + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Vendor; + m.LastSync = DateTime.Now; + m.ForeignID = QuickBooksID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + alErrors.Add("ImportQBVendor: AyaNova won't allow import / link of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + #endregion + + #region Rate + + /// + /// Import the indicated QB Item + /// to an AyaNova Rate record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportQBRate(string QuickBooksID, RateTypes AsRateType, Guid MostLikelyRateUnitChargeDescriptionID, ArrayList alErrors) + { + + DataRow dr = _dtQBItems.Rows.Find(QuickBooksID); + //QBListID not found in Rate list? + if (dr == null) + { + alErrors.Add("ImportQBRate: ID not found " + QuickBooksID); + return; + } + + string sName = dr["FullName"].ToString(); + if (sName.Length > 255) + { + alErrors.Add("ImportQBRate: QuickBooks Rate name exceeds 255 character limit for AyaNova\r\n" + + "Name: " + dr["FullName"].ToString() + "\r\n" + + "was imported as: " + sName); + sName = sName.Substring(0, 255); + } + try + { + //already a Rate by that name + if (Rate.Exists(Guid.Empty, dr["FullName"].ToString())) + { + alErrors.Add("ImportQBRate: " + dr["FullName"].ToString() + " already exists in AyaNova"); + return; + } + + //Import seems safe... + Rates rates = Rates.GetItems(false); + Rate c = rates.Add(); + c.RateType = AsRateType; + c.Name = sName; + c.Charge = (decimal)dr["Price"]; + c.ContractRate = false; + c.Cost = (decimal)dr["Cost"]; + c.Description = T(255, dr["SalesDesc"].ToString()); + c.RateUnitChargeDescriptionID = MostLikelyRateUnitChargeDescriptionID; + + + + if (!c.IsSavable) + { + alErrors.Add("ImportQBRate: AyaNova won't allow import of " + c.Name + "\r\n" + + "Due to the following broken rules:\r\n" + c.GetBrokenRulesString()); + return; + } + + + rates = (Rates)rates.Save(); + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Rate; + m.LastSync = DateTime.Now; + m.ForeignID = QuickBooksID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + alErrors.Add("ImportQBRate: AyaNova won't allow import / link of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + #endregion + + #region Part + + public static void RefreshAyaNovaPartFromQB(List objectIDList) + { + PopulateQBItemCache(); + foreach (Guid g in objectIDList) + { + try + { + Part c = Part.GetItem(g); + RefreshAyaNovaPartFromQB(c); + if (c.IsSavable) + c.Save(); + } + catch { }; + } + + } + + public static void RefreshAyaNovaPartFromQB(Part c) + { + PopulateQBItemCache(); + IntegrationMap im = QBI.Maps[c.ID]; + if (im == null) return;//this part is not linked + + DataRow dr = _dtQBItems.Rows.Find(im.ForeignID); + if (dr == null) return; //QBListID not found in part list? + + string sName = dr["FullName"].ToString(); + if (sName.Length > 255) + sName = sName.Substring(0, 255); + c.PartNumber = sName; + + c.Name = T(255, dr["SalesDesc"].ToString()); + c.WholesalerID = AyaVendorForQBItem(im.ForeignID); + c.Retail = (decimal)dr["Price"]; + c.Cost = (decimal)dr["Cost"]; + + } + + + + + + /// + /// Import the indicated QB Item + /// to an AyaNova Part record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportQBPart(string QuickBooksID, ArrayList alErrors) + { + + DataRow dr = _dtQBItems.Rows.Find(QuickBooksID); + //QBListID not found in Part list? + if (dr == null) + { + alErrors.Add("ImportQBPart: ID not found " + QuickBooksID); + return; + } + + string sName = dr["FullName"].ToString(); + if (sName.Length > 255) + { + alErrors.Add("ImportQBPart: QuickBooks Part name exceeds 255 character limit for AyaNova part number\r\n" + + "Name: " + dr["FullName"].ToString() + "\r\n" + + "was imported as: " + sName); + sName = sName.Substring(0, 255); + } + try + { + //already a Part by that number? + if (Part.Exists(Guid.Empty, dr["FullName"].ToString())) + { + alErrors.Add("ImportQBPart: Part number " + dr["FullName"].ToString() + " already exists in AyaNova"); + return; + } + + //Import seems safe... + Part c = Part.NewItem(); + + + c.PartNumber = sName; + c.Name = T(255, dr["SalesDesc"].ToString()); + c.WholesalerID = AyaVendorForQBItem(QuickBooksID); + c.Retail = (decimal)dr["Price"]; + c.Cost = (decimal)dr["Cost"]; + + + + if (!c.IsSavable) + { + alErrors.Add("ImportQBPart: AyaNova won't allow import of " + c.Name + "\r\n" + + "Due to the following broken rules:\r\n" + c.GetBrokenRulesString()); + return; + } + + //Save and get ready to provide the ID + c = (Part)c.Save(); + + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Part; + m.LastSync = DateTime.Now; + m.ForeignID = QuickBooksID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + alErrors.Add("ImportQBPart: AyaNova won't allow import / link of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + #endregion + + #endregion Import to AyaNova + + #region Export / refresh to QuickBooks + + #region Customer + + + #region Refresh to QB + + + public static void RefreshQBClientFromAyaNova(List objectIDList) + { + foreach (Guid g in objectIDList) + { + try + { + Client c = Client.GetItemNoMRU(g); + RefreshQBClientFromAyaNova(c); + + } + catch { }; + } + + } + + /// + /// Refresh the indicated AyaNova client + /// to it's linked QuickBooks customer record + /// + public static void RefreshQBClientFromAyaNova(Client c) + { + + IntegrationMap im = QBI.Maps[c.ID]; + if (im == null) return;//this client is not linked + + DataRow dr = _dtQBClients.Rows.Find(im.ForeignID); + if (dr == null) return; //QBListID not found in client list? + + string strEditSequence = GetQBCustomerEditSequence(im.ForeignID); + if (string.IsNullOrEmpty(strEditSequence)) + { + MessageBox.Show("RefreshQBClientFromAyaNova -> Error: unable to fetch edit sequence from QuickBooks. No changes made."); + return; + } + + string sName = c.Name; + if (sName.Length > 41) + sName = sName.Substring(0, 41); + + + //Connect to QB and fill + // IY: Create the session manager object using QBFC + QBSessionManager sessionManager = new QBSessionManager(); + + // IY: We want to know if we begun a session so we can end it if an + // error happens + bool booSessionBegun = false; + + try + { + + + //Import seems safe... + + // IY: Get the RequestMsgSet based on the correct QB Version + IMsgSetRequest requestSet = getLatestMsgSetRequest(sessionManager); + + // IY: Initialize the message set request object + requestSet.Attributes.OnError = ENRqOnError.roeStop; + + // IY: Add the request to the message set request object + + ICustomerMod ca = requestSet.AppendCustomerModRq(); + + //Set field value for ListID + ca.ListID.SetValue(im.ForeignID); + // ca.ParentRef.ListID.SetValue(im.ForeignID); + ca.EditSequence.SetValue(strEditSequence); + + dr["FullName"] = sName; + dr["MailAddress"] = new Address(); + dr["StreetAddress"] = new Address(); + dr["Phone"] = ""; + dr["Fax"] = ""; + dr["AltPhone"] = ""; + dr["Email"] = ""; + dr["Contact"] = ""; + //dr["Created"] = DateTime.MinValue;//flag indicating fresh record incomplete + dr["Modified"] = DateTime.Now;//ditto + dr["Account"] = ""; + + ca.Name.SetValue(sName); + //ca.FirstName.SetValue(T(25,Primary.FirstName)); + //Case 686 + ca.Contact.SetValue(T(41, c.Contact)); + //ca.LastName.SetValue(T(25, c.Contact)); + + if (c.Phone1 != null) + ca.Phone.SetValue(T(21, c.Phone1)); + else + ca.Phone.SetValue(""); + ca.Fax.SetValue(T(21, c.Phone2)); + ca.AltPhone.SetValue(T(21, c.Phone3)); + ca.Email.SetValue(T(99, c.Email)); + + + #region Addresses + bool bHasBillAddress = false; + + //Mailing address + //Changed:4-Sept-2006 client name is now addr1 + //rest shuffle down a spot + //Also changed max length of address lines from 21 characters to 41 + //as that is what is documented, not sure why they were set to 21 here before + ca.BillAddress.Addr1.SetValue(T(41, c.Name)); + + if (c.MailToAddress.DeliveryAddress != "") + { + bHasBillAddress = true; + string[] sad = c.MailToAddress.DeliveryAddress.Replace("\r\n", "\n").Split('\n'); + if (sad.GetLength(0) > 0) + ca.BillAddress.Addr2.SetValue(T(41, sad[0].TrimEnd())); + if (sad.GetLength(0) > 1) + ca.BillAddress.Addr3.SetValue(T(41, sad[1].TrimEnd())); + //if(sad.GetLength(0)>2) + // ca.BillAddress.Addr3.SetValue(T(21,sad[2].TrimEnd())); + + + if (QVersion > 1.1 && sad.GetLength(0) > 3)//4th address line is 2 or newer + ca.BillAddress.Addr4.SetValue(T(41, sad[2].TrimEnd())); + + } + ca.BillAddress.City.SetValue(T(31, c.MailToAddress.City)); + ca.BillAddress.Country.SetValue(T(31, c.MailToAddress.Country)); + ca.BillAddress.PostalCode.SetValue(T(13, c.MailToAddress.Postal)); + + //QBFC7 - unifies county and province to "State" + ca.BillAddress.State.SetValue(T(21, c.MailToAddress.StateProv)); + //switch(QCountry) + //{ + // case "CA": + // ca.BillAddress.Province.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + // case "UK": + // ca.BillAddress.County.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + // default: + // ca.BillAddress.State.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + + //} + + + + + bool bHasShipAddress = false; + //Delivery address + //Changed:4-Sept-2006 client name is now addr1 + //rest shuffle down a spot + //Also changed max length of address lines from 21 characters to 41 + //as that is what is documented, not sure why they were set to 21 here before + ca.ShipAddress.Addr1.SetValue(T(41, c.Name)); + + if (c.GoToAddress.DeliveryAddress != "") + { + bHasShipAddress = true; + string[] sad = c.GoToAddress.DeliveryAddress.Replace("\r\n", "\n").Split('\n'); + if (sad.GetLength(0) > 0) + ca.ShipAddress.Addr2.SetValue(T(41, sad[0].TrimEnd())); + if (sad.GetLength(0) > 1) + ca.ShipAddress.Addr3.SetValue(T(41, sad[1].TrimEnd())); + + //if(sad.GetLength(0)>2) + // ca.ShipAddress.Addr3.SetValue(T(21,sad[2].TrimEnd())); + + if (QVersion > 1.1 && sad.GetLength(0) > 3)//4th address line is 2 or newer + ca.ShipAddress.Addr4.SetValue(T(41, sad[2].TrimEnd())); + + } + + + ca.ShipAddress.City.SetValue(T(31, c.GoToAddress.City)); + ca.ShipAddress.Country.SetValue(T(31, c.GoToAddress.Country)); + ca.ShipAddress.PostalCode.SetValue(T(13, c.GoToAddress.Postal)); + + //QBFC7 - unifies county and province to "State" + ca.ShipAddress.State.SetValue(T(21, c.GoToAddress.StateProv)); + //switch(QCountry) + //{ + // case "CA": + // ca.ShipAddress.Province.SetValue(T(21,c.GoToAddress.StateProv)); + // break; + // case "UK": + // ca.ShipAddress.County.SetValue(T(21,c.GoToAddress.StateProv)); + // break; + // default: + // ca.ShipAddress.State.SetValue(T(21,c.GoToAddress.StateProv)); + // break; + + //} + + + #endregion + + //Added: 18-Nov-2006 CASE 95 + //ensure that if only one address in ayanova that both types in QB get it + if (!bHasShipAddress || !bHasBillAddress) + { + if (bHasShipAddress && !bHasBillAddress) + { + //copy shipping address to billing address + CopyAddress(ca.ShipAddress, ca.BillAddress); + + } + else if (bHasBillAddress && !bHasShipAddress) + { + CopyAddress(ca.BillAddress, ca.ShipAddress); + } + } + + + ca.AccountNumber.SetValue(T(99, c.AccountNumber)); + + //case 519 + ca.TermsRef.ListID.SetValue(QDat.TermsDefault); + + //This is intended to be called after already sucessfully connected + //to get version info so no special safety checks here + sessionManager.OpenConnection2("", "AyaNova QBI", ENConnectionType.ctLocalQBDLaunchUI); + sessionManager.BeginSession("", ENOpenMode.omDontCare); + booSessionBegun = true; + + + IMsgSetResponse responseSet = sessionManager.DoRequests(requestSet); + + // //// Uncomment the following to view and save the request and response XML + // string requestXML = requestSet.ToXMLString(); + // MessageBox.Show(requestXML); + // ////SaveXML(requestXML); + // string responseXML = responseSet.ToXMLString(); + // MessageBox.Show(responseXML); + ////// SaveXML(responseXML); + + IResponse response = responseSet.ResponseList.GetAt(0); + //nonzero indicates an error this is unrecoverable + //so throw an exception + + if (response.StatusCode != 0) + { + throw new ApplicationException(response.StatusMessage + " Code: " + response.StatusCode); + + } + + ICustomerRet cr = response.Detail as ICustomerRet; + string sNewCustID = cr.ListID.GetValue(); + requestSet.ClearRequests(); + //---------------- + + + // Close the session and connection with QuickBooks + sessionManager.EndSession(); + booSessionBegun = false; + sessionManager.CloseConnection(); + + //catch the new ID for the QB Item + // dr["ID"] = sNewCustID; + //add the new row for the newly imported object + // _dtQBClients.Rows.Add(dr); + + //Link + //IntegrationMap m = QBI.Maps.Add(QBI); + im.Name = sName; + //m.RootObjectID = c.ID; + //m.RootObjectType = RootObjectTypes.Client; + im.LastSync = DateTime.Now; + //m.ForeignID = sNewCustID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + if (booSessionBegun) + { + sessionManager.EndSession(); + sessionManager.CloseConnection(); + } + + + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + MessageBox.Show("RefreshQBClientFromAyaNova: QuickBooks won't allow refresh of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + + + #endregion Refresh to qb + + + #region Export to QB + + public static void ImportAyaClient(List objectIDList) + { + ArrayList alErrors = new ArrayList(); + foreach (Guid g in objectIDList) + { + try + { + + ImportAyaClient(g, alErrors); + + } + catch { }; + } + + if (alErrors.Count != 0) + { + + + StringBuilder sb = new StringBuilder(); + sb.Append("Export completed with some errors:\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(); + + } + } + + + /// + /// Import the indicated client + /// to QuickBooks customer record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportAyaClient(Guid ClientID, ArrayList alErrors) + { + + if (!Client.Exists(ClientID, "")) + { + alErrors.Add("ImportAyaClient: Client not found in AyaNova (deleted recently?) (" + ClientID.ToString() + ")"); + return; + + } + Client c = Client.GetItem(ClientID); + + + + + string sName = c.Name; + if (sName.Length > 41) + { + sName = sName.Substring(0, 41); + alErrors.Add("ImportAyaClient: AyaNova client name exceeds 41 character limit for QuickBooks\r\n" + + "Name: " + c.Name + "\r\n" + + "will be imported as: " + sName); + + } + + + + //Connect to QB and fill + // IY: Create the session manager object using QBFC + QBSessionManager sessionManager = new QBSessionManager(); + + // IY: We want to know if we begun a session so we can end it if an + // error happens + bool booSessionBegun = false; + + try + { + + + //Import seems safe... + + // IY: Get the RequestMsgSet based on the correct QB Version + IMsgSetRequest requestSet = getLatestMsgSetRequest(sessionManager); + + // IY: Initialize the message set request object + requestSet.Attributes.OnError = ENRqOnError.roeStop; + + // IY: Add the request to the message set request object + ICustomerAdd ca = requestSet.AppendCustomerAddRq(); + + //create a new row to add to the client cache datatable + DataRow dr = _dtQBClients.NewRow(); + + + dr["FullName"] = sName; + dr["MailAddress"] = new Address(); + dr["StreetAddress"] = new Address(); + dr["Phone"] = ""; + dr["Fax"] = ""; + dr["AltPhone"] = ""; + dr["Email"] = ""; + dr["Contact"] = ""; + dr["Created"] = DateTime.MinValue;//flag indicating fresh record incomplete + dr["Modified"] = DateTime.MinValue;//ditto + dr["Account"] = ""; + + ca.Name.SetValue(sName); + //ca.FirstName.SetValue(T(25,Primary.FirstName)); + //Case 686 + ca.Contact.SetValue(T(41, c.Contact)); + //ca.LastName.SetValue(T(25, c.Contact)); + + if (c.Phone1 != null) + ca.Phone.SetValue(T(21, c.Phone1)); + else + ca.Phone.SetValue(""); + ca.Fax.SetValue(T(21, c.Phone2)); + ca.AltPhone.SetValue(T(21, c.Phone3)); + ca.Email.SetValue(T(99, c.Email)); + + + #region Addresses + bool bHasBillAddress = false; + + //Mailing address + //Changed:4-Sept-2006 client name is now addr1 + //rest shuffle down a spot + //Also changed max length of address lines from 21 characters to 41 + //as that is what is documented, not sure why they were set to 21 here before + ca.BillAddress.Addr1.SetValue(T(41, c.Name)); + + if (c.MailToAddress.DeliveryAddress != "") + { + bHasBillAddress = true; + string[] sad = c.MailToAddress.DeliveryAddress.Replace("\r\n", "\n").Split('\n'); + if (sad.GetLength(0) > 0) + ca.BillAddress.Addr2.SetValue(T(41, sad[0].TrimEnd())); + if (sad.GetLength(0) > 1) + ca.BillAddress.Addr3.SetValue(T(41, sad[1].TrimEnd())); + //if(sad.GetLength(0)>2) + // ca.BillAddress.Addr3.SetValue(T(21,sad[2].TrimEnd())); + + + if (QVersion > 1.1 && sad.GetLength(0) > 3)//4th address line is 2 or newer + ca.BillAddress.Addr4.SetValue(T(41, sad[2].TrimEnd())); + + } + ca.BillAddress.City.SetValue(T(31, c.MailToAddress.City)); + ca.BillAddress.Country.SetValue(T(31, c.MailToAddress.Country)); + ca.BillAddress.PostalCode.SetValue(T(13, c.MailToAddress.Postal)); + + //QBFC7 - unifies county and province to "State" + ca.BillAddress.State.SetValue(T(21, c.MailToAddress.StateProv)); + //switch(QCountry) + //{ + // case "CA": + // ca.BillAddress.Province.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + // case "UK": + // ca.BillAddress.County.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + // default: + // ca.BillAddress.State.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + + //} + + + + + bool bHasShipAddress = false; + //Delivery address + //Changed:4-Sept-2006 client name is now addr1 + //rest shuffle down a spot + //Also changed max length of address lines from 21 characters to 41 + //as that is what is documented, not sure why they were set to 21 here before + ca.ShipAddress.Addr1.SetValue(T(41, c.Name)); + + if (c.GoToAddress.DeliveryAddress != "") + { + bHasShipAddress = true; + string[] sad = c.GoToAddress.DeliveryAddress.Replace("\r\n", "\n").Split('\n'); + if (sad.GetLength(0) > 0) + ca.ShipAddress.Addr2.SetValue(T(41, sad[0].TrimEnd())); + if (sad.GetLength(0) > 1) + ca.ShipAddress.Addr3.SetValue(T(41, sad[1].TrimEnd())); + + //if(sad.GetLength(0)>2) + // ca.ShipAddress.Addr3.SetValue(T(21,sad[2].TrimEnd())); + + if (QVersion > 1.1 && sad.GetLength(0) > 3)//4th address line is 2 or newer + ca.ShipAddress.Addr4.SetValue(T(41, sad[2].TrimEnd())); + + } + + + ca.ShipAddress.City.SetValue(T(31, c.GoToAddress.City)); + ca.ShipAddress.Country.SetValue(T(31, c.GoToAddress.Country)); + ca.ShipAddress.PostalCode.SetValue(T(13, c.GoToAddress.Postal)); + + //QBFC7 - unifies county and province to "State" + ca.ShipAddress.State.SetValue(T(21, c.GoToAddress.StateProv)); + //switch(QCountry) + //{ + // case "CA": + // ca.ShipAddress.Province.SetValue(T(21,c.GoToAddress.StateProv)); + // break; + // case "UK": + // ca.ShipAddress.County.SetValue(T(21,c.GoToAddress.StateProv)); + // break; + // default: + // ca.ShipAddress.State.SetValue(T(21,c.GoToAddress.StateProv)); + // break; + + //} + + + #endregion + + //Added: 18-Nov-2006 CASE 95 + //ensure that if only one address in ayanova that both types in QB get it + if (!bHasShipAddress || !bHasBillAddress) + { + if (bHasShipAddress && !bHasBillAddress) + { + //copy shipping address to billing address + CopyAddress(ca.ShipAddress, ca.BillAddress); + + } + else if (bHasBillAddress && !bHasShipAddress) + { + CopyAddress(ca.BillAddress, ca.ShipAddress); + } + } + + + ca.AccountNumber.SetValue(T(99, c.AccountNumber)); + + //case 519 + ca.TermsRef.ListID.SetValue(QDat.TermsDefault); + + //This is intended to be called after already sucessfully connected + //to get version info so no special safety checks here + sessionManager.OpenConnection2("", "AyaNova QBI", ENConnectionType.ctLocalQBDLaunchUI); + sessionManager.BeginSession("", ENOpenMode.omDontCare); + booSessionBegun = true; + + + IMsgSetResponse responseSet = sessionManager.DoRequests(requestSet); + + // Uncomment the following to view and save the request and response XML + //string requestXML = requestSet.ToXMLString(); + //MessageBox.Show(requestXML); + // SaveXML(requestXML); + //string responseXML = responseSet.ToXMLString(); + //MessageBox.Show(responseXML); + // SaveXML(responseXML); + + IResponse response = responseSet.ResponseList.GetAt(0); + //nonzero indicates an error this is unrecoverable + //so throw an exception + + if (response.StatusCode != 0) + { + throw new ApplicationException(response.StatusMessage + " Code: " + response.StatusCode); + + } + + ICustomerRet cr = response.Detail as ICustomerRet; + string sNewCustID = cr.ListID.GetValue(); + requestSet.ClearRequests(); + //---------------- + + + // Close the session and connection with QuickBooks + sessionManager.EndSession(); + booSessionBegun = false; + sessionManager.CloseConnection(); + + //catch the new ID for the QB Item + dr["ID"] = sNewCustID; + //add the new row for the newly imported object + _dtQBClients.Rows.Add(dr); + + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Client; + m.LastSync = DateTime.Now; + m.ForeignID = sNewCustID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + if (booSessionBegun) + { + sessionManager.EndSession(); + sessionManager.CloseConnection(); + } + + + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + alErrors.Add("ImportAyaClient: QuickBooks won't allow import of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + + + #endregion export to qb + + /// + /// Copy the contents of one address to the other + /// + /// + /// + private static void CopyAddress(IAddress from, IAddress to) + { + if (from.Addr1.IsSet()) + to.Addr1.SetValue(from.Addr1.GetValue()); + + if (from.Addr2.IsSet()) + to.Addr2.SetValue(from.Addr2.GetValue()); + + if (from.Addr3.IsSet()) + to.Addr3.SetValue(from.Addr3.GetValue()); + + if (QVersion > 1.1)//4th address line is 2 or newer + { + if (from.Addr4.IsSet()) + to.Addr4.SetValue(from.Addr4.GetValue()); + } + + if (from.City.IsSet()) + to.City.SetValue(from.City.GetValue()); + + if (from.Country.IsSet()) + to.Country.SetValue(from.Country.GetValue()); + + if (from.PostalCode.IsSet()) + to.PostalCode.SetValue(from.PostalCode.GetValue()); + + //QBFC7 - unifies county and province to "State" + if (from.State.IsSet()) + to.State.SetValue(from.State.GetValue()); + + //switch (QCountry) + //{ + // case "CA": + // if (from.Province.IsSet()) + // to.Province.SetValue(from.Province.GetValue()); + // break; + // case "UK": + // if (from.County.IsSet()) + // to.County.SetValue(from.County.GetValue()); + // break; + // default: + // if (from.State.IsSet()) + // to.State.SetValue(from.State.GetValue()); + // break; + + //} + + } + #endregion customer + + #region Vendor + /// + /// Import the indicated Vendor + /// to QuickBooks Vendor record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportAyaVendor(Guid VendorID, ArrayList alErrors) + { + + if (!Vendor.Exists(VendorID, "")) + { + alErrors.Add("ImportAyaVendor: Vendor not found in AyaNova (deleted recently?) (" + VendorID.ToString() + ")"); + return; + + } + Vendor c = Vendor.GetItem(VendorID); + + + + + string sName = c.Name; + if (sName.Length > 41) + { + sName = sName.Substring(0, 41); + alErrors.Add("ImportAyaVendor: AyaNova Vendor name exceeds 41 character limit for QuickBooks\r\n" + + "Name: " + c.Name + "\r\n" + + "will be imported as: " + sName); + + } + + + + //Connect to QB and fill + // IY: Create the session manager object using QBFC + QBSessionManager sessionManager = new QBSessionManager(); + + // IY: We want to know if we begun a session so we can end it if an + // error happens + bool booSessionBegun = false; + + try + { + + + //Import seems safe... + + // IY: Get the RequestMsgSet based on the correct QB Version + IMsgSetRequest requestSet = getLatestMsgSetRequest(sessionManager); + + // IY: Initialize the message set request object + requestSet.Attributes.OnError = ENRqOnError.roeStop; + + // IY: Add the request to the message set request object + IVendorAdd ca = requestSet.AppendVendorAddRq(); + //create a new row to add to the client cache datatable + DataRow dr = _dtQBVendors.NewRow(); + + + dr["FullName"] = sName; + dr["MailAddress"] = new Address(); + dr["StreetAddress"] = new Address(); + dr["Phone"] = ""; + dr["Fax"] = ""; + dr["AltPhone"] = ""; + dr["Email"] = ""; + dr["Contact"] = ""; + dr["Created"] = DateTime.MinValue;//flag indicating fresh record incomplete + dr["Modified"] = DateTime.MinValue;//ditto + dr["Account"] = ""; + + ca.Name.SetValue(sName); + + //Case 687 + ca.Contact.SetValue(T(41, c.Contact)); + //ca.FirstName.SetValue(T(25,Primary.FirstName)); + //ca.LastName.SetValue(T(25, c.Contact)); + + if (c.Phone1 != null) + ca.Phone.SetValue(T(21, c.Phone1)); + else + ca.Phone.SetValue(""); + ca.Fax.SetValue(T(21, c.Phone2)); + ca.AltPhone.SetValue(T(21, c.Phone3)); + ca.Email.SetValue(T(99, c.Email)); + + if (c.MailToAddress.DeliveryAddress != "") + { + string[] sad = c.MailToAddress.DeliveryAddress.Replace("\r\n", "\n").Split('\n'); + if (sad.GetLength(0) > 0) + ca.VendorAddress.Addr1.SetValue(T(21, sad[0].TrimEnd())); + if (sad.GetLength(0) > 1) + ca.VendorAddress.Addr2.SetValue(T(21, sad[1].TrimEnd())); + if (sad.GetLength(0) > 2) + ca.VendorAddress.Addr3.SetValue(T(21, sad[2].TrimEnd())); + if (QVersion > 1.1 && sad.GetLength(0) > 3)//4th address line is 2 or newer + ca.VendorAddress.Addr4.SetValue(T(21, sad[3].TrimEnd())); + + } + ca.VendorAddress.City.SetValue(T(31, c.MailToAddress.City)); + ca.VendorAddress.Country.SetValue(T(31, c.MailToAddress.Country)); + ca.VendorAddress.PostalCode.SetValue(T(13, c.MailToAddress.Postal)); + + //QBFC7 - unifies county and province to "State" + ca.VendorAddress.State.SetValue(T(21, c.MailToAddress.StateProv)); + //switch(QCountry) + //{ + // case "CA": + // ca.VendorAddress.Province.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + // case "UK": + // ca.VendorAddress.County.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + // default: + // ca.VendorAddress.State.SetValue(T(21,c.MailToAddress.StateProv)); + // break; + + //} + + ca.AccountNumber.SetValue(T(99, c.AccountNumber)); + + //This is intended to be called after already sucessfully connected + //to get version info so no special safety checks here + sessionManager.OpenConnection2("", "AyaNova QBI", ENConnectionType.ctLocalQBDLaunchUI); + sessionManager.BeginSession("", ENOpenMode.omDontCare); + booSessionBegun = true; + + + IMsgSetResponse responseSet = sessionManager.DoRequests(requestSet); + + // Uncomment the following to view and save the request and response XML + //string requestXML = requestSet.ToXMLString(); + //MessageBox.Show(requestXML); + // SaveXML(requestXML); + //string responseXML = responseSet.ToXMLString(); + //MessageBox.Show(responseXML); + // SaveXML(responseXML); + + IResponse response = responseSet.ResponseList.GetAt(0); + //nonzero indicates an error this is unrecoverable + //so throw an exception + + if (response.StatusCode != 0) + { + throw new ApplicationException(response.StatusMessage + " Code: " + response.StatusCode); + + } + + IVendorRet cr = response.Detail as IVendorRet; + string sNewCustID = cr.ListID.GetValue(); + requestSet.ClearRequests(); + //---------------- + + + // Close the session and connection with QuickBooks + sessionManager.EndSession(); + booSessionBegun = false; + sessionManager.CloseConnection(); + + //catch the new ID for the QB Item + dr["ID"] = sNewCustID; + //add the new row for the newly imported object + _dtQBVendors.Rows.Add(dr); + + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Vendor; + m.LastSync = DateTime.Now; + m.ForeignID = sNewCustID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + if (booSessionBegun) + { + sessionManager.EndSession(); + sessionManager.CloseConnection(); + } + + + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + alErrors.Add("ImportAyaVendor: QuickBooks won't allow import of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + #endregion vendor + + #region Part case 632 + + + /// + /// Refresh the list of AyaNova parts to their linked QuickBooks item records + /// + /// + public static void RefreshQBPartFromAyaNova(List objectIDList) + { + foreach (Guid g in objectIDList) + { + try + { + Part c = Part.GetItem(g); + RefreshQBPartFromAyaNova(c); + + } + catch { }; + } + + } + + /// + /// Refresh the indicated AyaNova part + /// to it's linked QuickBooks item record + /// + public static void RefreshQBPartFromAyaNova(Part c) + { + + IntegrationMap im = QBI.Maps[c.ID]; + if (im == null) return;//this part is not linked + + DataRow dr = _dtQBItems.Rows.Find(im.ForeignID); + if (dr == null) return; //QBListID not found in part list? + + string sName = c.PartNumber; + if (sName.Length > 31) + sName = sName.Substring(0, 31); + + + + string sDescription = PartPickList.GetOnePart(c.ID)[0].DisplayName(AyaBizUtils.GlobalSettings.DefaultPartDisplayFormat); + if (sDescription.Length > 4095) + sDescription = sDescription.Substring(0, 4095); + + + //Connect to QB and fill + // IY: Create the session manager object using QBFC + QBSessionManager sessionManager = new QBSessionManager(); + + // IY: We want to know if we begun a session so we can end it if an + // error happens + bool booSessionBegun = false; + + try + { + + + //Import seems safe... + + // IY: Get the RequestMsgSet based on the correct QB Version + IMsgSetRequest requestSet = getLatestMsgSetRequest(sessionManager); + + // IY: Initialize the message set request object + requestSet.Attributes.OnError = ENRqOnError.roeStop; + + + // IY: Add the request to the message set request object + IItemInventoryMod ca = requestSet.AppendItemInventoryModRq(); + //Get and set edit sequence + string sEditSequence = GetInventoryItemEditSequence(im.ForeignID); + + + + //create a new row to add to the client cache datatable + + dr["FullName"] = sName; + dr["Type"] = qbitemtype.Inventory; + dr["Price"] = c.Retail; + dr["Cost"] = c.Cost; + dr["SalesDesc"] = sDescription; + //dr["ReorderPoint"] = 0; + dr["Modified"] = DateTime.Now; + dr["VendorID"] = c.WholesalerID.ToString(); + + //Set the QB item identification and edit sequence + ca.ListID.SetValue(im.ForeignID); + ca.EditSequence.SetValue(sEditSequence); + + + //------------------------ + //Set the qb item values + ca.Name.SetValue(sName); + //ca.IncomeAccountRef.ListID.SetValue(QDat.QBInventoryIncomeAccountReference); + // ca.COGSAccountRef.ListID.SetValue(QDat.QBInventoryCOGSAccountRef); + // ca.AssetAccountRef.ListID.SetValue(QDat.QBInventoryAssetAccountRef); + ca.SalesDesc.SetValue(sDescription); + ca.PurchaseDesc.SetValue(sDescription); + + ca.SalesPrice.SetValue((double)c.Retail); + ca.PurchaseCost.SetValue((double)c.Cost); + + //Inventory values cannot be updated this way + //they require generating a PO or making an invoice so + //the refresh command won't support inventory values + + //if (AyaBizUtils.GlobalSettings.UseInventory) + //{ + // PartInventoryValuesFetcher pbw = PartInventoryValuesFetcher.GetItem(c.ID); + // ca.QuantityOnHand.SetValue((double)pbw.QuantityOnHand); + // ca.ReorderPoint.SetValue((double)pbw.MinStockLevel); + //} + //------------------------ + + + //This is intended to be called after already sucessfully connected + //to get version info so no special safety checks here + sessionManager.OpenConnection2("", "AyaNova QBI", ENConnectionType.ctLocalQBDLaunchUI); + sessionManager.BeginSession("", ENOpenMode.omDontCare); + booSessionBegun = true; + + + IMsgSetResponse responseSet = sessionManager.DoRequests(requestSet); + + // Uncomment the following to view and save the request and response XML + //string requestXML = requestSet.ToXMLString(); + //MessageBox.Show(requestXML); + // SaveXML(requestXML); + //string responseXML = responseSet.ToXMLString(); + //MessageBox.Show(responseXML); + // SaveXML(responseXML); + + IResponse response = responseSet.ResponseList.GetAt(0); + //nonzero indicates an error this is unrecoverable + //so throw an exception + + if (response.StatusCode != 0) + { + throw new ApplicationException(response.StatusMessage + " Code: " + response.StatusCode); + + } + + // IItemInventoryRet cr = response.Detail as IItemInventoryRet; + // string sNewID = cr.ListID.GetValue(); + requestSet.ClearRequests(); + //---------------- + + + // Close the session and connection with QuickBooks + sessionManager.EndSession(); + booSessionBegun = false; + sessionManager.CloseConnection(); + + //catch the new ID for the QB Item + // dr["ID"] = sNewID; + //add the new row for the newly imported object + // _dtQBItems.Rows.Add(dr); + + //Link + // IntegrationMap m = QBI.Maps.Add(QBI); + //m.Name = sName; + // m.RootObjectID = c.ID; + // m.RootObjectType = RootObjectTypes.Part; + im.LastSync = DateTime.Now; + //m.ForeignID = sNewID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + if (booSessionBegun) + { + sessionManager.EndSession(); + sessionManager.CloseConnection(); + } + + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + CopyableMessageBox cp = new CopyableMessageBox( + "RefreshQBPartFromAyaNova: QuickBooks won't allow import of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + cp.ShowDialog(); + } + } + + + #region AyaNova Part to Quickbooks + + /// + /// Import a list of ayanova parts to QuickBooks + /// + /// + public static void ImportAyaPart(List objectIDList) + { + ArrayList alErrors = new ArrayList(); + foreach (Guid g in objectIDList) + { + try + { + + ImportAyaPart(g, alErrors); + + } + catch { }; + } + + if (alErrors.Count != 0) + { + + + StringBuilder sb = new StringBuilder(); + sb.Append("Export AyaNova parts to QuickBooks completed with some errors:\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(); + + } + } + + + /// + /// Import the indicated part + /// to QuickBooks item record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportAyaPart(Guid PartID, ArrayList alErrors) + { + + if (!Part.Exists(PartID, "")) + { + alErrors.Add("ImportAyaPart: Part not found in AyaNova (deleted recently?) (" + PartID.ToString() + ")"); + return; + + } + Part c = Part.GetItem(PartID); + + + + + string sName = c.PartNumber; + if (sName.Length > 31) + { + sName = sName.Substring(0, 31); + alErrors.Add("ImportAyaPart: AyaNova part number exceeds 31 character limit for QuickBooks\r\n" + + "Number: " + c.PartNumber + "\r\n" + + "will be imported as: " + sName); + + } + string sDescription = PartPickList.GetOnePart(c.ID)[0].DisplayName(AyaBizUtils.GlobalSettings.DefaultPartDisplayFormat); + if (sDescription.Length > 4095) + { + sDescription = sDescription.Substring(0, 4095); + alErrors.Add("ImportAyaPart: AyaNova part full display name exceeds 4095 character limit for sales description in QuickBooks\r\n" + + "will be imported as: " + sDescription); + + } + + + //Connect to QB and fill + // IY: Create the session manager object using QBFC + QBSessionManager sessionManager = new QBSessionManager(); + + // IY: We want to know if we begun a session so we can end it if an + // error happens + bool booSessionBegun = false; + + try + { + + + //Import seems safe... + + // IY: Get the RequestMsgSet based on the correct QB Version + IMsgSetRequest requestSet = getLatestMsgSetRequest(sessionManager); + + // IY: Initialize the message set request object + requestSet.Attributes.OnError = ENRqOnError.roeStop; + + // IY: Add the request to the message set request object + IItemInventoryAdd ca = requestSet.AppendItemInventoryAddRq(); + //create a new row to add to the client cache datatable + DataRow dr = _dtQBItems.NewRow(); + dr["FullName"] = sName; + dr["Type"] = qbitemtype.Inventory; + dr["Price"] = c.Retail; + dr["Cost"] = c.Cost; + dr["SalesDesc"] = sDescription; + dr["ReorderPoint"] = 0; + dr["Modified"] = DateTime.MinValue; + dr["VendorID"] = c.WholesalerID.ToString(); + + //------------------------ + //Set the qb item values + ca.Name.SetValue(sName); + ca.IncomeAccountRef.ListID.SetValue(QDat.QBInventoryIncomeAccountReference); + ca.COGSAccountRef.ListID.SetValue(QDat.QBInventoryCOGSAccountRef); + ca.AssetAccountRef.ListID.SetValue(QDat.QBInventoryAssetAccountRef); + ca.SalesDesc.SetValue(sDescription); + ca.PurchaseDesc.SetValue(sDescription); + + ca.SalesPrice.SetValue((double)c.Retail); + ca.PurchaseCost.SetValue((double)c.Cost); + if (AyaBizUtils.GlobalSettings.UseInventory) + { + PartInventoryValuesFetcher pbw = PartInventoryValuesFetcher.GetItem(c.ID); + ca.QuantityOnHand.SetValue((double)pbw.QuantityOnHand); + ca.ReorderPoint.SetValue((double)pbw.MinStockLevel); + } + //------------------------ + + + //This is intended to be called after already sucessfully connected + //to get version info so no special safety checks here + sessionManager.OpenConnection2("", "AyaNova QBI", ENConnectionType.ctLocalQBDLaunchUI); + sessionManager.BeginSession("", ENOpenMode.omDontCare); + booSessionBegun = true; + + + IMsgSetResponse responseSet = sessionManager.DoRequests(requestSet); + + // Uncomment the following to view and save the request and response XML + //string requestXML = requestSet.ToXMLString(); + //MessageBox.Show(requestXML); + // SaveXML(requestXML); + //string responseXML = responseSet.ToXMLString(); + //MessageBox.Show(responseXML); + // SaveXML(responseXML); + + IResponse response = responseSet.ResponseList.GetAt(0); + //nonzero indicates an error this is unrecoverable + //so throw an exception + + if (response.StatusCode != 0) + { + throw new ApplicationException(response.StatusMessage + " Code: " + response.StatusCode); + + } + + IItemInventoryRet cr = response.Detail as IItemInventoryRet; + string sNewID = cr.ListID.GetValue(); + requestSet.ClearRequests(); + //---------------- + + + // Close the session and connection with QuickBooks + sessionManager.EndSession(); + booSessionBegun = false; + sessionManager.CloseConnection(); + + //catch the new ID for the QB Item + dr["ID"] = sNewID; + //add the new row for the newly imported object + _dtQBItems.Rows.Add(dr); + + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Part; + m.LastSync = DateTime.Now; + m.ForeignID = sNewID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + if (booSessionBegun) + { + sessionManager.EndSession(); + sessionManager.CloseConnection(); + } + + + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + alErrors.Add("ImportAyaPart: QuickBooks won't allow import of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + + + + + #endregion AyaNova part to Quickbooks + + #endregion part + + #region Rate case 632 + /// + /// Import the indicated service rate + /// to QuickBooks item record + /// + /// + /// An arraylist to hold strings indicating errors on fail + public static void ImportAyaRate(Guid RateID, RatePickList ratelist, ArrayList alErrors) + { + + if (!ratelist.Contains(RateID)) + { + alErrors.Add("ImportAyaRate: Rate not found in AyaNova (deleted recently?) (" + RateID.ToString() + ")"); + return; + + } + RatePickList.RatePickListInfo c = ratelist[RateID]; + + + + + string sName = c.Name; + if (sName.Length > 31) + { + sName = sName.Substring(0, 31); + alErrors.Add("ImportAyaRate: AyaNova Rate name exceeds 31 character limit for QuickBooks\r\n" + + "Name: " + c.Name + "\r\n" + + "will be imported as: " + sName); + + } + string sDescription = c.Description; + if (string.IsNullOrEmpty(sDescription)) sDescription = c.Name; + if (sDescription.Length > 4095) + { + sDescription = sDescription.Substring(0, 4095); + alErrors.Add("ImportAyaRate: AyaNova Rate description exceeds 4095 character limit for sales description in QuickBooks\r\n" + + "will be imported as: " + sDescription); + + } + + + //Connect to QB and fill + // IY: Create the session manager object using QBFC + QBSessionManager sessionManager = new QBSessionManager(); + + // IY: We want to know if we begun a session so we can end it if an + // error happens + bool booSessionBegun = false; + + try + { + + + //Import seems safe... + + // IY: Get the RequestMsgSet based on the correct QB Version + IMsgSetRequest requestSet = getLatestMsgSetRequest(sessionManager); + + // IY: Initialize the message set request object + requestSet.Attributes.OnError = ENRqOnError.roeStop; + + // IY: Add the request to the message set request object + IItemServiceAdd ca = requestSet.AppendItemServiceAddRq(); + //create a new row to add to the client cache datatable + DataRow dr = _dtQBItems.NewRow(); + dr["FullName"] = sName; + dr["Type"] = qbitemtype.Service; + dr["Price"] = c.Charge; + dr["Cost"] = c.Cost; + dr["SalesDesc"] = sDescription; + dr["ReorderPoint"] = 0; + dr["Modified"] = DateTime.MinValue; + dr["VendorID"] = ""; + + //------------------------ + //Set the qb item values + ca.Name.SetValue(sName); + ca.ORSalesPurchase.SalesOrPurchase.Desc.SetValue(sDescription); + ca.ORSalesPurchase.SalesOrPurchase.ORPrice.Price.SetValue((double)c.Charge); + ca.ORSalesPurchase.SalesOrPurchase.AccountRef.ListID.SetValue(QDat.QBServiceIncomeAccountRef); + //------------------------ + + + //This is intended to be called after already sucessfully connected + //to get version info so no special safety checks here + sessionManager.OpenConnection2("", "AyaNova QBI", ENConnectionType.ctLocalQBDLaunchUI); + sessionManager.BeginSession("", ENOpenMode.omDontCare); + booSessionBegun = true; + + + IMsgSetResponse responseSet = sessionManager.DoRequests(requestSet); + + // Uncomment the following to view and save the request and response XML + //string requestXML = requestSet.ToXMLString(); + //MessageBox.Show(requestXML); + // SaveXML(requestXML); + //string responseXML = responseSet.ToXMLString(); + //MessageBox.Show(responseXML); + // SaveXML(responseXML); + + IResponse response = responseSet.ResponseList.GetAt(0); + //nonzero indicates an error this is unrecoverable + //so throw an exception + + if (response.StatusCode != 0) + { + throw new ApplicationException(response.StatusMessage + " Code: " + response.StatusCode); + + } + + IItemServiceRet cr = response.Detail as IItemServiceRet; + string sNewID = cr.ListID.GetValue(); + requestSet.ClearRequests(); + //---------------- + + + // Close the session and connection with QuickBooks + sessionManager.EndSession(); + booSessionBegun = false; + sessionManager.CloseConnection(); + + //catch the new ID for the QB Item + dr["ID"] = sNewID; + //add the new row for the newly imported object + _dtQBItems.Rows.Add(dr); + + //Link + IntegrationMap m = QBI.Maps.Add(QBI); + m.Name = sName; + m.RootObjectID = c.ID; + m.RootObjectType = RootObjectTypes.Rate; + m.LastSync = DateTime.Now; + m.ForeignID = sNewID; + QBI = (Integration)QBI.Save(); + } + catch (Exception ex) + { + if (booSessionBegun) + { + sessionManager.EndSession(); + sessionManager.CloseConnection(); + } + + + //crack the exception in case it's a generic dataportal one + //and it is if it's got an inner exception of any kind + if (ex.InnerException != null) ex = ex.InnerException; + alErrors.Add("ImportAyaRate: QuickBooks won't allow import of " + sName + "\r\n" + + "Due to the following error:\r\n" + ex.Message); + + } + } + #endregion rate + + + private static string T(int nLength, string s) + { + if (s == null || s == "") return ""; + if (s.Length <= nLength) return s; + else + return s.Substring(0, nLength); + } + + #endregion export to quickbooks + + #endregion qb specific non-api stuff