This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
@@ -24,7 +25,6 @@
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
@@ -37,6 +37,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -51,7 +52,7 @@
|
||||
<Reference Include="Interop.QBFC15, Version=15.0.0.1, Culture=neutral, PublicKeyToken=31d8aec643e18259, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<HintPath>..\libs\QuickBooks\Interop.QBFC15.dll</HintPath>
|
||||
<HintPath>..\..\..\..\Program Files\Common Files\Intuit\QuickBooks\Interop.QBFC15.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
@@ -78,6 +79,12 @@
|
||||
<Compile Include="AuthorizationRoles.cs" />
|
||||
<Compile Include="AyaNovaLicense.cs" />
|
||||
<Compile Include="AyaType.cs" />
|
||||
<Compile Include="CopyableMessageBox.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CopyableMessageBox.Designer.cs">
|
||||
<DependentUpon>CopyableMessageBox.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Integration.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
@@ -101,6 +108,9 @@
|
||||
<EmbeddedResource Include="auth.resx">
|
||||
<DependentUpon>auth.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="CopyableMessageBox.resx">
|
||||
<DependentUpon>CopyableMessageBox.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
105
AyaNovaQBI/CopyableMessageBox.Designer.cs
generated
Normal file
105
AyaNovaQBI/CopyableMessageBox.Designer.cs
generated
Normal file
@@ -0,0 +1,105 @@
|
||||
namespace AyaNovaQBI
|
||||
{
|
||||
partial class CopyableMessageBox
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.edOut = new System.Windows.Forms.TextBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.btnCopy = new System.Windows.Forms.Button();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// edOut
|
||||
//
|
||||
this.edOut.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.edOut.Location = new System.Drawing.Point(0, 0);
|
||||
this.edOut.Multiline = true;
|
||||
this.edOut.Name = "edOut";
|
||||
this.edOut.ReadOnly = true;
|
||||
this.edOut.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.edOut.Size = new System.Drawing.Size(488, 356);
|
||||
this.edOut.TabIndex = 0;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.edOut);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(488, 356);
|
||||
this.panel1.TabIndex = 1;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.Controls.Add(this.btnCopy);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.panel2.Location = new System.Drawing.Point(0, 281);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(488, 75);
|
||||
this.panel2.TabIndex = 2;
|
||||
//
|
||||
// btnCopy
|
||||
//
|
||||
this.btnCopy.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCopy.Location = new System.Drawing.Point(135, 23);
|
||||
this.btnCopy.Name = "btnCopy";
|
||||
this.btnCopy.Size = new System.Drawing.Size(208, 40);
|
||||
this.btnCopy.TabIndex = 0;
|
||||
this.btnCopy.Text = "Copy all to clipboard";
|
||||
this.btnCopy.UseVisualStyleBackColor = true;
|
||||
this.btnCopy.Click += new System.EventHandler(this.btnCopy_Click);
|
||||
//
|
||||
// CopyableMessageBox
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(488, 356);
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Name = "CopyableMessageBox";
|
||||
this.ShowInTaskbar = false;
|
||||
this.Load += new System.EventHandler(this.CopyableMessageBox_Load);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox edOut;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private System.Windows.Forms.Button btnCopy;
|
||||
}
|
||||
}
|
||||
33
AyaNovaQBI/CopyableMessageBox.cs
Normal file
33
AyaNovaQBI/CopyableMessageBox.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
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 CopyableMessageBox : Form
|
||||
{
|
||||
private string mDisplay = string.Empty;
|
||||
public CopyableMessageBox(string Display)
|
||||
{
|
||||
InitializeComponent();
|
||||
mDisplay=Display;
|
||||
}
|
||||
|
||||
private void btnCopy_Click(object sender, EventArgs e)
|
||||
{
|
||||
Clipboard.SetData(System.Windows.Forms.DataFormats.Text, mDisplay);
|
||||
}
|
||||
|
||||
private void CopyableMessageBox_Load(object sender, EventArgs e)
|
||||
{
|
||||
edOut.Text = mDisplay;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
120
AyaNovaQBI/CopyableMessageBox.resx
Normal file
120
AyaNovaQBI/CopyableMessageBox.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -19,7 +19,7 @@ namespace AyaNovaQBI
|
||||
|
||||
async private void MainForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
|
||||
//Initialize
|
||||
StringBuilder initErrors = new StringBuilder();
|
||||
if (await util.InitializeQBI(initErrors) == false)
|
||||
|
||||
@@ -17,7 +17,7 @@ using System.Runtime.InteropServices;
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: ComVisible(true)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("82cd8e13-3297-472b-8c59-c4a50a69cb5c")]
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace AyaNovaQBI
|
||||
/// <remarks>
|
||||
/// Do not modify the definition of BuildAt as your changes will be discarded.
|
||||
/// </remarks>
|
||||
public static DateTime BuildAt { get { return new DateTime(637915929965140980); } } //--**
|
||||
public static DateTime BuildAt { get { return new DateTime(637915984703608685); } } //--**
|
||||
/// <summary>
|
||||
/// The program that time stamped it.
|
||||
/// </summary>
|
||||
|
||||
@@ -7,6 +7,9 @@ using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Interop.QBFC15;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AyaNovaQBI
|
||||
{
|
||||
@@ -456,6 +459,21 @@ namespace AyaNovaQBI
|
||||
#endregion
|
||||
|
||||
#region QB STUFF
|
||||
|
||||
|
||||
public static string QCountry = "US";
|
||||
public static double QVersion = 1.1;
|
||||
public static string QCompanyFile = "";
|
||||
public static string QCompanyName = "";
|
||||
public static string sLastRequestXML = "";
|
||||
|
||||
public enum pfstat
|
||||
{
|
||||
OK = 0,
|
||||
Failed = 1,
|
||||
Cancel = 2
|
||||
}
|
||||
|
||||
public static List<InvoiceableItem> GetInvoiceableItems()
|
||||
{
|
||||
var random = new Random();
|
||||
@@ -488,7 +506,7 @@ namespace AyaNovaQBI
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Get license
|
||||
var r = await GetAsync("license");
|
||||
ALicense = r.ObjectResponse["data"]["license"].ToObject<AyaNovaLicense>();
|
||||
@@ -518,30 +536,35 @@ namespace AyaNovaQBI
|
||||
return false;
|
||||
}
|
||||
|
||||
//PFC - integration object check (fetch or create if not present)
|
||||
//Need this early so can log any issues with other aspects
|
||||
if (!await IntegrationCheck(initErrors))
|
||||
return false;
|
||||
LOG_AVAILABLE = true;
|
||||
|
||||
|
||||
//PFC - Util.QBValidate stuff:
|
||||
//Validate QB connection can be made and open connection and start session with QB (see Util.QBValidate in v7
|
||||
try
|
||||
{
|
||||
|
||||
var pfstatus = await QBValidate();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
initErrors.AppendLine($"QuickBooks connection validation failed before connecting\r\n{ex.Message}");
|
||||
|
||||
return false;
|
||||
}
|
||||
//once connected collect the country, version we are dealing with (Util.qbValidate)
|
||||
//confirm qb is 2008 or newer and bail if not (util.qbvalidate)
|
||||
//cache company name and other qb info
|
||||
//PFC - PopulateQBListCache()
|
||||
//PFC - PopulateAyaListCache()
|
||||
//PFC - integration object check (fetch or create if not present)
|
||||
if (!await IntegrationCheck(initErrors))
|
||||
return false;
|
||||
|
||||
LOG_AVAILABLE = true;
|
||||
|
||||
//todo: logger needs to be enabled for integration next in a convenient to call util method and then make it work in UI
|
||||
await IntegrationLog("Test: boot up");
|
||||
for (int x = 0; x < 25; x++)
|
||||
await IntegrationLog($"Test entry {x}");
|
||||
|
||||
var res=await GetAsync($"integration/log/{QBIntegration.Id}");
|
||||
|
||||
//TODO: if QBIntegration.IntegrationData==null then nothing is set yet and it's fresh so trigger the setup stuff
|
||||
|
||||
//PFC - Validate settings, create if necessary (Util.ValidateSettings()) and save
|
||||
//TODO: if QBIntegration.IntegrationData==null then nothing is set yet and it's fresh so trigger the setup stuff
|
||||
|
||||
//PFC - verify integration mapped objects still exist at each end (Util.PreFlightCheck() line 199)
|
||||
//DONE
|
||||
|
||||
@@ -602,10 +625,277 @@ namespace AyaNovaQBI
|
||||
public static async Task IntegrationLog(string logLine)
|
||||
{
|
||||
|
||||
await PostAsync("integration/log", Newtonsoft.Json.JsonConvert.SerializeObject(new NameIdItem { Id=QBIntegration.Id, Name=logLine}));
|
||||
await PostAsync("integration/log", Newtonsoft.Json.JsonConvert.SerializeObject(new NameIdItem { Id = QBIntegration.Id, Name = logLine }));
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region PFC QB side
|
||||
/// <summary>
|
||||
/// Open QB connection
|
||||
/// gather info required for future
|
||||
/// transactions
|
||||
/// </summary>
|
||||
public async static Task<pfstat> QBValidate()
|
||||
{
|
||||
// We want to know if we begun a session so we can end it if an
|
||||
// error happens
|
||||
bool booSessionBegun = false;
|
||||
bool bConnected = false;
|
||||
// Create the session manager object using QBFC
|
||||
QBSessionManager sessionManager = new QBSessionManager();
|
||||
|
||||
while (!booSessionBegun)
|
||||
{
|
||||
try
|
||||
{
|
||||
sessionManager.OpenConnection2("", "AyaNova QBI", ENConnectionType.ctLocalQBDLaunchUI);
|
||||
bConnected = true;
|
||||
sessionManager.BeginSession("", ENOpenMode.omDontCare);
|
||||
booSessionBegun = true;
|
||||
|
||||
}
|
||||
catch (System.Runtime.InteropServices.COMException ex)
|
||||
{
|
||||
if (bConnected)
|
||||
sessionManager.CloseConnection();
|
||||
if (ex.ErrorCode == -2147220458 || ex.ErrorCode == -2147220472 || ex.Message.Contains("Could not start"))
|
||||
{
|
||||
|
||||
if (MessageBox.Show(
|
||||
"QuickBooks doesn't appear to be running on this computer.\r\n" +
|
||||
"Start QuickBooks and open your company file now before proceeding.",
|
||||
"AyaNova QBI: Pre flight check",
|
||||
MessageBoxButtons.RetryCancel, MessageBoxIcon.Information) == DialogResult.Cancel) return pfstat.Cancel;
|
||||
}
|
||||
else
|
||||
{
|
||||
await IntegrationLog("PFC: QBValidate connect unanticipated exception: " + ex.Message + "\r\nError code:" + ex.ErrorCode.ToString());
|
||||
MessageBox.Show(ex.Message + "\r\nError code:" + string.Format("(HRESULT:0x{0:X8})", ex.ErrorCode));
|
||||
return pfstat.Cancel;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
//Get the country and latest version supported
|
||||
QVersion = 0;
|
||||
QCountry = "US";//default
|
||||
|
||||
string[] versions = sessionManager.QBXMLVersionsForSession;
|
||||
double vers = 0;
|
||||
|
||||
Regex rxVersion = new Regex("[0-9.,]+", RegexOptions.Multiline | RegexOptions.Compiled);
|
||||
|
||||
foreach (string s in versions)
|
||||
{
|
||||
if (s.StartsWith("CA") || s.StartsWith("ca"))
|
||||
{
|
||||
QCountry = "CA";
|
||||
|
||||
}
|
||||
else if (s.StartsWith("UK") || s.StartsWith("uk"))
|
||||
{
|
||||
QCountry = "UK";
|
||||
|
||||
}
|
||||
|
||||
//case 262
|
||||
//strip out only numeric bit regardless of what text is in there
|
||||
//including commas if it's french canadian and using a comma instead of a decimal point
|
||||
//(the safe to double will handle the comma if present)
|
||||
string strVersionNumber = rxVersion.Match(s).Value;
|
||||
vers = SafeToDouble(strVersionNumber);
|
||||
|
||||
if (vers > QVersion)
|
||||
{
|
||||
QVersion = vers;
|
||||
}
|
||||
}
|
||||
|
||||
if (QVersion < 6.0)
|
||||
{
|
||||
await IntegrationLog("PFC: Failed, QuickBooks found is too old, 2008 or higher is required, prompted user to run QB update utility to be able to proceed");
|
||||
CopyableMessageBox cp = new CopyableMessageBox(
|
||||
|
||||
"You seem to be running QuickBooks older than 2008\r\n" +
|
||||
"You must update to 2008 or higher before you can use AyaNova QBI.\r\n\r\n" +
|
||||
"(If you are running QuickBooks 2008 or higher and still getting this error, ensure that you are also using QBFC7 or higher)\r\n\r\n" +
|
||||
"VERSION FOUND = " + QVersion
|
||||
|
||||
);
|
||||
|
||||
cp.ShowDialog();
|
||||
|
||||
return pfstat.Failed;
|
||||
}
|
||||
|
||||
|
||||
//Get the company file to open
|
||||
QCompanyFile = sessionManager.GetCurrentCompanyFileName();
|
||||
|
||||
// if(QCountry=="US")
|
||||
// {
|
||||
//Get company data
|
||||
// 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
|
||||
ICompanyQuery cq = requestSet.AppendCompanyQueryRq();
|
||||
|
||||
IMsgSetResponse responseSet = sessionManager.DoRequests(requestSet);
|
||||
IResponse response = responseSet.ResponseList.GetAt(0);
|
||||
if (response.StatusCode != 0)
|
||||
{
|
||||
await IntegrationLog("PFC: Failed Company query:" + response.StatusMessage + ", " + response.StatusCode.ToString());
|
||||
throw new ApplicationException("PFC: Failed Company query:" + response.StatusMessage + ", " + response.StatusCode.ToString());
|
||||
|
||||
}
|
||||
|
||||
ICompanyRet cl = response.Detail as ICompanyRet;
|
||||
QCompanyName = ProcessQBString(cl.CompanyName);
|
||||
requestSet.ClearRequests();
|
||||
//----------------
|
||||
// }
|
||||
// else
|
||||
// QCompanyName=QCompanyFile;
|
||||
|
||||
// Close the session and connection with QuickBooks
|
||||
sessionManager.EndSession();
|
||||
booSessionBegun = false;
|
||||
sessionManager.CloseConnection();
|
||||
return pfstat.OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//MessageBox.Show(ex.Message.ToString() + "\nStack Trace: \n" + ex.StackTrace + "\nExiting the application");
|
||||
|
||||
await IntegrationLog("PFC: Failed with exception:" + ex.Message);
|
||||
if (booSessionBegun)
|
||||
{
|
||||
sessionManager.EndSession();
|
||||
sessionManager.CloseConnection();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion pfc qb side
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region QB Specific utils
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sessionManager"></param>
|
||||
/// <returns></returns>
|
||||
public static IMsgSetRequest getLatestMsgSetRequest(QBSessionManager sessionManager)
|
||||
{
|
||||
// Find and adapt to supported version of QuickBooks
|
||||
short qbXMLMajorVer = 0;
|
||||
short qbXMLMinorVer = 0;
|
||||
|
||||
if (QVersion >= 5.0)
|
||||
{
|
||||
qbXMLMajorVer = 5;
|
||||
qbXMLMinorVer = 0;
|
||||
}
|
||||
else if (QVersion >= 4.0)
|
||||
{
|
||||
qbXMLMajorVer = 4;
|
||||
qbXMLMinorVer = 0;
|
||||
}
|
||||
else if (QVersion >= 3.0)
|
||||
{
|
||||
qbXMLMajorVer = 3;
|
||||
qbXMLMinorVer = 0;
|
||||
}
|
||||
else if (QVersion >= 2.0)
|
||||
{
|
||||
qbXMLMajorVer = 2;
|
||||
qbXMLMinorVer = 0;
|
||||
}
|
||||
else if (QVersion >= 1.1)
|
||||
{
|
||||
qbXMLMajorVer = 1;
|
||||
qbXMLMinorVer = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
qbXMLMajorVer = 1;
|
||||
qbXMLMinorVer = 0;
|
||||
throw new System.NotSupportedException("QuickBooks 1.0 (2002 initial release) is not supported, use QuickBooks online update feature now.");
|
||||
}
|
||||
|
||||
// Create the message set request object
|
||||
IMsgSetRequest requestMsgSet = sessionManager.CreateMsgSetRequest(QCountry, qbXMLMajorVer, qbXMLMinorVer);
|
||||
return requestMsgSet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle null qb string types with "aplomb" :)
|
||||
/// </summary>
|
||||
/// <param name="qs"></param>
|
||||
/// <returns></returns>
|
||||
private static string ProcessQBString(IQBStringType qs)
|
||||
{
|
||||
if (qs == null) return "";
|
||||
return qs.GetValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Case 262 addition
|
||||
/// Convert a string to a double handling french canadian locale
|
||||
/// , since qb is not locale aware in it's api
|
||||
/// conversion can fail because .net expects a comma that isn't there
|
||||
///
|
||||
/// case 262 redux, changed to use tryparse and explicitly replace comma if present
|
||||
/// for french canadian versions
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public static double SafeToDouble(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) return 0;
|
||||
if (s.Contains(","))
|
||||
s = s.Replace(",", ".");
|
||||
|
||||
double retvalue = 0;
|
||||
if (!double.TryParse(s, out retvalue))
|
||||
{
|
||||
try
|
||||
{
|
||||
retvalue = Convert.ToDouble(s, System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{
|
||||
CopyableMessageBox cp = new CopyableMessageBox("SafeToDouble: Can't parse QB string double version number:\r\n[" +
|
||||
s +
|
||||
"]\r\nPlease copy and send this message to AyaNova tech support at support@ayanova.com");
|
||||
cp.ShowDialog();
|
||||
throw new System.ApplicationException("SafeToDouble: Can't parse QB string double value number: \"" + s + "\"");
|
||||
}
|
||||
}
|
||||
return retvalue;
|
||||
}
|
||||
|
||||
#endregion qb specific utils
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion qb stuff
|
||||
|
||||
|
||||
}
|
||||
|
||||
BIN
libs/QuickBooks/QBFC15_0Installer.exe
Normal file
BIN
libs/QuickBooks/QBFC15_0Installer.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user