Compare commits

...

2 commits

Author SHA1 Message Date
9a1272c085
don't warn about missing xml comments
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-27 13:08:55 +10:00
6aa366c714
use a CSV file for the rules instead 2020-09-27 13:06:44 +10:00
4 changed files with 19 additions and 28 deletions

2
.gitignore vendored
View file

@ -2,4 +2,4 @@
bin/
obj/
test.csv
rules.json
rules.csv

View file

@ -20,10 +20,8 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.Json;
using System.CommandLine.DragonFruit;
using System.Linq;
using System.Text.Json.Serialization;
using CsvHelper;
namespace BunyMuny {
@ -32,18 +30,16 @@ namespace BunyMuny {
/// BunyMuny parses the CSV output of various bank statement listings and converts it to something more human readable with nice visualisations.
/// </summary>
/// <param name="file">The CSV file to read</param>
/// <param name="ruleFile">The JSON file to use for rules when parsing statement descriptions</param>
/// <param name="ruleFile">The CSV file to use for rules when parsing statement descriptions</param>
/// <returns></returns>
private static int Main(string file = "test.csv", string ruleFile = "rules.json") {
private static int Main(string file = "test.csv", string ruleFile = "rules.csv") {
var bank = Bank.Other;
var statements = new List<Statement>();
List<Rule> rules;
using (var ruleStreamReader = new StreamReader(ruleFile)) {
var jsonOptions = new JsonSerializerOptions();
jsonOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
jsonOptions.WriteIndented = true;
rules = JsonSerializer.Deserialize<List<Rule>>(ruleStreamReader.ReadToEnd(), jsonOptions);
using var ruleCsv = new CsvReader(ruleStreamReader,CultureInfo.InvariantCulture);
rules = ruleCsv.GetRecords<Rule>().ToList();
}
using var sr = new StreamReader(file);
@ -73,14 +69,13 @@ namespace BunyMuny {
switch (bank) {
case Bank.ME:
var value = double.Parse(csv.GetField("Debits and credits").TrimStart().Replace("$", ""));
// SHOW PET THIS
var ruleValues = MatchAgainstRules(rules, csv.GetField("Description"));
var (category, description) = MatchAgainstRules(rules, csv.GetField("Description"));
statements.Add(new Statement() {
Date = DateTime.ParseExact(csv.GetField("Date"), "dd/MM/yyyy", CultureInfo.InvariantCulture),
OriginalDescription = csv.GetField("Description"),
Description = ruleValues.Description,
Category = ruleValues.Category,
Description = description,
Category = category,
Value = value
});
break;
@ -100,7 +95,7 @@ namespace BunyMuny {
}
foreach (var statement in statements.
Where(s => s.Category != null).
// Where(s => s.Category != null).
OrderBy(s => s.Date)) {
Console.WriteLine(statement);
}

View file

@ -13,24 +13,19 @@ dotnet build
## The rules file
By default, BunyMuny checks for rules in `rules.json` in the current directory. An example rules file might look like this:
```json
[
{
"Match":"Start",
"Value": "Purchase Cash Converters",
"Category":"Personal",
"Description":"Cashies"
}
]
```csv
Match,Value,Category,Description,CaseSensitive
Start,Purchase Cash Converters,Personal,Cashies,true
```
This means that any statement that starts with "Purchase Cash Converters" will be assigned the category "Personal", and the description "Cashies".
This means that any statement that starts with "Purchase Cash Converters" (case sensitive) will be assigned the category "Personal", and the description "Cashies".
- `"Match"` specifies the type of matching to perform. It can be any of the following:
- `Match` specifies the type of matching to perform. It can be any of the following:
- "Start": Match the start of the description.
- "End": Match the end of the description.
- "Contains": Match anywhere in the description.
- "Exact": Only match if the bank statement's description is exactly equal to the provided value.
- "Regex": Match with [regular expressions](https://en.wikipedia.org/wiki/Regular_expression).
- `"Value"` specifies the value to match against.
- `"Category"` is the category that the statement should be filed under.
- `"Description"` is a short description to distinguish the particular merchant.
- `Value` specifies the value to match against.
- `Category` is the category that the statement should be filed under.
- `Description` is a short description to distinguish the particular merchant.
- `CaseSensitive` specifies whether or not the match should be case sensitive.

View file

@ -3,6 +3,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<NoWarn>1591</NoWarn>
</PropertyGroup>
<ItemGroup>