public void Sync() { // Disable the buttons. IsExitEnabled = false; IsTryEnabled = false; IsStartOverEnabled = false; OnPropertyChanged("IsExitEnabled"); OnPropertyChanged("IsTryEnabled"); OnPropertyChanged("IsStartOverEnabled"); // Reset error count. ValidationErrorCount = 0; SaveErrorCount = 0; StatusText = string.Format("{0} - Starting.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); // ------------------------------------------------------------ // Ensure the vendor name is specified. // ------------------------------------------------------------ if (string.IsNullOrEmpty(vendorFullName)) { StatusText = string.Format("{0} - Must specify the InventoryConsumptionVendorName in the configuration.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); // Enable the buttons. IsExitEnabled = true; IsTryEnabled = true; IsStartOverEnabled = true; OnPropertyChanged("IsExitEnabled"); OnPropertyChanged("IsTryEnabled"); OnPropertyChanged("IsStartOverEnabled"); return; } // ------------------------------------------------------------ // Prepare the QuickBooks connection. // ------------------------------------------------------------ var service = new QuickBooksService(); StatusText += string.Format("{0} - Connecting to QuickBooks.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); // QBXML request processor must always be closed after use. var req = new RequestProcessor2(); try { req.OpenConnection2("", "BRIZBEE Integration Utility", QBXMLRPConnectionType.localQBD); var ticket = req.BeginSession("", QBFileMode.qbFileOpenDoNotCare); var companyFileName = req.GetCurrentCompanyFileName(ticket); StatusText += string.Format("{0} - Syncing.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); // Determine the method of recording consumption. if (selectedMethod == "Inventory Adjustment") { StatusText += string.Format("{0} - Using {1} method.\r\n", DateTime.Now.ToString(), selectedMethod); OnPropertyChanged("StatusText"); } else if (selectedMethod == "Sales Receipt") { StatusText += string.Format("{0} - Using {1} method and {2} value.\r\n", DateTime.Now.ToString(), selectedMethod, selectedValue); OnPropertyChanged("StatusText"); } else if (selectedMethod == "Bill") { StatusText += string.Format("{0} - Using {1} method and {2} value with {3} vendor.\r\n", DateTime.Now.ToString(), selectedMethod, selectedValue, vendorFullName); OnPropertyChanged("StatusText"); } // ------------------------------------------------------------ // Collect the QuickBooks host details. // ------------------------------------------------------------ // Prepare a new QBXML document. var hostQBXML = service.MakeQBXMLDocument(); var hostDocument = hostQBXML.Item1; var hostElement = hostQBXML.Item2; service.BuildHostQueryRq(hostDocument, hostElement); // Make the request. Logger.Debug(hostDocument.OuterXml); var hostResponse = req.ProcessRequest(ticket, hostDocument.OuterXml); Logger.Debug(hostResponse); // Then walk the response. var hostWalkResponse = service.WalkHostQueryRsAndParseHostDetails(hostResponse); var hostDetails = hostWalkResponse.Item3; // ------------------------------------------------------------ // Collect any unsynced consumption. // ------------------------------------------------------------ var consumptions = GetConsumption(); var txnIds = new List <string>(consumptions.Count); if (consumptions.Count == 0) { StatusText += string.Format("{0} - There is no inventory consumption to sync.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); } else { // ------------------------------------------------------------ // Record the unsynced consumptions. // ------------------------------------------------------------ // Build the request to store consumptions. if (selectedMethod == "Sales Receipt") { // Prepare a new QBXML document. var consQBXML = service.MakeQBXMLDocument(); var consDocument = consQBXML.Item1; var consElement = consQBXML.Item2; service.BuildSalesReceiptAddRq(consDocument, consElement, consumptions, selectedValue.ToUpperInvariant()); // Make the request. Logger.Debug(consDocument.OuterXml); var consResponse = req.ProcessRequest(ticket, consDocument.OuterXml); Logger.Debug(consResponse); // Then walk the response. var walkReponse = service.WalkSalesReceiptAddRs(consResponse); txnIds = walkReponse.Item3; } else if (selectedMethod == "Bill") { foreach (var consumption in consumptions) { // Prepare a new QBXML document. var consQBXML = service.MakeQBXMLDocument(); var consDocument = consQBXML.Item1; var consElement = consQBXML.Item2; service.BuildBillAddRq(consDocument, consElement, consumption, vendorFullName, refNumber, selectedValue.ToUpperInvariant()); // Make the request. Logger.Debug(consDocument.OuterXml); var consResponse = req.ProcessRequest(ticket, consDocument.OuterXml); Logger.Debug(consResponse); // Then walk the response. var walkReponse = service.WalkBillAddRs(consResponse); txnIds = txnIds.Concat(walkReponse.Item3).ToList(); } } else if (selectedMethod == "Inventory Adjustment") { // Prepare a new QBXML document. var consQBXML = service.MakeQBXMLDocument(); var consDocument = consQBXML.Item1; var consElement = consQBXML.Item2; service.BuildInventoryAdjustmentAddRq(consDocument, consElement, consumptions, selectedValue.ToUpperInvariant()); // Make the request. Logger.Debug(consDocument.OuterXml); var consResponse = req.ProcessRequest(ticket, consDocument.OuterXml); Logger.Debug(consResponse); // Then walk the response. var walkReponse = service.WalkInventoryAdjustmentAddRs(consResponse); txnIds = walkReponse.Item3; } if (SaveErrorCount > 0) { StatusText += string.Format("{0} - Sync failed. Please correct the {1} errors first.\r\n", DateTime.Now.ToString(), SaveErrorCount); OnPropertyChanged("StatusText"); var transactionType = ""; switch (selectedMethod) { case "Sales Receipt": transactionType = "SalesReceipt"; break; case "Bill": transactionType = "Bill"; break; case "Inventory Adjustment": transactionType = "InventoryAdjustment"; break; } // Reverse the transactions. foreach (var txnId in txnIds) { // Prepare a new QBXML document. var delQBXML = service.MakeQBXMLDocument(); var delDocument = delQBXML.Item1; var delElement = delQBXML.Item2; service.BuildTxnDelRq(delDocument, delElement, transactionType, txnId); // InventoryAdjustment, SalesReceipt, or Bill // Make the request. Logger.Debug(delDocument.OuterXml); var delResponse = req.ProcessRequest(ticket, delDocument.OuterXml); Logger.Debug(delResponse); // Then walk the response. var delWalkResponse = service.WalkTxnDelRs(delResponse); } } else { // Build the payload. var payload = new { TxnIDs = txnIds, Ids = consumptions.Select(c => c.Id).ToArray() }; // Build the request to send the sync details. var syncHttpRequest = new RestRequest("api/QBDInventoryConsumptions/Sync", Method.POST); syncHttpRequest.AddJsonBody(payload); syncHttpRequest.AddQueryParameter("recordingMethod", selectedMethod); syncHttpRequest.AddQueryParameter("valueMethod", selectedValue); syncHttpRequest.AddQueryParameter("productName", hostDetails.QBProductName); syncHttpRequest.AddQueryParameter("majorVersion", hostDetails.QBMajorVersion); syncHttpRequest.AddQueryParameter("minorVersion", hostDetails.QBMinorVersion); syncHttpRequest.AddQueryParameter("country", hostDetails.QBCountry); syncHttpRequest.AddQueryParameter("supportedQBXMLVersion", hostDetails.QBSupportedQBXMLVersions); syncHttpRequest.AddQueryParameter("hostname", Environment.MachineName); syncHttpRequest.AddQueryParameter("companyFilePath", companyFileName); // Execute request. var syncHttpResponse = client.Execute(syncHttpRequest); if ((syncHttpResponse.ResponseStatus == ResponseStatus.Completed) && (syncHttpResponse.StatusCode == System.Net.HttpStatusCode.OK)) { StatusText += string.Format("{0} - Synced Successfully.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); } else { StatusText += $"{DateTime.Now} - {syncHttpResponse.Content}"; StatusText += string.Format("{0} - Sync failed.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); } } } // Close the QuickBooks connection. req.EndSession(ticket); req.CloseConnection(); req = null; } catch (DownloadFailedException) { StatusText += string.Format("{0} - Sync failed. Could not download consumption from the server.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); } catch (COMException cex) { Logger.Error(cex.ToString()); if ((uint)cex.ErrorCode == 0x80040408) { StatusText += string.Format("{0} - Sync failed. QuickBooks Desktop is not open.\r\n", DateTime.Now.ToString()); OnPropertyChanged("StatusText"); } else { StatusText += string.Format("{0} - Sync failed. {1}\r\n", DateTime.Now.ToString(), cex.Message); OnPropertyChanged("StatusText"); } } catch (Exception ex) { Logger.Error(ex.ToString()); StatusText += string.Format("{0} - Sync failed. {1}\r\n", DateTime.Now.ToString(), ex.Message); OnPropertyChanged("StatusText"); } finally { // Enable the buttons. IsExitEnabled = true; IsTryEnabled = true; IsStartOverEnabled = true; OnPropertyChanged("IsExitEnabled"); OnPropertyChanged("IsTryEnabled"); OnPropertyChanged("IsStartOverEnabled"); // Try to close the QuickBooks connection if it is still open. if (req != null) { req.CloseConnection(); req = null; } } }