Added better error handling + added bulk handling of payable import BOD-152

This commit is contained in:
Patrick Fic
2020-06-04 09:52:17 -07:00
parent fe4cb24742
commit b9573b38f0
11 changed files with 202 additions and 27 deletions

View File

@@ -46,6 +46,9 @@
<setting name="AutoStartMonitor" serializeAs="String"> <setting name="AutoStartMonitor" serializeAs="String">
<value>True</value> <value>True</value>
</setting> </setting>
<setting name="QuickBooksFilePath" serializeAs="String">
<value />
</setting>
</BodyshopPartner.Properties.Settings> </BodyshopPartner.Properties.Settings>
</userSettings> </userSettings>
</configuration> </configuration>

View File

@@ -267,6 +267,60 @@ namespace BodyshopPartner.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Successfully connected to QuickBooks. Processing requests....
/// </summary>
public static string Msg_QbConnected_Msg {
get {
return ResourceManager.GetString("Msg_QbConnected_Msg", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to QuickBooks Connection.
/// </summary>
public static string Msg_QbConnected_Title {
get {
return ResourceManager.GetString("Msg_QbConnected_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please do not close ImEX Online or ImEX Partner during the connection process..
/// </summary>
public static string Msg_QbConnection_Msg {
get {
return ResourceManager.GetString("Msg_QbConnection_Msg", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to QuickBooks Connection Request.
/// </summary>
public static string Msg_QbConnection_Title {
get {
return ResourceManager.GetString("Msg_QbConnection_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Successfully disconnected from QuickBooks..
/// </summary>
public static string Msg_QbDisconnection_Msg {
get {
return ResourceManager.GetString("Msg_QbDisconnection_Msg", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to QuickBooks Disconnection.
/// </summary>
public static string Msg_QbDisconnection_Title {
get {
return ResourceManager.GetString("Msg_QbDisconnection_Title", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Password. /// Looks up a localized string similar to Password.
/// </summary> /// </summary>

View File

@@ -186,6 +186,24 @@
<data name="Msg_NewJobUploadError" xml:space="preserve"> <data name="Msg_NewJobUploadError" xml:space="preserve">
<value>Error uploading job.</value> <value>Error uploading job.</value>
</data> </data>
<data name="Msg_QbConnected_Msg" xml:space="preserve">
<value>Successfully connected to QuickBooks. Processing requests...</value>
</data>
<data name="Msg_QbConnected_Title" xml:space="preserve">
<value>QuickBooks Connection</value>
</data>
<data name="Msg_QbConnection_Msg" xml:space="preserve">
<value>Please do not close ImEX Online or ImEX Partner during the connection process.</value>
</data>
<data name="Msg_QbConnection_Title" xml:space="preserve">
<value>QuickBooks Connection Request</value>
</data>
<data name="Msg_QbDisconnection_Msg" xml:space="preserve">
<value>Successfully disconnected from QuickBooks.</value>
</data>
<data name="Msg_QbDisconnection_Title" xml:space="preserve">
<value>QuickBooks Disconnection</value>
</data>
<data name="Password" xml:space="preserve"> <data name="Password" xml:space="preserve">
<value>Password</value> <value>Password</value>
</data> </data>

View File

@@ -92,5 +92,17 @@ namespace BodyshopPartner.Properties {
this["AutoStartMonitor"] = value; this["AutoStartMonitor"] = value;
} }
} }
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string QuickBooksFilePath {
get {
return ((string)(this["QuickBooksFilePath"]));
}
set {
this["QuickBooksFilePath"] = value;
}
}
} }
} }

View File

@@ -20,5 +20,8 @@
<Setting Name="AutoStartMonitor" Type="System.Boolean" Scope="User"> <Setting Name="AutoStartMonitor" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value> <Value Profile="(Default)">True</Value>
</Setting> </Setting>
<Setting Name="QuickBooksFilePath" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>

View File

@@ -127,7 +127,7 @@
To="0" To="0"
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
Duration="0:0:1" Duration="0:0:1"
BeginTime="0:0:2" /> BeginTime="0:0:3" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</EventTrigger> </EventTrigger>

View File

@@ -46,28 +46,48 @@ namespace BodyshopPartner.Utils
List<QbRequestItem> AllRequests = ParseRequest(req); List<QbRequestItem> AllRequests = ParseRequest(req);
List<QbResponseItem> HttpResponse = new List<QbResponseItem>(); List<QbResponseItem> HttpResponse = new List<QbResponseItem>();
// string requestXMLstring = ParseBodyToString(req); hlog("Connecting to QuickBooks. This may take a moment...");
QuickBooksInterop.ConnectToQuickBooks();
foreach (QbRequestItem request in AllRequests) foreach (QbRequestItem request in AllRequests)
{ {
XDocument response = XDocument.Parse(QuickBooksInterop.ProcessQBXmlRequest(request.QbXML)); try
QbXmlResponse ResponseStatus = QuickBooksInterop.ParseResponseXml(response);
logger.Trace(response.ToString());
logger.Debug(ResponseStatus.ToString());
hlog(ResponseStatus.ToString());
QbResponseItem r = new QbResponseItem()
{ {
Id = request.Id, hlog("Processing QuickBooks request. ImEX Online Record ID:" + request.Id);
Success = ResponseStatus.StatusCode == "0" || request.OkStatusCodes.Contains(ResponseStatus.StatusCode), XDocument response = XDocument.Parse(QuickBooksInterop.ProcessQBXmlRequestUnManaged(request.QbXML));
ErrorMessage = ResponseStatus.StatusMessage QbXmlResponse ResponseStatus = QuickBooksInterop.ParseResponseXml(response);
};
logger.Trace(response.ToString());
logger.Debug(ResponseStatus.ToString());
hlog(ResponseStatus.ToString());
QbResponseItem r = new QbResponseItem()
{
Id = request.Id,
Success = ResponseStatus.StatusCode == "0" || request.OkStatusCodes.Contains(ResponseStatus.StatusCode),
ErrorMessage = ResponseStatus.StatusMessage
};
HttpResponse.Add(r);
}
catch (Exception Ex)
{
//Shouldn't really get here unless something is malformed.
logger.Error(Ex, "Error encountered when processing QbXML Request.\n {0}", request.QbXML);
QbResponseItem r = new QbResponseItem()
{
Id = request.Id,
Success = false,
ErrorMessage = Ex.Message
};
HttpResponse.Add(r);
}
HttpResponse.Add(r);
} }
QuickBooksInterop.DisconnectFromQuickBooks();
hlog("Completed QuickBooks request."); hlog("Completed QuickBooks requests.");
res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse)); res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse));
} }

View File

@@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
using BodyshopPartner.Utils.Growls;
using Interop.QBFC13; using Interop.QBFC13;
using Interop.QBXMLRP2; using Interop.QBXMLRP2;
@@ -16,20 +17,43 @@ namespace BodyshopPartner.Utils
private static string ticket; private static string ticket;
private static RequestProcessor2 rp; private static RequestProcessor2 rp;
private static string maxVersion; private static string maxVersion;
private static string companyFile = ""; //public static string companyFile; //= @"C:\Users\pfic\Development\QB Testing\Testing\DANS2014.QBW";
private static QBFileMode mode = QBFileMode.qbFileOpenDoNotCare; private static QBFileMode mode = QBFileMode.qbFileOpenDoNotCare;
private static string appID = "ImEXBSP"; private static string appID = "ImEXBSP";
private static string appName = "BodyshopPartner"; private static string appName = "BodyshopPartner";
private static GrowlNotification Growler;
public static void ConnectToQuickBooks() public static void ConnectToQuickBooks()
{ {
try try
{ {
logger.Debug("Attempting to connect to QuickBooks...");
App.Current.Dispatcher.Invoke(() =>
{
Growler.AddNotification(new Notification()
{
Id = new Random().Next(),
Title = Properties.Resources.Msg_QbConnection_Title,
Message = Properties.Resources.Msg_QbConnection_Msg
});
});
rp = new RequestProcessor2Class(); rp = new RequestProcessor2Class();
rp.OpenConnection(appID, appName); rp.OpenConnection(appID, appName);
ticket = rp.BeginSession(companyFile, mode); ticket = rp.BeginSession(Properties.Settings.Default.QuickBooksFilePath, mode);
string[] versions = rp.get_QBXMLVersionsForSession(ticket); string[] versions = rp.get_QBXMLVersionsForSession(ticket);
maxVersion = versions[versions.Length - 1]; maxVersion = versions[versions.Length - 1];
logger.Debug("Connected to QuickBooks. Ticket: " + ticket.ToString());
App.Current.Dispatcher.Invoke(() =>
{
Growler.AddNotification(new Notification()
{
Id = new Random().Next(),
Title = Properties.Resources.Msg_QbConnected_Title,
Message = Properties.Resources.Msg_QbConnected_Msg
});
});
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -47,6 +71,16 @@ namespace BodyshopPartner.Utils
rp.EndSession(ticket); rp.EndSession(ticket);
ticket = null; ticket = null;
rp.CloseConnection(); rp.CloseConnection();
App.Current.Dispatcher.Invoke(() =>
{
Growler.AddNotification(new Notification()
{
Id = new Random().Next(),
Title = Properties.Resources.Msg_QbDisconnection_Title,
Message = Properties.Resources.Msg_QbDisconnection_Msg
});
});
logger.Debug("Disconnected from QuickBooks successfully.");
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -70,7 +104,22 @@ namespace BodyshopPartner.Utils
return null; return null;
} }
} }
public static string ProcessQBXmlRequestUnManaged(string request)
{
try
{
//ConnectToQuickBooks();
var ret = rp.ProcessRequest(ticket, request);
//DisconnectFromQuickBooks();
return ret;
}
catch (Exception e)
{
logger.Error(e.Message);
// DisconnectFromQuickBooks();
return null;
}
}
public static Models.QbXmlResponse ParseResponseXml(XDocument response) public static Models.QbXmlResponse ParseResponseXml(XDocument response)
{ {
XElement QueryResponse = response.Root.Descendants("QBXMLMsgsRs").Descendants().FirstOrDefault(); XElement QueryResponse = response.Root.Descendants("QBXMLMsgsRs").Descendants().FirstOrDefault();
@@ -87,6 +136,10 @@ namespace BodyshopPartner.Utils
Response = response Response = response
}; };
} }
public static void SetGrowler(GrowlNotification g)
{
Growler = g;
}
} }
} }

