From a8034f7f1cf7cdfbca4e908e056074607e944c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Aubrecht?= Date: Thu, 5 Mar 2020 23:39:33 +0100 Subject: [PATCH] Minor analyzer code-fixes (#3) --- .../Models/CurrencyDescriptor.cs | 2 +- .../Models/CurrencyList.cs | 6 +-- .../Czk/CzechNationalBankProvider.cs | 4 +- .../Providers/Czk/KurzyCzProvider.cs | 18 ++++----- .../Attributes/DescriptionAttribute.cs | 11 ++--- .../Models/DepositTransaction.cs | 2 +- .../Models/DividendTransaction.cs | 1 + .../StatementParser/Models/ESPPTransaction.cs | 5 ++- .../StatementParser/Models/SaleTransaction.cs | 6 ++- .../Degiro/CsvModels/StatementRowModel.cs | 5 +-- .../Parsers/Brokers/Degiro/DegiroCsvParser.cs | 24 +++++------ .../FXChoice/FxChoiceStatementParser.cs | 11 ++--- .../Fidelity/FidelityStatementParser.cs | 15 +++---- .../Lynx/Extensions/CsvReaderExtensions.cs | 2 +- .../Parsers/Brokers/Lynx/LynxCsvParser.cs | 40 ++++++++----------- .../MorganStanleyStatementPdfParser.cs | 12 ++---- .../MorganStanleyStatementXlsParser.cs | 2 +- .../PdfModels/TransactionModel.cs | 10 +---- .../StatementParser/TransactionParser.cs | 2 +- StatementParser/StatementParserCLI/Output.cs | 38 +++++++++--------- StatementParser/StatementParserCLI/Program.cs | 2 +- .../Models/Views/DepositTransactionView.cs | 4 +- .../Models/Views/DividendBrokerSummaryView.cs | 8 ++-- .../Views/DividendCurrencySummaryView.cs | 7 ++-- .../Models/Views/DividendTransactionView.cs | 2 +- .../Models/Views/ESPPTransactionView.cs | 2 +- .../Models/Views/SaleTransactionView.cs | 8 ++-- .../Models/Views/TransactionView.cs | 2 +- StatementParser/TaxReporterCLI/Output.cs | 24 +++++------ StatementParser/TaxReporterCLI/Program.cs | 4 +- .../TaxReporterCLI/TransactionBuilder.cs | 3 +- 31 files changed, 125 insertions(+), 157 deletions(-) diff --git a/StatementParser/ExchangeRateProvider/Models/CurrencyDescriptor.cs b/StatementParser/ExchangeRateProvider/Models/CurrencyDescriptor.cs index 3bbc57d..500855b 100644 --- a/StatementParser/ExchangeRateProvider/Models/CurrencyDescriptor.cs +++ b/StatementParser/ExchangeRateProvider/Models/CurrencyDescriptor.cs @@ -36,7 +36,7 @@ public override int GetHashCode() public override string ToString() { - return String.Format("{0} {1} {2} {3}", this.Code, this.Name, this.Price, this.Country); + return $"{this.Code} {this.Name} {this.Price} {this.Country}"; } public static bool operator ==(CurrencyDescriptor cd1, CurrencyDescriptor cd2) diff --git a/StatementParser/ExchangeRateProvider/Models/CurrencyList.cs b/StatementParser/ExchangeRateProvider/Models/CurrencyList.cs index ad16fcc..c15107b 100644 --- a/StatementParser/ExchangeRateProvider/Models/CurrencyList.cs +++ b/StatementParser/ExchangeRateProvider/Models/CurrencyList.cs @@ -4,13 +4,13 @@ namespace ExchangeRateProvider.Models { internal class CurrencyList : ICurrencyList { - private Dictionary currencyList = new Dictionary(); + private readonly Dictionary currencyList = new Dictionary(); public CurrencyDescriptor this[string currencyCode] => currencyList[currencyCode.ToLower()]; - public bool IsEmpty { get { return currencyList.Count == 0; } } + public bool IsEmpty => currencyList.Count == 0; - public CurrencyList(IList currencyList) + public CurrencyList(IList currencyList) { foreach (var currencyDescriptor in currencyList) { diff --git a/StatementParser/ExchangeRateProvider/Providers/Czk/CzechNationalBankProvider.cs b/StatementParser/ExchangeRateProvider/Providers/Czk/CzechNationalBankProvider.cs index af37d5f..49eca23 100644 --- a/StatementParser/ExchangeRateProvider/Providers/Czk/CzechNationalBankProvider.cs +++ b/StatementParser/ExchangeRateProvider/Providers/Czk/CzechNationalBankProvider.cs @@ -9,7 +9,7 @@ namespace ExchangeRateProvider.Providers.Czk { public class CzechNationalBankProvider : IExchangeProvider { - private string apiUrl = "http://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.xml?date="; + private const string ApiUrl = "http://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.xml?date="; public Task FetchCurrencyListByDateAsync(DateTime date) { @@ -38,7 +38,7 @@ private string CreateUrlByDate(DateTime date) { var czechDate = date.Day + "." + date.Month + "." + date.Year; - return apiUrl + czechDate; + return ApiUrl + czechDate; } } } diff --git a/StatementParser/ExchangeRateProvider/Providers/Czk/KurzyCzProvider.cs b/StatementParser/ExchangeRateProvider/Providers/Czk/KurzyCzProvider.cs index ab6f2c7..665c2d7 100644 --- a/StatementParser/ExchangeRateProvider/Providers/Czk/KurzyCzProvider.cs +++ b/StatementParser/ExchangeRateProvider/Providers/Czk/KurzyCzProvider.cs @@ -13,7 +13,7 @@ namespace ExchangeRateProvider.Providers.Czk { public class KurzyCzProvider : IExchangeProvider { - private string apiUrl = "https://www.kurzy.cz/kurzy-men/jednotny-kurz/"; + private const string ApiUrl = "https://www.kurzy.cz/kurzy-men/jednotny-kurz/"; public KurzyCzProvider() { @@ -32,12 +32,12 @@ public Task FetchCurrencyListByDateAsync(DateTime date) { var responseStream = response.GetResponseStream(); var encoding = Encoding.GetEncoding(response.CharacterSet); - using (var sr = new StreamReader(responseStream, encoding)) - { - var htmlContent = sr.ReadToEnd(); - htmlDocument.LoadHtml(htmlContent); - } - } + + using var sr = new StreamReader(responseStream, encoding); + + var htmlContent = sr.ReadToEnd(); + htmlDocument.LoadHtml(htmlContent); + } var table = htmlDocument.DocumentNode.SelectNodes("//*[@id=\"leftcolumn\"]/div[2]/div[2]/table/tr"); @@ -50,7 +50,7 @@ public Task FetchCurrencyListByDateAsync(DateTime date) var name = this.SanitizeValue(cellNode[0].SelectNodes("a/span")[1].InnerHtml); var code = this.SanitizeValue(cellNode[2].InnerHtml); var amount = Convert.ToDecimal(this.SanitizeValue(cellNode[3].InnerHtml)); - var price = Decimal.Parse(this.SanitizeValue(cellNode[4].InnerHtml), System.Globalization.NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-US")); + var price = Decimal.Parse(this.SanitizeValue(cellNode[4].InnerHtml), NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-US")); output.Add(new CurrencyDescriptor(code, name, price, amount, country)); } @@ -65,7 +65,7 @@ private string SanitizeValue(string value) private string CreateUrlByDate(DateTime date) { - return apiUrl + date.Year; + return ApiUrl + date.Year; } } } diff --git a/StatementParser/StatementParser/Attributes/DescriptionAttribute.cs b/StatementParser/StatementParser/Attributes/DescriptionAttribute.cs index a011233..7ce82d2 100644 --- a/StatementParser/StatementParser/Attributes/DescriptionAttribute.cs +++ b/StatementParser/StatementParser/Attributes/DescriptionAttribute.cs @@ -1,13 +1,14 @@ using System; using System.Reflection; using System.Text.RegularExpressions; -using StatementParser.Models; -namespace TaxReporterCLI.Models.Attributes +namespace StatementParser.Attributes { + [AttributeUsage(AttributeTargets.Property)] public class DescriptionAttribute : Attribute { - private static readonly Regex placeHolderRegex = new Regex("\\{([^\\}]+)\\}", RegexOptions.Compiled); + private static readonly Regex PlaceHolderRegex = new Regex("\\{([^\\}]+)\\}", RegexOptions.Compiled); + private string Description { get; } public DescriptionAttribute(string description) @@ -18,14 +19,14 @@ public DescriptionAttribute(string description) public static string ConstructDescription(PropertyInfo propertyInfo, object instanceHoldingProperty) { var attribute = propertyInfo.GetCustomAttribute(true); - + if (attribute == null) { return propertyInfo.Name; } var output = attribute.Description; - var matches = placeHolderRegex.Matches(attribute.Description); + var matches = PlaceHolderRegex.Matches(attribute.Description); foreach (Match match in matches) { diff --git a/StatementParser/StatementParser/Models/DepositTransaction.cs b/StatementParser/StatementParser/Models/DepositTransaction.cs index f9aaed0..fda31d1 100644 --- a/StatementParser/StatementParser/Models/DepositTransaction.cs +++ b/StatementParser/StatementParser/Models/DepositTransaction.cs @@ -1,5 +1,5 @@ using System; -using TaxReporterCLI.Models.Attributes; +using StatementParser.Attributes; namespace StatementParser.Models { diff --git a/StatementParser/StatementParser/Models/DividendTransaction.cs b/StatementParser/StatementParser/Models/DividendTransaction.cs index f82c034..32e1325 100644 --- a/StatementParser/StatementParser/Models/DividendTransaction.cs +++ b/StatementParser/StatementParser/Models/DividendTransaction.cs @@ -9,6 +9,7 @@ public class DividendTransaction : Transaction public decimal Income { get; } public decimal Tax { get; } + public DividendTransaction(DividendTransaction dividendTransaction) : this(dividendTransaction.Broker, dividendTransaction.Date, dividendTransaction.Name, dividendTransaction.Income, dividendTransaction.Tax, dividendTransaction.Currency) { } diff --git a/StatementParser/StatementParser/Models/ESPPTransaction.cs b/StatementParser/StatementParser/Models/ESPPTransaction.cs index 73ac032..6093a92 100644 --- a/StatementParser/StatementParser/Models/ESPPTransaction.cs +++ b/StatementParser/StatementParser/Models/ESPPTransaction.cs @@ -1,5 +1,5 @@ using System; -using TaxReporterCLI.Models.Attributes; +using StatementParser.Attributes; namespace StatementParser.Models { @@ -10,7 +10,9 @@ public class ESPPTransaction : Transaction [Description("Market Price")] public decimal MarketPrice { get; } + public decimal Amount { get; } + public decimal Profit { get; } [Description("Total Profit")] @@ -18,7 +20,6 @@ public class ESPPTransaction : Transaction public ESPPTransaction(ESPPTransaction eSPPTransaction) : this(eSPPTransaction.Broker, eSPPTransaction.Date, eSPPTransaction.Name, eSPPTransaction.Currency, eSPPTransaction.PurchasePrice, eSPPTransaction.MarketPrice, eSPPTransaction.Amount) { - } public ESPPTransaction(Broker broker, DateTime date, string name, Currency currency, decimal purchasePrice, decimal marketPrice, decimal amount) : base(broker, date, name, currency) diff --git a/StatementParser/StatementParser/Models/SaleTransaction.cs b/StatementParser/StatementParser/Models/SaleTransaction.cs index 4fc1016..e9f3a1a 100644 --- a/StatementParser/StatementParser/Models/SaleTransaction.cs +++ b/StatementParser/StatementParser/Models/SaleTransaction.cs @@ -1,5 +1,5 @@ using System; -using TaxReporterCLI.Models.Attributes; +using StatementParser.Attributes; namespace StatementParser.Models { @@ -29,9 +29,13 @@ public SaleTransaction(Broker broker, DateTime date, string name, Currency curre [Description("Sale Price")] public decimal SalePrice { get; } + public decimal Commission { get; } + public decimal Taxes { get; } + public decimal Swap { get; } + public decimal Profit { get; } public override string ToString() diff --git a/StatementParser/StatementParser/Parsers/Brokers/Degiro/CsvModels/StatementRowModel.cs b/StatementParser/StatementParser/Parsers/Brokers/Degiro/CsvModels/StatementRowModel.cs index 3913b1f..0ddcdfd 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/Degiro/CsvModels/StatementRowModel.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/Degiro/CsvModels/StatementRowModel.cs @@ -1,4 +1,3 @@ - using System; using CsvHelper.Configuration.Attributes; using StatementParser.Models; @@ -27,8 +26,8 @@ internal class StatementRowModel public override string ToString() { - var dateString = Date.HasValue ? Date.Value.ToShortDateString() : null; - var incomeString = Income.HasValue ? Income.Value : 0; + var dateString = Date?.ToShortDateString(); + var incomeString = Income ?? 0; return $"{nameof(Date)}: {dateString} {nameof(Name)}: {Name} {nameof(ISIN)}: {ISIN} {nameof(Description)}: {Description} {nameof(Currency)}: {Currency} {nameof(Income)}: {incomeString}"; } } diff --git a/StatementParser/StatementParser/Parsers/Brokers/Degiro/DegiroCsvParser.cs b/StatementParser/StatementParser/Parsers/Brokers/Degiro/DegiroCsvParser.cs index 308f3fa..e6a0d52 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/Degiro/DegiroCsvParser.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/Degiro/DegiroCsvParser.cs @@ -12,14 +12,9 @@ namespace StatementParser.Parsers.Brokers.Degiro internal class DegiroParser : ITransactionParser { private bool CanParse(string statementFilePath) - { - if (!File.Exists(statementFilePath) || Path.GetExtension(statementFilePath).ToLowerInvariant() != ".csv") - { - return false; - } - - return true; - } + { + return File.Exists(statementFilePath) && Path.GetExtension(statementFilePath).ToLowerInvariant() == ".csv"; + } public IList Parse(string statementFilePath) { @@ -51,7 +46,7 @@ public IList Parse(string statementFilePath) private decimal SearchForTax(IList statementRows, string isin, DateTime date) { - var row = statementRows.Where(i => i.Date.Value == date && i.ISIN == isin && i.Description.Contains("z dividendy")).FirstOrDefault(); + var row = statementRows.FirstOrDefault(i => i.Date.Value == date && i.ISIN == isin && i.Description.Contains("z dividendy")); return row.Income.Value; } @@ -65,12 +60,11 @@ private IList LoadStatementModel(string statementFilePath) ShortDatePattern = "dd-MM-yyyy" }; - using (var reader = new StreamReader(statementFilePath)) - using (var csv = new CsvReader(reader, ci)) - { - return csv.GetRecords().Where(i => i.Date != null).ToList(); - } - } + using var reader = new StreamReader(statementFilePath); + using var csv = new CsvReader(reader, ci); + + return csv.GetRecords().Where(i => i.Date != null).ToList(); + } catch (Exception ex) { Console.WriteLine(ex.Message); diff --git a/StatementParser/StatementParser/Parsers/Brokers/FXChoice/FxChoiceStatementParser.cs b/StatementParser/StatementParser/Parsers/Brokers/FXChoice/FxChoiceStatementParser.cs index 24b455a..f78459c 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/FXChoice/FxChoiceStatementParser.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/FXChoice/FxChoiceStatementParser.cs @@ -11,14 +11,9 @@ namespace StatementParser.Parsers.Brokers.FxChoice internal class FxChoiceStatementParser : ITransactionParser { private bool CanParse(string statementFilePath) - { - if (!File.Exists(statementFilePath) || Path.GetExtension(statementFilePath).ToLowerInvariant() != ".htm") - { - return false; - } - - return true; - } + { + return File.Exists(statementFilePath) && Path.GetExtension(statementFilePath).ToLowerInvariant() == ".htm"; + } public IList Parse(string statementFilePath) { diff --git a/StatementParser/StatementParser/Parsers/Brokers/Fidelity/FidelityStatementParser.cs b/StatementParser/StatementParser/Parsers/Brokers/Fidelity/FidelityStatementParser.cs index 32b8262..99bed27 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/Fidelity/FidelityStatementParser.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/Fidelity/FidelityStatementParser.cs @@ -13,14 +13,9 @@ namespace StatementParser.Parsers.Brokers.Fidelity internal class FidelityStatementParser : ITransactionParser { private bool CanParse(string statementFilePath) - { - if (!File.Exists(statementFilePath) || Path.GetExtension(statementFilePath).ToLowerInvariant() != ".pdf") - { - return false; - } - - return true; - } + { + return File.Exists(statementFilePath) && Path.GetExtension(statementFilePath).ToLowerInvariant() == ".pdf"; + } public IList Parse(string statementFilePath) { @@ -52,7 +47,7 @@ public IList Parse(string statementFilePath) public string SearchForCompanyName(ActivityBuyModel[] activityBuyModels, ESPPModel esppRow) { - string removeLastCharFunc(decimal number) + static string removeLastCharFunc(decimal number) { return number.ToString().Remove(number.ToString().Length - 1); } @@ -73,7 +68,7 @@ string removeLastCharFunc(decimal number) private decimal SearchForTaxString(ActivityTaxesModel[] activityTaxesModels, DateTime date) { - return activityTaxesModels.Where(i => i.Date == date.ToString("MM/dd", CultureInfo.InvariantCulture)).FirstOrDefault()?.Tax ?? 0; + return activityTaxesModels.FirstOrDefault(i => i.Date == date.ToString("MM/dd", CultureInfo.InvariantCulture))?.Tax ?? 0; } private ESPPTransaction CreateESPPTransaction(ActivityBuyModel[] activityBuyModels, ESPPModel esppRow) diff --git a/StatementParser/StatementParser/Parsers/Brokers/Lynx/Extensions/CsvReaderExtensions.cs b/StatementParser/StatementParser/Parsers/Brokers/Lynx/Extensions/CsvReaderExtensions.cs index c25e6df..70b5922 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/Lynx/Extensions/CsvReaderExtensions.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/Lynx/Extensions/CsvReaderExtensions.cs @@ -45,7 +45,7 @@ public static T ReadObject(this CsvReader csvReader, int headerFieldIndex, Fu dataSets[key].SetValue(output, value); } - dataSets[key].PropertyType.GetMethod("Add").Invoke(value, new object[] { record }); + dataSets[key].PropertyType.GetMethod("Add").Invoke(value, new[] { record }); } return output; } diff --git a/StatementParser/StatementParser/Parsers/Brokers/Lynx/LynxCsvParser.cs b/StatementParser/StatementParser/Parsers/Brokers/Lynx/LynxCsvParser.cs index 8442271..921d3e0 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/Lynx/LynxCsvParser.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/Lynx/LynxCsvParser.cs @@ -14,14 +14,9 @@ namespace StatementParser.Parsers.Brokers.Lynx internal class LynxCsvParser : ITransactionParser { private bool CanParse(string statementFilePath) - { - if (!File.Exists(statementFilePath) || Path.GetExtension(statementFilePath).ToLowerInvariant() != ".csv") - { - return false; - } - - return true; - } + { + return File.Exists(statementFilePath) && Path.GetExtension(statementFilePath).ToLowerInvariant() == ".csv"; + } public IList Parse(string statementFilePath) { @@ -52,9 +47,9 @@ public IList Parse(string statementFilePath) private decimal SearchForTax(DividendsRowModel dividend, List withholdingTaxes) { - var tax = withholdingTaxes.Where(i => dividend.Description.Contains(Regex.Replace(i.Description, " - [^ ]+ Tax", "", RegexOptions.Compiled)) && i.Date == dividend.Date).FirstOrDefault(); + var tax = withholdingTaxes.FirstOrDefault(i => dividend.Description.Contains(Regex.Replace(i.Description, " - [^ ]+ Tax", "", RegexOptions.Compiled)) && i.Date == dividend.Date); - return (tax == null) ? 0 : tax.Amount; + return tax?.Amount ?? 0; } private StatementModel LoadStatementModel(string statementFilePath) @@ -67,22 +62,21 @@ private StatementModel LoadStatementModel(string statementFilePath) ShortDatePattern = "yyyy-MM-dd" }; - using (var reader = new StreamReader(statementFilePath)) - using (var csv = new CsvReader(reader, ci)) - { - var statement = csv.ReadObject(0, () => csv.GetField(1) == "Header"); + using var reader = new StreamReader(statementFilePath); + using var csv = new CsvReader(reader, ci); - if (statement == null) - { - return null; - } + var statement = csv.ReadObject(0, () => csv.GetField(1) == "Header"); - statement.Dividends = statement.Dividends.Where(i => i.Date != null).ToList(); - statement.WithholdingTaxes = statement.WithholdingTaxes.Where(i => i.Date != null).ToList(); + if (statement == null) + { + return null; + } - return statement; - } - } + statement.Dividends = statement.Dividends.Where(i => i.Date != null).ToList(); + statement.WithholdingTaxes = statement.WithholdingTaxes.Where(i => i.Date != null).ToList(); + + return statement; + } catch (Exception ex) { Console.WriteLine(ex.Message); diff --git a/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementPdfParser.cs b/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementPdfParser.cs index cca4c31..37e94bd 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementPdfParser.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementPdfParser.cs @@ -11,14 +11,9 @@ namespace StatementParser.Parsers.Brokers.MorganStanley internal class MorganStanleyStatementPdfParser : ITransactionParser { private bool CanParse(string statementFilePath) - { - if (!File.Exists(statementFilePath) || Path.GetExtension(statementFilePath).ToLowerInvariant() != ".pdf") - { - return false; - } - - return true; - } + { + return File.Exists(statementFilePath) && Path.GetExtension(statementFilePath).ToLowerInvariant() == ".pdf"; + } public IList Parse(string statementFilePath) { @@ -61,7 +56,6 @@ private IEnumerable GetTransactions(StatementModel statementModel) .Where(i => i.Type == "Share Deposit") .Select(i => new DepositTransaction(Broker.MorganStanley, i.Date, statementModel.Name, i.Quantity, i.Price, Currency.USD))); - output.AddRange(statementModel.Transactions .Where(i => i.Type == "Dividend Credit") .Select(i => new DividendTransaction(Broker.MorganStanley, i.Date, statementModel.Name, i.GrossAmount, SearchForTax(statementModel, i), Currency.USD))); diff --git a/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementXlsParser.cs b/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementXlsParser.cs index fed5dcb..108dbee 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementXlsParser.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/MorganStanleyStatementXlsParser.cs @@ -91,7 +91,7 @@ private IRow SearchTaxRow(ISheet sheet, IRow creditRow) private ISheet GetSheet(string statementFilePath) { - HSSFWorkbook workbook = null; + HSSFWorkbook workbook; using (FileStream stream = new FileStream(statementFilePath, FileMode.Open, FileAccess.Read)) { workbook = new HSSFWorkbook(stream); diff --git a/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/PdfModels/TransactionModel.cs b/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/PdfModels/TransactionModel.cs index f9316fa..e6d1fb9 100644 --- a/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/PdfModels/TransactionModel.cs +++ b/StatementParser/StatementParser/Parsers/Brokers/MorganStanley/PdfModels/TransactionModel.cs @@ -24,15 +24,9 @@ internal class TransactionModel public string NetAmountRaw { get; set; } - public decimal NetAmount - { - get - { - return Convert.ToDecimal(NetAmountRaw?.Replace('(', '-').TrimEnd(')')); - } - } + public decimal NetAmount => Convert.ToDecimal(NetAmountRaw?.Replace('(', '-').TrimEnd(')')); - public override string ToString() + public override string ToString() { return $"{nameof(Date)}: {Date} {nameof(Type)}: {Type} {nameof(Quantity)}: {Quantity} {nameof(Price)}: {Price} {nameof(GrossAmount)}: {GrossAmount} {nameof(Commissions)}: {Commissions} {nameof(DistributionFees)}: {DistributionFees} {nameof(OtherCosts)}: {OtherCosts} {nameof(NetAmount)}: {NetAmount}"; } diff --git a/StatementParser/StatementParser/TransactionParser.cs b/StatementParser/StatementParser/TransactionParser.cs index b6d078c..6402d3f 100644 --- a/StatementParser/StatementParser/TransactionParser.cs +++ b/StatementParser/StatementParser/TransactionParser.cs @@ -12,7 +12,7 @@ namespace StatementParser { public class TransactionParser { - private IList parsers = new List(); + private readonly IList parsers = new List(); public TransactionParser() { diff --git a/StatementParser/StatementParserCLI/Output.cs b/StatementParser/StatementParserCLI/Output.cs index 5afdf5b..0c2c09b 100644 --- a/StatementParser/StatementParserCLI/Output.cs +++ b/StatementParser/StatementParserCLI/Output.cs @@ -27,31 +27,29 @@ public void SaveAsExcelSheet(string filePath, IList transactions) { var groupedTransactions = GroupTransactions(transactions); - using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)) - { - var wb1 = new XSSFWorkbook(); + using FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); + var wb1 = new XSSFWorkbook(); - foreach (var group in groupedTransactions) - { - var sheet = wb1.CreateSheet(group.Key); + foreach (var group in groupedTransactions) + { + var sheet = wb1.CreateSheet(@group.Key); - var headerRow = sheet.CreateRow(0); - var headerProperties = GetPublicProperties(group.Value[0]); - SetRowValues(headerRow, headerProperties.Keys); + var headerRow = sheet.CreateRow(0); + var headerProperties = GetPublicProperties(@group.Value[0]); + SetRowValues(headerRow, headerProperties.Keys); - for (int rowIndex = 1; rowIndex < group.Value.Count() + 1; rowIndex++) - { - var row = sheet.CreateRow(rowIndex); - var properties = GetPublicProperties(group.Value[rowIndex - 1]); + for (int rowIndex = 1; rowIndex <= @group.Value.Count; rowIndex++) + { + var row = sheet.CreateRow(rowIndex); + var properties = GetPublicProperties(@group.Value[rowIndex - 1]); - SetRowValues(row, properties.Values); - } - wb1.Add(sheet); - } + SetRowValues(row, properties.Values); + } + wb1.Add(sheet); + } - wb1.Write(file); - } - } + wb1.Write(file); + } public void PrintAsPlainText(IList transactions) { diff --git a/StatementParser/StatementParserCLI/Program.cs b/StatementParser/StatementParserCLI/Program.cs index 4290d34..56b8d05 100644 --- a/StatementParser/StatementParserCLI/Program.cs +++ b/StatementParser/StatementParserCLI/Program.cs @@ -9,7 +9,7 @@ namespace StatementParserCLI { - public class Program + public static class Program { public static async Task Main(string[] args) { diff --git a/StatementParser/TaxReporterCLI/Models/Views/DepositTransactionView.cs b/StatementParser/TaxReporterCLI/Models/Views/DepositTransactionView.cs index 72606c8..74cb9ef 100644 --- a/StatementParser/TaxReporterCLI/Models/Views/DepositTransactionView.cs +++ b/StatementParser/TaxReporterCLI/Models/Views/DepositTransactionView.cs @@ -1,5 +1,5 @@ +using StatementParser.Attributes; using StatementParser.Models; -using TaxReporterCLI.Models.Attributes; namespace TaxReporterCLI.Models.Views { @@ -7,7 +7,7 @@ public class DepositTransactionView : TransactionView { [Description("Total Price in {ExchangedToCurrency} per Day")] public decimal? ExchangedPerDayTotalPrice { get; } - + [Description("Total Price in {ExchangedToCurrency} per Year")] public decimal? ExchangedPerYearTotalPrice { get; } diff --git a/StatementParser/TaxReporterCLI/Models/Views/DividendBrokerSummaryView.cs b/StatementParser/TaxReporterCLI/Models/Views/DividendBrokerSummaryView.cs index 267171b..405d113 100644 --- a/StatementParser/TaxReporterCLI/Models/Views/DividendBrokerSummaryView.cs +++ b/StatementParser/TaxReporterCLI/Models/Views/DividendBrokerSummaryView.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using StatementParser.Attributes; using StatementParser.Models; -using TaxReporterCLI.Models.Attributes; namespace TaxReporterCLI.Models.Views { @@ -10,12 +10,14 @@ public class DividendBrokerSummaryView { [Description("Exchanged to currency")] public Currency ExchangedToCurrency { get; } + public Broker Broker { get; } + public Currency Currency { get; } - + [Description("Total Income")] public decimal TotalIncome { get; } - + [Description("Total Tax")] public decimal TotalTax { get; } diff --git a/StatementParser/TaxReporterCLI/Models/Views/DividendCurrencySummaryView.cs b/StatementParser/TaxReporterCLI/Models/Views/DividendCurrencySummaryView.cs index 4c01b75..7c0bb5a 100644 --- a/StatementParser/TaxReporterCLI/Models/Views/DividendCurrencySummaryView.cs +++ b/StatementParser/TaxReporterCLI/Models/Views/DividendCurrencySummaryView.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using StatementParser.Attributes; using StatementParser.Models; -using TaxReporterCLI.Models.Attributes; namespace TaxReporterCLI.Models.Views { @@ -10,11 +10,12 @@ public class DividendCurrencySummaryView { [Description("Exchanged to currency")] public Currency ExchangedToCurrency { get; } + public Currency Currency { get; } - + [Description("Total Income")] public decimal TotalIncome { get; } - + [Description("Total Tax")] public decimal TotalTax { get; } diff --git a/StatementParser/TaxReporterCLI/Models/Views/DividendTransactionView.cs b/StatementParser/TaxReporterCLI/Models/Views/DividendTransactionView.cs index 0bf0e1e..c026e46 100644 --- a/StatementParser/TaxReporterCLI/Models/Views/DividendTransactionView.cs +++ b/StatementParser/TaxReporterCLI/Models/Views/DividendTransactionView.cs @@ -1,5 +1,5 @@ +using StatementParser.Attributes; using StatementParser.Models; -using TaxReporterCLI.Models.Attributes; namespace TaxReporterCLI.Models.Views { diff --git a/StatementParser/TaxReporterCLI/Models/Views/ESPPTransactionView.cs b/StatementParser/TaxReporterCLI/Models/Views/ESPPTransactionView.cs index fd7728a..d6712f1 100644 --- a/StatementParser/TaxReporterCLI/Models/Views/ESPPTransactionView.cs +++ b/StatementParser/TaxReporterCLI/Models/Views/ESPPTransactionView.cs @@ -1,5 +1,5 @@ +using StatementParser.Attributes; using StatementParser.Models; -using TaxReporterCLI.Models.Attributes; namespace TaxReporterCLI.Models.Views { diff --git a/StatementParser/TaxReporterCLI/Models/Views/SaleTransactionView.cs b/StatementParser/TaxReporterCLI/Models/Views/SaleTransactionView.cs index 23bb566..a71df95 100644 --- a/StatementParser/TaxReporterCLI/Models/Views/SaleTransactionView.cs +++ b/StatementParser/TaxReporterCLI/Models/Views/SaleTransactionView.cs @@ -1,5 +1,5 @@ +using StatementParser.Attributes; using StatementParser.Models; -using TaxReporterCLI.Models.Attributes; namespace TaxReporterCLI.Models.Views { @@ -46,9 +46,9 @@ public SaleTransactionView(SaleTransaction transaction, decimal? exchangeRatePer public override string ToString() { - return base.ToString() - + $" {nameof(ExchangedPerDayProfit)}: {ExchangedPerDayProfit} {nameof(ExchangedPerYearProfit)}: {ExchangedPerYearProfit} {nameof(ExchangedPerDaySwap)}: {ExchangedPerDaySwap} {nameof(ExchangedPerYearSwap)}: {ExchangedPerYearSwap}" - + $" {nameof(ExchangedPerDayTaxes)}: {ExchangedPerDayTaxes} {nameof(ExchangedPerYearTaxes)}: {ExchangedPerYearTaxes} {nameof(ExchangedPerDayCommission)}: {ExchangedPerDayCommission} {nameof(ExchangedPerYearCommission)}: {ExchangedPerYearCommission}"; + return base.ToString() + + $" {nameof(ExchangedPerDayProfit)}: {ExchangedPerDayProfit} {nameof(ExchangedPerYearProfit)}: {ExchangedPerYearProfit} {nameof(ExchangedPerDaySwap)}: {ExchangedPerDaySwap} {nameof(ExchangedPerYearSwap)}: {ExchangedPerYearSwap}" + + $" {nameof(ExchangedPerDayTaxes)}: {ExchangedPerDayTaxes} {nameof(ExchangedPerYearTaxes)}: {ExchangedPerYearTaxes} {nameof(ExchangedPerDayCommission)}: {ExchangedPerDayCommission} {nameof(ExchangedPerYearCommission)}: {ExchangedPerYearCommission}"; } } } \ No newline at end of file diff --git a/StatementParser/TaxReporterCLI/Models/Views/TransactionView.cs b/StatementParser/TaxReporterCLI/Models/Views/TransactionView.cs index f158cde..bd908e6 100644 --- a/StatementParser/TaxReporterCLI/Models/Views/TransactionView.cs +++ b/StatementParser/TaxReporterCLI/Models/Views/TransactionView.cs @@ -1,5 +1,5 @@ +using StatementParser.Attributes; using StatementParser.Models; -using TaxReporterCLI.Models.Attributes; namespace TaxReporterCLI.Models.Views { diff --git a/StatementParser/TaxReporterCLI/Output.cs b/StatementParser/TaxReporterCLI/Output.cs index 63f7c6c..4b78c83 100644 --- a/StatementParser/TaxReporterCLI/Output.cs +++ b/StatementParser/TaxReporterCLI/Output.cs @@ -6,7 +6,7 @@ using Newtonsoft.Json; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; -using TaxReporterCLI.Models.Attributes; +using StatementParser.Attributes; namespace TaxReporterCLI { @@ -28,18 +28,16 @@ public void SaveAsExcelSheet(string filePath, IList transactions) { var groupedTransactions = GroupTransactions(transactions); - using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)) - { - var wb1 = new XSSFWorkbook(); + using FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); + var wb1 = new XSSFWorkbook(); - foreach (var group in groupedTransactions) - { - wb1.Add(CreateSheet(wb1, group.Key, group.Value)); - } + foreach (var group in groupedTransactions) + { + wb1.Add(CreateSheet(wb1, @group.Key, @group.Value)); + } - wb1.Write(file); - } - } + wb1.Write(file); + } public void PrintAsPlainText(IList transactions) { @@ -61,7 +59,7 @@ private ISheet CreateSheet(XSSFWorkbook workbook, string sheetName, IList DescriptionAttribute.ConstructDescription(i.Key, objects[0])).ToList(); CreateRow(sheet, 0, haeders); - for (int rowIndex = 1; rowIndex < objects.Count() + 1; rowIndex++) + for (int rowIndex = 1; rowIndex <= objects.Count; rowIndex++) { var properties = CollectPublicProperties(objects[rowIndex - 1]); CreateRow(sheet, rowIndex, properties.Values.ToList()); @@ -98,7 +96,7 @@ private IRow CreateRow(ISheet sheet, int rowIndex, IList rowValues) private IDictionary CollectPublicProperties(Object instance) { var properties = instance.GetType().GetProperties(); - + var dictionary = properties.Reverse().ToDictionary( k => k, i => i.GetValue(instance)); diff --git a/StatementParser/TaxReporterCLI/Program.cs b/StatementParser/TaxReporterCLI/Program.cs index 220a462..e800d9d 100644 --- a/StatementParser/TaxReporterCLI/Program.cs +++ b/StatementParser/TaxReporterCLI/Program.cs @@ -8,12 +8,11 @@ using ExchangeRateProvider.Providers.Czk; using StatementParser; using StatementParser.Models; -using TaxReporterCLI.Models; using TaxReporterCLI.Models.Views; namespace TaxReporterCLI { - public class Program + public static class Program { public static async Task Main(string[] args) { @@ -28,7 +27,6 @@ public static async Task Main(string[] args) { Console.WriteLine(parser.Usage()); } - } private static IList ResolveFilePaths(string[] paths) diff --git a/StatementParser/TaxReporterCLI/TransactionBuilder.cs b/StatementParser/TaxReporterCLI/TransactionBuilder.cs index 92f4fdb..23ed316 100644 --- a/StatementParser/TaxReporterCLI/TransactionBuilder.cs +++ b/StatementParser/TaxReporterCLI/TransactionBuilder.cs @@ -29,7 +29,6 @@ public async Task> BuildAsync(IList transact var kurzyCurrencyListPerYear = await exchangeProviderPerYear.FetchCurrencyListsForDatesAsync(transactions.Select(i => new DateTime(i.Date.Year, 1, 1)).ToHashSet()); var cnbCurrencyListPerDay = await exchangeProviderPerDay.FetchCurrencyListsForDatesAsync(transactions.Select(i => i.Date.Date).ToHashSet()); - foreach (var transaction in transactions) { var currency = transaction.Currency.ToString(); @@ -46,7 +45,7 @@ public async Task> BuildAsync(IList transact private static TransactionView CreateTransactionView(Transaction transaction, decimal? exchangeRatePerDay, decimal? exchangeRatePerYear, Currency exchangedToCurrency) { var type = transaction.GetType(); - + var typeToCreate = new Dictionary>() { {typeof(DividendTransaction),