Skip to content

Commit 037ef9f

Browse files
authored
Merge pull request #89 from MoneyTools/clovet/CitibankVisa
Fix OFX parsing issue so that Citibank VISA cards
2 parents faf6a54 + b35142f commit 037ef9f

30 files changed

+541
-410
lines changed

Source/WPF/MoneyPackage/Package.appxmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap rescap">
3-
<Identity Name="43906ChrisLovett.MyMoney.Net" Publisher="CN=Chris Lovett, O=Chris Lovett, S=Washington, C=US" Version="2.1.0.2" />
3+
<Identity Name="43906ChrisLovett.MyMoney.Net" Publisher="CN=Chris Lovett, O=Chris Lovett, S=Washington, C=US" Version="2.1.0.3" />
44
<Properties>
55
<DisplayName>MyMoney.Net</DisplayName>
66
<PublisherDisplayName>Chris Lovett</PublisherDisplayName>

Source/WPF/MyMoney/Controls/MoneyDataGrid.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public MoneyDataGrid()
4747
Loaded += this.OnLoaded;
4848
}
4949

50+
protected override void OnExecutedCommitEdit(ExecutedRoutedEventArgs e)
51+
{
52+
// This is the code path that is executed when the unit test uses the InvokePattern to
53+
// commit the edit on the current edited row, but the default implementation in DataGrid
54+
// doesn't do anything useful, so we intercept it here so the row is actually committed.
55+
base.OnExecutedCommitEdit(e);
56+
}
57+
5058
public ContextMenu ParentMenu { get; set; }
5159

5260
private void OnLoaded(object sender, RoutedEventArgs e)
@@ -742,6 +750,11 @@ protected override void OnRowEditEnding(DataGridRowEditEndingEventArgs e)
742750

