From b013281de8e97d4d60155299d46476727ad154da Mon Sep 17 00:00:00 2001 From: Henrique Netzka Date: Tue, 15 Oct 2019 11:34:55 -0300 Subject: [PATCH 1/2] small bug fixes: - ToDate() would throw an exception if the date was "zero"; - Amount field eventually brings "," as the decimal separator --- Lib/OfxHelperMethods.cs | 3 ++- Lib/Transaction.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/OfxHelperMethods.cs b/Lib/OfxHelperMethods.cs index eba5ba5..328ccf3 100644 --- a/Lib/OfxHelperMethods.cs +++ b/Lib/OfxHelperMethods.cs @@ -38,7 +38,8 @@ public static DateTime ToDate(this string date) } catch { - throw new OfxParseException("Unable to parse date"); + return DateTime.MinValue; + //throw new OfxParseException("Unable to parse date"); } } diff --git a/Lib/Transaction.cs b/Lib/Transaction.cs index e657060..7bcc68f 100644 --- a/Lib/Transaction.cs +++ b/Lib/Transaction.cs @@ -53,7 +53,7 @@ public Transaction(XmlNode node, string currency) try { - Amount = Convert.ToDecimal(node.GetValue("//TRNAMT"), CultureInfo.InvariantCulture); + Amount = Convert.ToDecimal(node.GetValue("//TRNAMT").Replace(",", "."), CultureInfo.InvariantCulture); } catch (Exception ex) { From d45f0e3cdc1c525e91ec40cb37a36c5226ff9e1d Mon Sep 17 00:00:00 2001 From: Henrique Netzka Date: Mon, 13 Dec 2021 16:57:17 -0300 Subject: [PATCH 2/2] changes to accept mal-formed ofx --- Lib/Balance.cs | 31 +++++++++++++++++++------------ Lib/OfxDocumentParser.cs | 6 +++--- Lib/OfxHelperMethods.cs | 9 ++++++++- Lib/Resources.Designer.cs | 38 +++++++++++++++++++------------------- 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/Lib/Balance.cs b/Lib/Balance.cs index 37c3935..e2d4887 100644 --- a/Lib/Balance.cs +++ b/Lib/Balance.cs @@ -20,18 +20,21 @@ public Balance(XmlNode ledgerNode, XmlNode avaliableNode) if (!String.IsNullOrEmpty(tempLedgerBalance)) { - // ***** Forced Invariant Culture. - // If you don't force it, it will use the computer's default (defined in windows control panel, regional settings) - // So, if the number format of the computer in use it's different from OFX standard (i suppose the english/invariant), - // the next line of could crash or (worse) the number would be wrongly interpreted. - // For example, my computer has a brazilian regional setting, with "." as thousand separator and "," as - // decimal separator, so the value "10.99" (ten 'dollars' (or whatever currency) and ninetynine cents) would be interpreted as "1099" - // (one thousand and ninetynine dollars - the "." would be ignored) - LedgerBalance = Convert.ToDecimal(tempLedgerBalance, CultureInfo.InvariantCulture); + // ***** Forced Invariant Culture. + // If you don't force it, it will use the computer's default (defined in windows control panel, regional settings) + // So, if the number format of the computer in use it's different from OFX standard (i suppose the english/invariant), + // the next line of could crash or (worse) the number would be wrongly interpreted. + // For example, my computer has a brazilian regional setting, with "." as thousand separator and "," as + // decimal separator, so the value "10.99" (ten 'dollars' (or whatever currency) and ninetynine cents) would be interpreted as "1099" + // (one thousand and ninetynine dollars - the "." would be ignored) + try + { + LedgerBalance = Convert.ToDecimal(tempLedgerBalance, CultureInfo.InvariantCulture); + } catch { } } else { - throw new OfxParseException("Ledger balance has not been set"); + //throw new OfxParseException("Ledger balance has not been set"); } // ***** OFX files from my bank don't have the 'avaliableNode' node, so i manage a null situation @@ -51,12 +54,16 @@ public Balance(XmlNode ledgerNode, XmlNode avaliableNode) if (!String.IsNullOrEmpty(tempAvaliableBalance)) { - // ***** Forced Invariant Culture. (same commment as above) - AvaliableBalance = Convert.ToDecimal(tempAvaliableBalance, CultureInfo.InvariantCulture); + // ***** Forced Invariant Culture. (same commment as above) + try + { + AvaliableBalance = Convert.ToDecimal(tempAvaliableBalance, CultureInfo.InvariantCulture); + } + catch { } } else { - throw new OfxParseException("Avaliable balance has not been set"); + //throw new OfxParseException("Avaliable balance has not been set"); } AvaliableBalanceDate = avaliableNode.GetValue("//DTASOF").ToDate(); } diff --git a/Lib/OfxDocumentParser.cs b/Lib/OfxDocumentParser.cs index 6d39171..1214d1a 100644 --- a/Lib/OfxDocumentParser.cs +++ b/Lib/OfxDocumentParser.cs @@ -54,7 +54,7 @@ private OfxDocument Parse(string ofxString) } else { - throw new OfxParseException("Currency not found"); + ofx.Currency = "BRL"; // default :) } //Get sign on node from OFX file @@ -256,7 +256,7 @@ private void CheckHeader(string[] header) if (header[1] != "DATA:OFXSGML") throw new OfxParseException("Data type unsupported: " + header[1] + ". OFXSGML required"); - + /* if (header[2] != "VERSION:102") throw new OfxParseException("OFX version unsupported. " + header[2]); @@ -273,7 +273,7 @@ private void CheckHeader(string[] header) throw new OfxParseException("Compression unsupported"); if (header[7] != "OLDFILEUID:NONE") - throw new OfxParseException("OLDFILEUID incorrect"); + throw new OfxParseException("OLDFILEUID incorrect");*/ } #region Nested type: OFXSection diff --git a/Lib/OfxHelperMethods.cs b/Lib/OfxHelperMethods.cs index 328ccf3..c5d9647 100644 --- a/Lib/OfxHelperMethods.cs +++ b/Lib/OfxHelperMethods.cs @@ -56,7 +56,14 @@ public static string GetValue(this XmlNode node, string xpath) fixedNode.Load(new StringReader(node.OuterXml)); var tempNode = fixedNode.SelectSingleNode(xpath); - return tempNode != null ? tempNode.FirstChild.Value : ""; + try + { + return tempNode != null ? tempNode.FirstChild.Value : ""; + } + catch { + // Colocado pois se o nó estava vazio, levantava exceção - o Sicredi tem nós vazios + return ""; + } } } } \ No newline at end of file diff --git a/Lib/Resources.Designer.cs b/Lib/Resources.Designer.cs index 205c987..4b49e77 100644 --- a/Lib/Resources.Designer.cs +++ b/Lib/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.34003 +// O código foi gerado por uma ferramenta. +// Versão de Tempo de Execução:4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se +// o código for gerado novamente. // //------------------------------------------------------------------------------ @@ -13,13 +13,13 @@ namespace OfxSharpLib { /// - /// A strongly-typed resource class, for looking up localized strings, etc. + /// Uma classe de recurso de tipo de alta segurança, para pesquisar cadeias de caracteres localizadas etc. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + // Essa classe foi gerada automaticamente pela classe StronglyTypedResourceBuilder + // através de uma ferramenta como ResGen ou Visual Studio. + // Para adicionar ou remover um associado, edite o arquivo .ResX e execute ResGen novamente + // com a opção /str, ou recrie o projeto do VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -33,7 +33,7 @@ internal Resources() { } /// - /// Returns the cached ResourceManager instance used by this class. + /// Retorna a instância de ResourceManager armazenada em cache usada por essa classe. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { @@ -47,8 +47,8 @@ internal Resources() { } /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. + /// Substitui a propriedade CurrentUICulture do thread atual para todas as + /// pesquisas de recursos que usam essa classe de recurso de tipo de alta segurança. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { @@ -61,7 +61,7 @@ internal Resources() { } /// - /// Looks up a localized string similar to OFX/BANKMSGSRSV1/STMTTRNRS/. + /// Consulta uma cadeia de caracteres localizada semelhante a OFX/BANKMSGSRSV1/STMTTRNRS/. /// internal static string BankAccount { get { @@ -70,7 +70,7 @@ internal static string BankAccount { } /// - /// Looks up a localized string similar to OFX/CREDITCARDMSGSRSV1/CCSTMTTRNRS/CCSTMTRS. + /// Consulta uma cadeia de caracteres localizada semelhante a OFX/CREDITCARDMSGSRSV1/CCSTMTTRNRS/CCSTMTRS. /// internal static string CCAccount { get { @@ -79,7 +79,7 @@ internal static string CCAccount { } /// - /// Looks up a localized string similar to There are insufficent funds to pay your {item}. We have allocated what you have evenly between the {item} but there is no room in the budget for anything else, sorry.... + /// Consulta uma cadeia de caracteres localizada semelhante a There are insufficent funds to pay your {item}. We have allocated what you have evenly between the {item} but there is no room in the budget for anything else, sorry.... /// internal static string InsufficentFunds { get { @@ -88,7 +88,7 @@ internal static string InsufficentFunds { } /// - /// Looks up a localized string similar to There are no funds for your {item} sorry.... + /// Consulta uma cadeia de caracteres localizada semelhante a There are no funds for your {item} sorry.... /// internal static string NoFunds { get { @@ -97,7 +97,7 @@ internal static string NoFunds { } /// - /// Looks up a localized string similar to You are spending beyond your means so we have had to use your savings to create this budget. Perhaps you need to review your spending.... + /// Consulta uma cadeia de caracteres localizada semelhante a You are spending beyond your means so we have had to use your savings to create this budget. Perhaps you need to review your spending.... /// internal static string NoMoney { get { @@ -106,7 +106,7 @@ internal static string NoMoney { } /// - /// Looks up a localized string similar to OFX/SIGNONMSGSRSV1/SONRS. + /// Consulta uma cadeia de caracteres localizada semelhante a OFX/SIGNONMSGSRSV1/SONRS. /// internal static string SignOn { get {