Skip to content

Commit

Permalink
feat(plugins): Add American Express (NL) plugin (#38)
Browse files Browse the repository at this point in the history
* feat(plugin): Add Amex

* Consolidate packages

* fix: assembly name and InnoSetup
  • Loading branch information
janssen-io authored Jan 6, 2025
1 parent 9dc26d7 commit 9e4387f
Show file tree
Hide file tree
Showing 17 changed files with 118 additions and 10 deletions.
7 changes: 7 additions & 0 deletions TransactionQL.sln
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionQL.DesktopApp.Te
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TransactionQL.Build", "src\TransactionQL.Build\TransactionQL.Build.fsproj", "{4EE573F5-E881-430C-80AA-A71DEF20161D}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TransactionQL.Plugins.Amex", "src\TransactionQL.Plugins.Amex\TransactionQL.Plugins.Amex.fsproj", "{11ACCFD8-1CF6-4F56-B822-A661A289774C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -100,6 +102,10 @@ Global
{4EE573F5-E881-430C-80AA-A71DEF20161D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EE573F5-E881-430C-80AA-A71DEF20161D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EE573F5-E881-430C-80AA-A71DEF20161D}.Release|Any CPU.Build.0 = Release|Any CPU
{11ACCFD8-1CF6-4F56-B822-A661A289774C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11ACCFD8-1CF6-4F56-B822-A661A289774C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11ACCFD8-1CF6-4F56-B822-A661A289774C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11ACCFD8-1CF6-4F56-B822-A661A289774C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -108,6 +114,7 @@ Global
{EA0A782C-D5BF-4DA6-9710-25FDE5123B79} = {B645AC52-7FA5-47ED-8162-E39B705813C6}
{32027311-05E4-465B-9F5A-F5C59768B99A} = {B645AC52-7FA5-47ED-8162-E39B705813C6}
{F6F92978-83BF-4DB9-B513-2B8ABD22AC5F} = {B645AC52-7FA5-47ED-8162-E39B705813C6}
{11ACCFD8-1CF6-4F56-B822-A661A289774C} = {B645AC52-7FA5-47ED-8162-E39B705813C6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55AA355A-8CC6-47CA-BEAB-C07FDEFB4BAB}
Expand Down
2 changes: 1 addition & 1 deletion src/TransactionQL.Build/build.fs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ let initTargets () =
Directory.create (stagingDirectory </> "plugins")
Directory.create (stagingDirectory </> "desktop")

let plugins = ["ASN"; "Bunq"; "ING"]
let plugins = ["ASN"; "Bunq"; "ING"; "Amex"]
let src = plugins |> List.map (fun p -> buildDirectory </> "plugins" </> $"TransactionQL.Plugins.{p}.dll")
let dst = plugins |> List.map (fun p -> stagingDirectory </> "plugins" </> $"{String.toLower p}.dll")

Expand Down
2 changes: 2 additions & 0 deletions src/TransactionQL.Build/tql.iss
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ Name: "Plugins"; Description: "Transaction Parsers"; Ty
Name: "Plugins\ASN"; Description: "ASN"; Types: full cli-only custom; Flags: checkablealone
Name: "Plugins\Bunq"; Description: "Bunq"; Types: full cli-only custom; Flags: checkablealone
Name: "Plugins\ING"; Description: "ING"; Types: full cli-only custom; Flags: checkablealone
Name: "Plugins\Amex"; Description: "American Express"; Types: full cli-only custom; Flags: checkablealone

[Files]
Source: "{#Staging}\desktop\*"; Components: GUI; DestDir: "{app}\app"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "{#Staging}\tql.exe"; Components: CLI; DestDir: "{app}"; DestName: "tql.exe"; Flags: ignoreversion
Source: "{#Staging}\plugins\asn.dll"; Components: Plugins\ASN; DestDir: "{app}\plugins"; DestName: "asn.dll"; Flags: ignoreversion
Source: "{#Staging}\plugins\bunq.dll"; Components: Plugins\Bunq; DestDir: "{app}\plugins"; DestName: "bunq.dll"; Flags: ignoreversion
Source: "{#Staging}\plugins\ing.dll"; Components: Plugins\ING; DestDir: "{app}\plugins"; DestName: "ing.dll"; Flags: ignoreversion
Source: "{#Staging}\plugins\amex.dll"; Components: Plugins\Amex; DestDir: "{app}\plugins"; DestName: "amex.dll"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="8.0.400" />
<PackageReference Update="FSharp.Core" Version="9.0.100" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using TransactionQL.DesktopApp.Models;
using TransactionQL.DesktopApp.Services;
using TransactionQL.Parser;
using TransactionQL.Shared.Disposables;
using static TransactionQL.Input.Converters;
using static TransactionQL.Shared.Types;

Expand Down Expand Up @@ -83,7 +84,7 @@ public void ReturnsError_OfCreatingReader()
[Fact]
public void ParsesFilteredTransactions()
{
CultureInfo.CurrentCulture = new CultureInfo("en-us");
using var _ = Disposables.changeCulture("en-us");
var transactions = """
13-02-2025,NL12ASNB13243546,NL98BANK75645342,AH,,,,EUR,50.00,EUR,-10.00,,,,,,,,
14-02-2025,NL12ASNB13243546,NL98BANK75645342,AH,,,,EUR,40.00,EUR,-15.00,,,,,,,,
Expand Down Expand Up @@ -158,7 +159,7 @@ public void ParsesFilteredTransactions()
[Fact]
public void ParsesUnfilteredTransactions()
{
CultureInfo.CurrentCulture = new CultureInfo("en-us");
using var _ = Disposables.changeCulture("en-us");
var transactions = """
13-02-2025,NL12ASNB13243546,NL98BANK75645342,AH,,,,EUR,50.00,EUR,-10.00,,,,,,,,
14-02-2025,NL12ASNB13243546,NL98BANK75645342,AH,,,,EUR,40.00,EUR,-15.00,,,,,,,,
Expand Down Expand Up @@ -215,7 +216,7 @@ public void ParsesUnfilteredTransactions()
[Fact]
public void ParsesMixedTransactions()
{
CultureInfo.CurrentCulture = new CultureInfo("en-us");
using var _ = Disposables.changeCulture("en-us");
var transactions = """
13-02-2025,NL12ASNB13243546,NL98BANK75645342,AH,,,,EUR,50.00,EUR,-10.00,,,,,,,,
14-02-2025,NL12ASNB13243546,NL98BANK75645342,Jumbo,,,,EUR,40.00,EUR,-15.00,,,,,,,,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<ItemGroup>
<PackageReference Include="Avalonia.Headless.XUnit" Version="11.2.3" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.3" />
<PackageReference Include="FSharp.Core" Version="9.0.100" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="xunit" Version="2.9.2" />
Expand Down
1 change: 1 addition & 0 deletions src/TransactionQL.DesktopApp/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using TransactionQL.DesktopApp.Application;
using TransactionQL.DesktopApp.ViewModels;
using TransactionQL.DesktopApp.Views;
using TransactionQL.Shared.Disposables;

namespace TransactionQL.DesktopApp;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.2.3" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.3" />
<PackageReference Include="FSharp.Core" Version="9.0.100" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Projektanker.Icons.Avalonia" Version="9.6.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="8.0.400" />
<PackageReference Update="FSharp.Core" Version="9.0.100" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="8.0.400" />
<PackageReference Update="FSharp.Core" Version="9.0.100" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/TransactionQL.Plugins.Amex/Amex.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Datum,Omschrijving,Kaartlid,Rekening #,Bedrag
56 changes: 56 additions & 0 deletions src/TransactionQL.Plugins.Amex/Amex.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace TransactionQL.Plugins

open System
open System.Globalization
open FSharp.Data
open TransactionQL.Parser.AST
open TransactionQL.Parser.QLInterpreter
open TransactionQL.Input.Converters
open TransactionQL.Shared.Disposables

module Amex =

let private dateFormat = "MM/dd/yyyy"

type AmexTransactions = CsvProvider<"Amex.csv">

type AmexReader() =
let toMap (row: AmexTransactions.Row) =
let amount =
-1m * Decimal.Parse(row.Bedrag, NumberStyles.AllowLeadingSign ||| NumberStyles.AllowDecimalPoint)

let isSent = amount < 0m

Map.ofList
[ ("Sender", if isSent then row.Omschrijving else row.Kaartlid)
("Receiver", if isSent then row.Kaartlid else row.Omschrijving)
("Amount", string amount)
("Total", (string <| Math.Abs amount))
("Date", row.Datum)
("Description", row.Omschrijving)
("Name", row.Omschrijving) ]

interface IConverter with
member this.DateFormat = dateFormat

member this.Read lines =
using (Disposables.changeCulture "nl-NL") (fun _ ->
lines |> AmexTransactions.ParseRows |> Array.map toMap
)

member this.Map row =
let fromRow col = Map.find col row

{ Header =
Header(
DateTime.ParseExact(fromRow "Date", dateFormat, CultureInfo.InvariantCulture),
fromRow "Name"
)
Lines =
[ { Account = Account [ fromRow "Receiver" ]
Amount = (Commodity "EUR", float (fromRow "Total")) |> Some
Tag = None }
{ Account = Account [ fromRow "Sender" ]
Amount = None
Tag = None } ]
Comments = [ fromRow "Description" ] }
20 changes: 20 additions & 0 deletions src/TransactionQL.Plugins.Amex/TransactionQL.Plugins.Amex.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyTitle>Amex</AssemblyTitle>
</PropertyGroup>

<ItemGroup>
<None Include="Amex.csv" />
<Compile Include="Amex.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TransactionQL.Input\TransactionQL.Input.fsproj" />
<ProjectReference Include="..\TransactionQL.Parser\TransactionQL.Parser.fsproj" />
<ProjectReference Include="..\TransactionQL.Shared\TransactionQL.Shared.fsproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="8.0.400" />
<PackageReference Update="FSharp.Core" Version="9.0.100" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="8.0.400" />
<PackageReference Update="FSharp.Core" Version="9.0.100" />
</ItemGroup>

</Project>
17 changes: 17 additions & 0 deletions src/TransactionQL.Shared/Disposables.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace TransactionQL.Shared.Disposables

module Disposables =
open System
open System.Globalization

let private createDisposable f =
{
new IDisposable with
member x.Dispose() = f()
}

let changeCulture (culture:string) =
let current = CultureInfo.CurrentCulture
CultureInfo.CurrentCulture <- CultureInfo.GetCultureInfo(culture)
createDisposable(fun () -> CultureInfo.CurrentCulture <- current)

3 changes: 2 additions & 1 deletion src/TransactionQL.Shared/TransactionQL.Shared.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="Disposables.fs" />
<Compile Include="Extensions.fs" />
<Compile Include="Types.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="8.0.400" />
<PackageReference Update="FSharp.Core" Version="9.0.100" />
</ItemGroup>

</Project>

0 comments on commit 9e4387f

Please sign in to comment.