This commit is contained in:
parent
0800fa8cca
commit
42be0862ca
2 changed files with 54 additions and 29 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,5 +2,6 @@
|
|||
bin/
|
||||
obj/
|
||||
test.csv
|
||||
test2.csv
|
||||
rules.csv
|
||||
.~lock*
|
||||
|
|
82
Program.cs
82
Program.cs
|
@ -22,7 +22,9 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.CommandLine.DragonFruit;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using CsvHelper;
|
||||
using CsvHelper.Configuration;
|
||||
|
||||
namespace BunyMuny {
|
||||
internal class Program {
|
||||
|
@ -38,38 +40,53 @@ namespace BunyMuny {
|
|||
List<Rule> rules;
|
||||
|
||||
using (var ruleStreamReader = new StreamReader(ruleFile)) {
|
||||
using var ruleCsv = new CsvReader(ruleStreamReader,CultureInfo.InvariantCulture);
|
||||
using var ruleCsv = new CsvReader(ruleStreamReader, CultureInfo.InvariantCulture);
|
||||
rules = ruleCsv.GetRecords<Rule>().ToList();
|
||||
}
|
||||
|
||||
// get the first line of the CSV file (the header) as a string
|
||||
string header;
|
||||
using (var headerReader = new StreamReader(file)) {
|
||||
header = headerReader.ReadLine();
|
||||
}
|
||||
|
||||
using var sr = new StreamReader(file);
|
||||
using var csv = new CsvReader(sr, CultureInfo.InvariantCulture);
|
||||
csv.Configuration.HasHeaderRecord = false;
|
||||
|
||||
csv.Read();
|
||||
csv.ReadHeader();
|
||||
var nabRegex = new Regex(@"^\d\d \w{3} \d\d");
|
||||
|
||||
// get the first line of the CSV file (the header) as a string
|
||||
var header = csv.Parser.Context.RawRecord.Trim();
|
||||
switch (header) {
|
||||
case null:
|
||||
Console.WriteLine("File is empty 0uo");
|
||||
return 1;
|
||||
case "Date,Description,Debits and credits,Balance":
|
||||
bank = Bank.ME;
|
||||
break;
|
||||
case "Whatever NAB uses I guess":
|
||||
bank = Bank.NAB;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine($"Unknown header: [{header}]");
|
||||
break;
|
||||
if (header == null) {
|
||||
Console.WriteLine("File is empty 0uo");
|
||||
return 1;
|
||||
}
|
||||
else if (header == "Date,Description,Debits and credits,Balance") {
|
||||
bank = Bank.ME;
|
||||
csv.Configuration.HasHeaderRecord = true;
|
||||
// read in the header to allow for accessing fields by name rather than by index
|
||||
csv.Read();
|
||||
csv.ReadHeader();
|
||||
}
|
||||
else if (nabRegex.IsMatch(header)) {
|
||||
// NAB exports don't have headers
|
||||
// records look like "02 Apr 20,23.00,,,MISCELLANEOUS DEBIT,V1234 02/09 PAYPAL Sydney,1234.56
|
||||
// the columns mean: date of transaction, amount, ???, ???, category,method,remaining balance
|
||||
// i don't like it >:c
|
||||
bank = Bank.NAB;
|
||||
}
|
||||
else {
|
||||
Console.WriteLine($"Unknown header: [{header}]");
|
||||
}
|
||||
|
||||
while (csv.Read()) {
|
||||
decimal value;
|
||||
string category;
|
||||
string description;
|
||||
|
||||
switch (bank) {
|
||||
case Bank.ME:
|
||||
var value = decimal.Parse(csv.GetField("Debits and credits").TrimStart().Replace("$", ""));
|
||||
var (category, description) = MatchAgainstRules(rules, csv.GetField("Description"));
|
||||
value = decimal.Parse(csv.GetField("Debits and credits").TrimStart().Replace("$", ""));
|
||||
(category, description) = MatchAgainstRules(rules, csv.GetField("Description"));
|
||||
|
||||
statements.Add(new Statement() {
|
||||
Date = DateTime.ParseExact(csv.GetField("Date"), "dd/MM/yyyy", CultureInfo.InvariantCulture),
|
||||
|
@ -81,8 +98,17 @@ namespace BunyMuny {
|
|||
break;
|
||||
|
||||
case Bank.NAB:
|
||||
Console.WriteLine("Unimplemented");
|
||||
return 1;
|
||||
// return 1;
|
||||
value = decimal.Parse(csv.GetField(1));
|
||||
(category, description) = MatchAgainstRules(rules, csv.GetField(5));
|
||||
statements.Add(new Statement() {
|
||||
Date = DateTime.ParseExact(csv.GetField(0), "dd MMM yy", CultureInfo.CurrentCulture),
|
||||
OriginalDescription = csv.GetField(5),
|
||||
Description = description,
|
||||
Category = category,
|
||||
Value = value
|
||||
});
|
||||
break;
|
||||
|
||||
case Bank.Other:
|
||||
Console.WriteLine("Unknown bank!");
|
||||
|
@ -102,16 +128,14 @@ namespace BunyMuny {
|
|||
|
||||
Console.WriteLine("Summary:");
|
||||
Console.WriteLine("==================");
|
||||
var summaries = statements.
|
||||
GroupBy(s => s.Category). // group statements by category
|
||||
Select(summary => new { // and then select:
|
||||
Name = summary.First().Category?? "Other", // the name of the category...
|
||||
var summaries = statements.GroupBy(s => s.Category). // group statements by category
|
||||
Select(summary => new {
|
||||
// and then select:
|
||||
Name = summary.First().Category ?? "Other", // the name of the category...
|
||||
Total = summary.Sum(s => s.Value).ToString() // ...and the sum of all the statement's values in that category
|
||||
});
|
||||
|
||||
var longestCategoryName = summaries.
|
||||
ToList().
|
||||
Max(summary => summary.Name.Length);
|
||||
var longestCategoryName = summaries.ToList().Max(summary => summary.Name.Length);
|
||||
|
||||
foreach (var summary in summaries) {
|
||||
Console.WriteLine("{0}: {1}", summary.Name.PadLeft(longestCategoryName), summary.Total);
|
||||
|
|
Loading…
Reference in a new issue