View File

@@ -33,6 +33,7 @@ namespace BodyshopPartner.ViewModels
Growler = new GrowlNotification(this); Growler = new GrowlNotification(this);
Utils.JobProcessingQueue.SetGrowler(Growler); Utils.JobProcessingQueue.SetGrowler(Growler);
Utils.QuickBooksInterop.SetGrowler(Growler);
} }
private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
@@ -227,7 +228,7 @@ namespace BodyshopPartner.ViewModels
{ {
Notification _n = new Notification() Notification _n = new Notification()
{ {
Id = 123, Id = new Random().Next(),
Title = "This is a title", Title = "This is a title",
Subtitle = "Subtitle", Subtitle = "Subtitle",
Message = "Somethin" Message = "Somethin"

View File

@@ -21,6 +21,7 @@
FontFamily="{DynamicResource MaterialDesignFont}" FontFamily="{DynamicResource MaterialDesignFont}"
Loaded="Window_Loaded" Loaded="Window_Loaded"
xmlns:util="clr-namespace:BodyshopPartner.Utils" xmlns:util="clr-namespace:BodyshopPartner.Utils"
xmlns:properties="clr-namespace:BodyshopPartner.Properties"
Closing="Window_Closing"> Closing="Window_Closing">
<Window.DataContext> <Window.DataContext>
<vm:MainViewModel /> <vm:MainViewModel />
@@ -205,13 +206,17 @@
</DataGridTemplateColumn> </DataGridTemplateColumn>
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
<StackPanel Grid.Column="1"
Height="Auto">
<TextBox Text="{Binding Source={x:Static properties:Settings.Default},
Path=QuickBooksFilePath}"
materialDesign:HintAssist.Hint="QuickBooks File Path" TextChanged="TextBox_TextChanged"/>
<TextBox Height="Auto"
Text="{Binding HttpServerLog}"
TextWrapping="Wrap"
AcceptsReturn="True" />
</StackPanel>
<TextBox Grid.Column="1"
Height="Auto"
Text="{Binding HttpServerLog}"
TextWrapping="Wrap"
AcceptsReturn="True"
/>
</Grid> </Grid>
</DockPanel> </DockPanel>

View File

@@ -35,5 +35,11 @@ namespace BodyshopPartner.Views
e.Cancel = true ; e.Cancel = true ;
this.Hide(); this.Hide();
} }
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
Properties.Settings.Default.QuickBooksFilePath = ((System.Windows.Controls.TextBox)sender).Text;
Properties.Settings.Default.Save();
}
} }
} }