743751
private void OnStartEdit(DataGridColumn column, DataGridRow row, RoutedEventArgs args)
744752
{
753+
IEditableCollectionView iecv = this.Items as IEditableCollectionView;
754+
if (iecv != null)
755+
{
756+
757+
}
745758
Control editor = this.GetCellEditor(column, row, args);
746759
if (editor != null)
747760
{

Source/WPF/MyMoney/Database/Money.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ public partial class MyMoney : PersistentObject
705705
internal PayeeIndex payeeAccountIndex;
706706
private bool watching;
707707

708-
internal static Type[] GetKnownTypes()
708+
public static Type[] GetKnownTypes()
709709
{
710710
return new Type[]
711711
{

Source/WPF/MyMoney/Dialogs/OnlineAccountDialog.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
Title="Online Account"
1515
WindowStartupLocation="CenterOwner"
1616
WindowStyle="ToolWindow"
17-
SizeToContent="WidthAndHeight"
18-
MinWidth="700"
17+
SizeToContent="Height"
18+
MinWidth="700" Width="850"
1919
d:DesignHeight="600" d:DesignWidth="900">
2020

2121
<Window.Resources>

Source/WPF/MyMoney/Ofx/Ofx.cs

Lines changed: 21 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Diagnostics;
77
using System.IO;
88
using System.Linq;
9-
using System.Net;
109
using System.Net.Http;
1110
using System.Net.Http.Headers;
1211
using System.Net.NetworkInformation;
@@ -348,7 +347,7 @@ private static XDocument LoadXmlStream(Stream fs)
348347
settings.ProhibitDtd = false;
349348
#pragma warning restore 618
350349
settings.ValidationType = ValidationType.None;
351-
using (XmlReader reader = new StringTrimmingXmlReader(XmlReader.Create(fs, settings)))
350+
using (XmlReader reader = XmlReader.Create(fs, settings))
352351
{
353352
return XDocument.Load(reader);
354353
}
@@ -1025,43 +1024,6 @@ private async Task<XDocument> SendOfxRequest(XDocument doc, string oldFileUid, s
10251024
}
10261025
}
10271026

1028-
private string RemoveIndents(string msg)
1029-
{
1030-
StringBuilder sb = new StringBuilder();
1031-
foreach (string line in msg.Split('\n'))
1032-
{
1033-
sb.Append(line.Trim());
1034-
sb.Append("\n");
1035-
}
1036-
return sb.ToString();
1037-
}
1038-
1039-
private static string GetHttpHeaders(HttpWebResponse response)
1040-
{
1041-
string headers = string.Empty;
1042-
WebHeaderCollection col = response.Headers;
1043-
foreach (string key in col.AllKeys)
1044-
{
1045-
headers += key + "=" + col[key] + "<br/>";
1046-
}
1047-
return headers;
1048-
}
1049-
1050-
private static string GetResponseBody(HttpWebResponse resp)
1051-
{
1052-
try
1053-
{
1054-
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
1055-
{
1056-
return sr.ReadToEnd();
1057-
}
1058-
}
1059-
catch
1060-
{
1061-
return null;
1062-
}
1063-
}
1064-
10651027
private static void EnsurePathExists(string path)
10661028
{
10671029
if (!Directory.Exists(path))
@@ -1310,6 +1272,7 @@ internal static OFX DeserializeOfxResponse(XDocument doc)
13101272
{
13111273
try
13121274
{
1275+
StripWhitespace(doc);
13131276
OFX ofx;
13141277
XmlSerializer s = new XmlSerializer(typeof(OFX));
13151278
using (XmlReader r = XmlReader.Create(new StringReader(doc.ToString())))
@@ -1838,8 +1801,22 @@ private static string GetLogFileLocation(XDocument doc)
18381801
return null;
18391802
}
18401803

1804+
private static void StripWhitespace(XDocument doc)
1805+
{
1806+
foreach (var node in doc.DescendantNodes())
1807+
{
1808+
if (node is XText t)
1809+
{
1810+
t.Value = t.Value.Trim();
1811+
}
1812+
}
1813+
}
1814+
18411815
public void ProcessResponse(XDocument doc, OfxDownloadData results)
18421816
{
1817+
// So we don't have to do a .Trim() on every single selected value when parsing the response.
1818+
StripWhitespace(doc);
1819+
18431820
XElement root = doc.Root;
18441821
if (root == null || root.Name.LocalName != "OFX")
18451822
{
@@ -1869,7 +1846,7 @@ public void ProcessResponse(XDocument doc, OfxDownloadData results)
18691846
e = doc.SelectElement("OFX/SIGNONMSGSRSV1/SONRS/STATUS/MESSAGE");
18701847
if (e != null)
18711848
{
1872-
message += e.Value.Trim();
1849+
message += e.Value;
18731850
results.AddError(this.OnlineAccount, this.Account, message);
18741851
}
18751852
return;
@@ -1920,7 +1897,7 @@ public void ProcessResponse(XDocument doc, OfxDownloadData results)
19201897
e = child.SelectElement("*/STATUS/MESSAGE");
19211898
if (e != null)
19221899
{
1923-
message += e.Value.Trim();
1900+
message += e.Value;
19241901
results.AddError(this.OnlineAccount, this.Account, message);
19251902
}
19261903
}
@@ -3472,14 +3449,14 @@ private static string ProcessStatementStatus(XElement tr, Account a)
34723449
if (statusElement != null)
34733450
{
34743451
XElement sc = statusElement.Element("CODE");
3475-
if (sc != null && sc.Value.Trim() != "0")
3452+
if (sc != null && sc.Value != "0")
34763453
{
34773454
string msg = (a == null) ? string.Empty : a.Name + ": ";
34783455
XElement severity = statusElement.Element("SEVERITY");
34793456
string reason = null;
34803457
if (severity != null)
34813458
{
3482-
reason = severity.Value?.Trim();
3459+
reason = severity.Value;
34833460
}
34843461
XElement message = statusElement.Element("MESSAGE");
34853462
if (message != null)
@@ -3489,7 +3466,7 @@ private static string ProcessStatementStatus(XElement tr, Account a)
34893466
reason += ", ";
34903467
}
34913468

3492-
reason += message.Value?.Trim();
3469+
reason += message.Value;
34933470
}
34943471
return msg + reason;
34953472
}
@@ -3829,107 +3806,5 @@ private void HandleChallenge(OFX ofx)
38293806
HelpLink = challengeLog
38303807
});
38313808
}
3832-
3833-
3834-
}
3835-
3836-
internal class StringTrimmingXmlReader : XmlReader
3837-
{
3838-
private readonly XmlReader inner;
3839-
public StringTrimmingXmlReader(XmlReader inner)
3840-
{
3841-
this.inner = inner;
3842-
}
3843-
3844-
protected override void Dispose(bool disposing)
3845-
{
3846-
this.inner.Dispose();
3847-
base.Dispose(disposing);
3848-
}
3849-
3850-
public override XmlNodeType NodeType => this.inner.NodeType;
3851-
3852-
public override string LocalName => this.inner.LocalName;
3853-
3854-
public override string NamespaceURI => this.inner.NamespaceURI;
3855-
3856-
public override string Prefix => this.inner.Prefix;
3857-
3858-
public override string Value => this.inner.Value?.Trim();
3859-
3860-
public override int Depth => this.inner.Depth;
3861-
3862-
public override string BaseURI => this.inner.BaseURI;
3863-
3864-
public override bool IsEmptyElement => this.inner.IsEmptyElement;
3865-
3866-
public override int AttributeCount => this.inner.AttributeCount;
3867-
3868-
public override bool EOF => this.inner.EOF;
3869-
3870-
public override ReadState ReadState => this.inner.ReadState;
3871-
3872-
public override XmlNameTable NameTable => this.inner.NameTable;
3873-
3874-
public override string GetAttribute(string name)
3875-
{
3876-
return this.inner.GetAttribute(name);
3877-
}
3878-
3879-
public override string GetAttribute(string name, string namespaceURI)
3880-
{
3881-
return this.inner.GetAttribute(name, namespaceURI);
3882-
}
3883-
3884-
public override string GetAttribute(int i)
3885-
{
3886-
return this.inner.GetAttribute(i);
3887-
}
3888-
3889-
public override string LookupNamespace(string prefix)
3890-
{
3891-
return this.inner.LookupNamespace(prefix);
3892-
}
3893-
3894-
public override bool MoveToAttribute(string name)
3895-
{
3896-
return this.inner.MoveToAttribute(name);
3897-
}
3898-
3899-
public override bool MoveToAttribute(string name, string ns)
3900-
{
3901-
return this.inner.MoveToAttribute(name, ns);
3902-
}
3903-
3904-
public override bool MoveToElement()
3905-
{
3906-
return this.inner.MoveToElement();
3907-
}
3908-
3909-
public override bool MoveToFirstAttribute()
3910-
{
3911-
return this.inner.MoveToFirstAttribute();
3912-
}
3913-
3914-
public override bool MoveToNextAttribute()
3915-
{
3916-
return this.inner.MoveToNextAttribute();
3917-
}
3918-
3919-
public override bool Read()
3920-
{
3921-
return this.inner.Read();
3922-
}
3923-
3924-
public override bool ReadAttributeValue()
3925-
{
3926-
return this.inner.ReadAttributeValue();
3927-
}
3928-
3929-
public override void ResolveEntity()
3930-
{
3931-
this.inner.ResolveEntity();
3932-
}
39333809
}
3934-
39353810
}

Source/WPF/MyMoney/Properties/PublishProfiles/ClickOnceProfile.pubxml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
44
-->
55
<Project>
66
<PropertyGroup>
7-
<ApplicationRevision>2</ApplicationRevision>
8-
<ApplicationVersion>2.1.0.2</ApplicationVersion>
7+
<ApplicationRevision>3</ApplicationRevision>
8+
<ApplicationVersion>2.1.0.3</ApplicationVersion>
99
<BootstrapperEnabled>True</BootstrapperEnabled>
1010
<Configuration>Release</Configuration>
1111
<CreateWebPageOnPublish>True</CreateWebPageOnPublish>

Source/WPF/MyMoney/Setup/changes.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<changes>
3+
<change version="2.1.0.3" date="2/5/2022">
4+
- Fix OFX parsing issue so that Citibank VISA cards Connect dialog works properly.
5+
- Fix online banking documentation &amp; screenshots.
6+
- Add backslash escaping support to escape a double quote in the quickfilter search box.
7+
</change>
38
<change version="2.1.0.2" date="1/30/2022">
49
- Fix problem with open file dialog, where it was incorrectly inserting password from windows credential store on Sqllite databases.
510
- Fix misleading documentation about Sqllite passwords.

0 commit comments

Comments
 (0)