diff --git a/docs/res/AppIcon/AppIcons.zip b/docs/res/AppIcon/AppIcons.zip
new file mode 100644
index 00000000..2607c14b
Binary files /dev/null and b/docs/res/AppIcon/AppIcons.zip differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-1024@1x.png b/docs/res/AppIcon/AppIcons/icon-ios-1024@1x.png
new file mode 100644
index 00000000..8acdd236
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-1024@1x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-20@1x.png b/docs/res/AppIcon/AppIcons/icon-ios-20@1x.png
new file mode 100644
index 00000000..5a82f6a2
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-20@1x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-20@2x.png b/docs/res/AppIcon/AppIcons/icon-ios-20@2x.png
new file mode 100644
index 00000000..f2d9328d
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-20@2x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-20@3x.png b/docs/res/AppIcon/AppIcons/icon-ios-20@3x.png
new file mode 100644
index 00000000..36907fc9
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-20@3x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-29@1x.png b/docs/res/AppIcon/AppIcons/icon-ios-29@1x.png
new file mode 100644
index 00000000..13058643
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-29@1x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-29@2x.png b/docs/res/AppIcon/AppIcons/icon-ios-29@2x.png
new file mode 100644
index 00000000..866d7a4e
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-29@2x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-29@3x.png b/docs/res/AppIcon/AppIcons/icon-ios-29@3x.png
new file mode 100644
index 00000000..9a7a17ce
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-29@3x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-40@1x.png b/docs/res/AppIcon/AppIcons/icon-ios-40@1x.png
new file mode 100644
index 00000000..f2d9328d
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-40@1x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-40@2x.png b/docs/res/AppIcon/AppIcons/icon-ios-40@2x.png
new file mode 100644
index 00000000..cc9c951e
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-40@2x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-40@3x.png b/docs/res/AppIcon/AppIcons/icon-ios-40@3x.png
new file mode 100644
index 00000000..0e62f72a
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-40@3x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-60@2x.png b/docs/res/AppIcon/AppIcons/icon-ios-60@2x.png
new file mode 100644
index 00000000..0e62f72a
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-60@2x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-60@3x.png b/docs/res/AppIcon/AppIcons/icon-ios-60@3x.png
new file mode 100644
index 00000000..61aead05
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-60@3x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-76@1x.png b/docs/res/AppIcon/AppIcons/icon-ios-76@1x.png
new file mode 100644
index 00000000..1b4730dc
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-76@1x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-76@2x.png b/docs/res/AppIcon/AppIcons/icon-ios-76@2x.png
new file mode 100644
index 00000000..e5d83974
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-76@2x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios-83.5@2x.png b/docs/res/AppIcon/AppIcons/icon-ios-83.5@2x.png
new file mode 100644
index 00000000..917a2a63
Binary files /dev/null and b/docs/res/AppIcon/AppIcons/icon-ios-83.5@2x.png differ
diff --git a/docs/res/AppIcon/AppIcons/icon-ios.svg b/docs/res/AppIcon/AppIcons/icon-ios.svg
new file mode 100644
index 00000000..be6d0dff
--- /dev/null
+++ b/docs/res/AppIcon/AppIcons/icon-ios.svg
@@ -0,0 +1,21 @@
+
diff --git a/docs/res/AppIcon/AppIconsMitB.zip b/docs/res/AppIcon/AppIconsMitB.zip
new file mode 100644
index 00000000..7b1b3fcf
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB.zip differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-1024@1x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-1024@1x.png
new file mode 100644
index 00000000..f6d8ac2e
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-1024@1x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-20@2x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-20@2x.png
new file mode 100644
index 00000000..32cf9dad
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-20@2x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-20@3x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-20@3x.png
new file mode 100644
index 00000000..eb47edf1
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-20@3x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-29@2x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-29@2x.png
new file mode 100644
index 00000000..0b704ce5
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-29@2x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-29@3x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-29@3x.png
new file mode 100644
index 00000000..3dd1d0a9
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-29@3x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-40@2x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-40@2x.png
new file mode 100644
index 00000000..40f45f69
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-40@2x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-40@3x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-40@3x.png
new file mode 100644
index 00000000..071a2d9a
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-40@3x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-60@2x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-60@2x.png
new file mode 100644
index 00000000..071a2d9a
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-60@2x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-60@3x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-60@3x.png
new file mode 100644
index 00000000..a02004af
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-60@3x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-76@2x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-76@2x.png
new file mode 100644
index 00000000..38e65c7b
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-76@2x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios-83.5@2x.png b/docs/res/AppIcon/AppIconsMitB/icon-ios-83.5@2x.png
new file mode 100644
index 00000000..a04586ca
Binary files /dev/null and b/docs/res/AppIcon/AppIconsMitB/icon-ios-83.5@2x.png differ
diff --git a/docs/res/AppIcon/AppIconsMitB/icon-ios.svg b/docs/res/AppIcon/AppIconsMitB/icon-ios.svg
new file mode 100644
index 00000000..2fe78812
--- /dev/null
+++ b/docs/res/AppIcon/AppIconsMitB/icon-ios.svg
@@ -0,0 +1,22 @@
+
diff --git a/docs/res/icons/BankTransfer.pdf b/docs/res/icons/BankTransfer.pdf
new file mode 100644
index 00000000..94d9188b
--- /dev/null
+++ b/docs/res/icons/BankTransfer.pdf
@@ -0,0 +1,362 @@
+%PDF-1.7
+
+1 0 obj
+ << >>
+endobj
+
+2 0 obj
+ << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 0.000000 12.840942 cm
+0.000000 0.000000 0.000000 scn
+1.279276 25.159058 m
+0.572751 25.159058 0.000000 24.586306 0.000000 23.879782 c
+0.000000 17.483404 l
+0.000000 1.279245 l
+0.000000 0.572721 0.572751 -0.000031 1.279276 -0.000031 c
+5.221627 -0.000031 l
+5.221627 2.558521 l
+2.558551 2.558521 l
+2.558551 17.483404 l
+2.558551 22.600506 l
+36.028580 22.600506 l
+36.028580 20.894806 l
+38.587132 20.894806 l
+38.587132 23.879782 l
+38.587132 24.586306 38.014378 25.159058 37.307854 25.159058 c
+1.279276 25.159058 l
+h
+f*
+n
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 3.942383 9.056763 cm
+0.000000 0.000000 0.000000 scn
+1.279276 25.105347 m
+36.988125 25.105347 l
+37.327412 25.105347 37.652798 24.970568 37.892708 24.730656 c
+38.132618 24.490746 38.267403 24.165356 38.267403 23.826071 c
+38.267403 10.402944 l
+37.452763 10.640730 36.596001 10.804845 35.708851 10.885599 c
+35.708851 22.546795 l
+2.558552 22.546795 l
+2.558552 2.558540 l
+23.013508 2.558540 l
+22.961720 2.192711 22.935091 1.820532 22.935091 1.443214 c
+22.935091 0.952564 22.980118 0.470600 23.066944 -0.000010 c
+1.279276 -0.000010 l
+0.939991 -0.000010 0.614603 0.134769 0.374692 0.374680 c
+0.134781 0.614590 0.000000 0.939981 0.000000 1.279266 c
+0.000000 23.826071 l
+0.000000 24.165356 0.134781 24.490746 0.374692 24.730656 c
+0.614603 24.970568 0.939991 25.105347 1.279276 25.105347 c
+h
+23.255920 6.382050 m
+22.035740 5.566751 20.601198 5.131590 19.133701 5.131590 c
+17.166679 5.134298 15.280995 5.916893 13.890100 7.307789 c
+12.499204 8.698685 11.716607 10.584367 11.713900 12.551389 c
+11.713900 14.018887 12.149064 15.453429 12.964362 16.673609 c
+13.779660 17.893787 14.938475 18.844801 16.294266 19.406387 c
+17.650057 19.967976 19.141930 20.114914 20.581230 19.828619 c
+22.020531 19.542324 23.342613 18.835655 24.380291 17.797979 c
+25.417969 16.760302 26.124636 15.438218 26.410931 13.998919 c
+26.697226 12.559619 26.550285 11.067746 25.988699 9.711955 c
+25.427113 8.356165 24.476101 7.197348 23.255920 6.382050 c
+h
+21.834467 16.593369 m
+21.035038 17.127529 20.095165 17.412636 19.133701 17.412636 c
+19.133701 17.414341 l
+17.844608 17.412762 16.608788 16.899853 15.697420 15.988167 c
+14.786053 15.076480 14.273580 13.840483 14.272451 12.551389 c
+14.272451 11.589925 14.557560 10.650051 15.091721 9.850623 c
+15.625881 9.051195 16.385103 8.428120 17.273380 8.060183 c
+18.161657 7.692245 19.139093 7.595976 20.082083 7.783548 c
+21.025072 7.971121 21.891266 8.434109 22.571123 9.113967 c
+23.250980 9.793824 23.713966 10.660017 23.901539 11.603006 c
+24.089111 12.545996 23.992846 13.523432 23.624908 14.411709 c
+23.256971 15.299986 22.633896 16.059208 21.834467 16.593369 c
+h
+f*
+n
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 8.500000 27.750000 cm
+0.000000 0.000000 0.000000 scn
+0.000000 1.250000 m
+0.000000 1.940356 0.559644 2.500000 1.250000 2.500000 c
+5.250000 2.500000 l
+5.940356 2.500000 6.500000 1.940356 6.500000 1.250000 c
+6.500000 0.559644 5.940356 0.000000 5.250000 0.000000 c
+1.250000 0.000000 l
+0.559644 0.000000 0.000000 0.559644 0.000000 1.250000 c
+h
+f*
+n
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 33.000000 12.000000 cm
+0.000000 0.000000 0.000000 scn
+0.000000 1.000000 m
+0.000000 1.552285 0.447715 2.000000 1.000000 2.000000 c
+8.000000 2.000000 l
+8.552285 2.000000 9.000000 1.552285 9.000000 1.000000 c
+9.000000 1.000000 l
+9.000000 0.447715 8.552285 0.000000 8.000000 0.000000 c
+1.000000 0.000000 l
+0.447715 0.000000 0.000000 0.447715 0.000000 1.000000 c
+0.000000 1.000000 l
+h
+f
+n
+Q
+q
+q
+-1.000000 -0.000000 -0.000000 1.000000 43.000000 6.000000 cm
+0.000000 0.000000 0.000000 scn
+0.000000 1.000000 m
+0.000000 1.552285 0.447715 2.000000 1.000000 2.000000 c
+8.000000 2.000000 l
+8.552285 2.000000 9.000000 1.552285 9.000000 1.000000 c
+9.000000 1.000000 l
+9.000000 0.447715 8.552285 0.000000 8.000000 0.000000 c
+1.000000 0.000000 l
+0.447715 0.000000 0.000000 0.447715 0.000000 1.000000 c
+0.000000 1.000000 l
+h
+f
+n
+Q
+43.000000 7.000000 m
+43.000000 7.552284 42.552284 8.000000 42.000000 8.000000 c
+35.000000 8.000000 l
+34.447716 8.000000 34.000000 7.552284 34.000000 7.000000 c
+34.000000 7.000000 l
+34.000000 6.447716 34.447716 6.000000 35.000000 6.000000 c
+42.000000 6.000000 l
+42.552284 6.000000 43.000000 6.447716 43.000000 7.000000 c
+43.000000 7.000000 l
+h
+W*
+n
+q
+-1.000000 -0.000000 -0.000000 1.000000 43.000000 6.000000 cm
+0.000000 0.000000 0.000000 scn
+1.000000 1.000000 m
+8.000000 1.000000 l
+8.000000 3.000000 l
+1.000000 3.000000 l
+1.000000 1.000000 l
+h
+8.000000 1.000000 m
+1.000000 1.000000 l
+1.000000 -1.000000 l
+8.000000 -1.000000 l
+8.000000 1.000000 l
+h
+1.000000 1.000000 m
+1.000000 1.000000 l
+-1.000000 1.000000 l
+-1.000000 -0.104569 -0.104570 -1.000000 1.000000 -1.000000 c
+1.000000 1.000000 l
+h
+8.000000 1.000000 m
+8.000000 1.000000 l
+8.000000 -1.000000 l
+9.104569 -1.000000 10.000000 -0.104569 10.000000 1.000000 c
+8.000000 1.000000 l
+h
+8.000000 1.000000 m
+8.000000 1.000000 l
+10.000000 1.000000 l
+10.000000 2.104569 9.104569 3.000000 8.000000 3.000000 c
+8.000000 1.000000 l
+h
+1.000000 3.000000 m
+-0.104569 3.000000 -1.000000 2.104569 -1.000000 1.000000 c
+1.000000 1.000000 l
+1.000000 1.000000 l
+1.000000 3.000000 l
+h
+f
+n
+Q
+Q
+q
+50.000000 10.000000 m
+50.000000 4.477154 44.851273 0.000000 38.500000 0.000000 c
+32.148727 0.000000 27.000000 4.477154 27.000000 10.000000 c
+27.000000 15.522848 32.148727 20.000000 38.500000 20.000000 c
+44.851273 20.000000 50.000000 15.522848 50.000000 10.000000 c
+h
+W*
+n
+q
+1.000000 0.000000 -0.000000 1.000000 27.000000 0.000000 cm
+0.000000 0.000000 0.000000 scn
+22.000000 10.000000 m
+22.000000 5.156100 17.434797 1.000000 11.500000 1.000000 c
+11.500000 -1.000000 l
+18.267752 -1.000000 24.000000 3.798204 24.000000 10.000000 c
+22.000000 10.000000 l
+h
+11.500000 1.000000 m
+5.565202 1.000000 1.000000 5.156100 1.000000 10.000000 c
+-1.000000 10.000000 l
+-1.000000 3.798204 4.732249 -1.000000 11.500000 -1.000000 c
+11.500000 1.000000 l
+h
+1.000000 10.000000 m
+1.000000 14.843899 5.565202 19.000000 11.500000 19.000000 c
+11.500000 21.000000 l
+4.732249 21.000000 -1.000000 16.201796 -1.000000 10.000000 c
+1.000000 10.000000 l
+h
+11.500000 19.000000 m
+17.434797 19.000000 22.000000 14.843899 22.000000 10.000000 c
+24.000000 10.000000 l
+24.000000 16.201796 18.267752 21.000000 11.500000 21.000000 c
+11.500000 19.000000 l
+h
+f
+n
+Q
+Q
+q
+0.707107 -0.707107 0.707107 0.707107 28.118925 3.187651 cm
+0.000000 0.000000 0.000000 scn
+1.000000 6.949707 m
+0.447715 6.949707 0.000000 6.501992 0.000000 5.949707 c
+0.000000 5.397422 0.447715 4.949707 1.000000 4.949707 c
+1.000000 6.949707 l
+h
+4.000000 4.949707 m
+4.552285 4.949707 5.000000 5.397422 5.000000 5.949707 c
+5.000000 6.501992 4.552285 6.949707 4.000000 6.949707 c
+4.000000 4.949707 l
+h
+1.000000 4.949707 m
+4.000000 4.949707 l
+4.000000 6.949707 l
+1.000000 6.949707 l
+1.000000 4.949707 l
+h
+f
+n
+Q
+q
+0.707107 0.707107 -0.707107 0.707107 36.499969 1.964506 cm
+0.000000 0.000000 0.000000 scn
+1.000000 6.949707 m
+0.447715 6.949707 0.000000 6.501992 0.000000 5.949707 c
+0.000000 5.397422 0.447715 4.949707 1.000000 4.949707 c
+1.000000 6.949707 l
+h
+4.000000 4.949707 m
+4.552285 4.949707 5.000000 5.397422 5.000000 5.949707 c
+5.000000 6.501992 4.552285 6.949707 4.000000 6.949707 c
+4.000000 4.949707 l
+h
+1.000000 4.949707 m
+4.000000 4.949707 l
+4.000000 6.949707 l
+1.000000 6.949707 l
+1.000000 4.949707 l
+h
+f
+n
+Q
+q
+-0.707107 0.707107 -0.707107 -0.707107 47.035614 16.964449 cm
+0.000000 0.000000 0.000000 scn
+1.000000 6.949707 m
+0.447715 6.949707 0.000000 6.501992 0.000000 5.949707 c
+0.000000 5.397422 0.447715 4.949707 1.000000 4.949707 c
+1.000000 6.949707 l
+h
+4.000000 4.949707 m
+4.552285 4.949707 5.000000 5.397422 5.000000 5.949707 c
+5.000000 6.501992 4.552285 6.949707 4.000000 6.949707 c
+4.000000 4.949707 l
+h
+1.000000 4.949707 m
+4.000000 4.949707 l
+4.000000 6.949707 l
+1.000000 6.949707 l
+1.000000 4.949707 l
+h
+f
+n
+Q
+q
+-0.707107 -0.707107 0.707107 -0.707107 39.035675 17.499971 cm
+0.000000 0.000000 0.000000 scn
+1.000000 6.949707 m
+0.447715 6.949707 0.000000 6.501992 0.000000 5.949707 c
+0.000000 5.397422 0.447715 4.949707 1.000000 4.949707 c
+1.000000 6.949707 l
+h
+4.000000 4.949707 m
+4.552285 4.949707 5.000000 5.397422 5.000000 5.949707 c
+5.000000 6.501992 4.552285 6.949707 4.000000 6.949707 c
+4.000000 4.949707 l
+h
+1.000000 4.949707 m
+4.000000 4.949707 l
+4.000000 6.949707 l
+1.000000 6.949707 l
+1.000000 4.949707 l
+h
+f
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+ 8320
+endobj
+
+4 0 obj
+ << /Annots []
+ /Type /Page
+ /MediaBox [ 0.000000 0.000000 50.000000 38.000000 ]
+ /Resources 1 0 R
+ /Contents 2 0 R
+ /Parent 5 0 R
+ >>
+endobj
+
+5 0 obj
+ << /Kids [ 4 0 R ]
+ /Count 1
+ /Type /Pages
+ >>
+endobj
+
+6 0 obj
+ << /Type /Catalog
+ /Pages 5 0 R
+ >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000008410 00000 n
+0000008433 00000 n
+0000008606 00000 n
+0000008680 00000 n
+trailer
+<< /ID [ (some) (id) ]
+ /Root 6 0 R
+ /Size 7
+>>
+startxref
+8739
+%%EOF
\ No newline at end of file
diff --git a/docs/res/icons/gear.fill.pdf b/docs/res/icons/gear.fill.pdf
new file mode 100644
index 00000000..6591a0b4
--- /dev/null
+++ b/docs/res/icons/gear.fill.pdf
@@ -0,0 +1,170 @@
+%PDF-1.7
+
+1 0 obj
+ << >>
+endobj
+
+2 0 obj
+ << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
+0.596078 0.592157 0.572549 scn
+12.000000 0.000000 m
+18.627417 0.000000 24.000000 5.372583 24.000000 12.000000 c
+24.000000 18.627417 18.627417 24.000000 12.000000 24.000000 c
+5.372583 24.000000 0.000000 18.627417 0.000000 12.000000 c
+0.000000 5.372583 5.372583 0.000000 12.000000 0.000000 c
+h
+11.356085 20.726612 m
+11.080673 20.706541 10.887666 20.454128 10.923384 20.180305 c
+11.042957 19.263630 l
+10.397048 19.179354 9.777586 19.010939 9.195930 18.769743 c
+8.841808 19.623703 l
+8.736031 19.878782 8.442759 20.001123 8.194168 19.880884 c
+7.804816 19.692562 7.431699 19.476336 7.077398 19.234867 c
+6.849212 19.079351 6.808879 18.764158 6.977139 18.545200 c
+7.540419 17.812202 l
+7.032850 17.422173 6.577827 16.967148 6.187798 16.459579 c
+5.454800 17.022860 l
+5.235841 17.191120 4.920649 17.150787 4.765132 16.922600 c
+4.523664 16.568302 4.307439 16.195185 4.119116 15.805833 c
+3.998877 15.557242 4.121218 15.263969 4.376298 15.158192 c
+5.230257 14.804070 l
+4.989061 14.222414 4.820646 13.602952 4.736370 12.957043 c
+3.819693 13.076614 l
+3.545871 13.112333 3.293459 12.919325 3.273387 12.643913 c
+3.257878 12.431119 3.250000 12.216384 3.250000 12.000000 c
+3.250000 11.783616 3.257878 11.568881 3.273387 11.356086 c
+3.293460 11.080674 3.545871 10.887668 3.819694 10.923385 c
+4.736370 11.042957 l
+4.820646 10.397048 4.989061 9.777586 5.230256 9.195931 c
+4.376297 8.841809 l
+4.121218 8.736032 3.998877 8.442759 4.119116 8.194168 c
+4.307439 7.804817 4.523664 7.431700 4.765132 7.077400 c
+4.920649 6.849213 5.235842 6.808880 5.454801 6.977140 c
+6.187798 7.540421 l
+6.577827 7.032852 7.032850 6.577827 7.540419 6.187798 c
+6.977141 5.454802 l
+6.808880 5.235844 6.849213 4.920650 7.077399 4.765133 c
+7.431699 4.523664 7.804815 4.307440 8.194167 4.119116 c
+8.442758 3.998877 8.736031 4.121218 8.841808 4.376299 c
+9.195930 5.230255 l
+9.777586 4.989059 10.397048 4.820644 11.042957 4.736368 c
+10.923386 3.819695 l
+10.887667 3.545872 11.080674 3.293459 11.356086 3.273388 c
+11.568880 3.257879 11.783616 3.250000 12.000000 3.250000 c
+12.216384 3.250000 12.431120 3.257879 12.643914 3.273388 c
+12.919326 3.293459 13.112333 3.545872 13.076615 3.819695 c
+12.957043 4.736368 l
+13.602952 4.820644 14.222414 4.989059 14.804070 5.230255 c
+15.158191 4.376299 l
+15.263968 4.121218 15.557241 3.998877 15.805832 4.119116 c
+16.195183 4.307440 16.568300 4.523664 16.922600 4.765133 c
+17.150787 4.920650 17.191120 5.235844 17.022858 5.454802 c
+16.459581 6.187798 l
+16.967150 6.577827 17.422173 7.032850 17.812202 7.540419 c
+18.545198 6.977142 l
+18.764156 6.808880 19.079350 6.849213 19.234867 7.077400 c
+19.476336 7.431700 19.692560 7.804817 19.880884 8.194167 c
+20.001123 8.442758 19.878782 8.736032 19.623701 8.841808 c
+18.769745 9.195930 l
+19.010941 9.777586 19.179356 10.397049 19.263632 11.042958 c
+20.180305 10.923386 l
+20.454128 10.887668 20.706541 11.080674 20.726612 11.356086 c
+20.742121 11.568881 20.750000 11.783616 20.750000 12.000000 c
+20.750000 12.216385 20.742121 12.431121 20.726612 12.643916 c
+20.706541 12.919327 20.454128 13.112334 20.180305 13.076616 c
+19.263632 12.957044 l
+19.179356 13.602953 19.010939 14.222414 18.769745 14.804070 c
+19.623701 15.158192 l
+19.878782 15.263969 20.001123 15.557241 19.880884 15.805832 c
+19.692560 16.195185 19.476336 16.568302 19.234867 16.922602 c
+19.079350 17.150787 18.764156 17.191120 18.545198 17.022861 c
+17.812202 16.459581 l
+17.422173 16.967150 16.967148 17.422173 16.459579 17.812202 c
+17.022860 18.545200 l
+17.191120 18.764158 17.150787 19.079351 16.922600 19.234867 c
+16.568300 19.476336 16.195183 19.692562 15.805832 19.880884 c
+15.557241 20.001123 15.263968 19.878782 15.158192 19.623703 c
+14.804069 18.769743 l
+14.222413 19.010939 13.602951 19.179354 12.957042 19.263630 c
+13.076614 20.180307 l
+13.112332 20.454130 12.919325 20.706541 12.643913 20.726612 c
+12.431118 20.742123 12.216383 20.750000 12.000000 20.750000 c
+11.783615 20.750000 11.568880 20.742123 11.356085 20.726612 c
+h
+12.696518 11.185913 m
+18.050842 11.185913 l
+17.652849 8.199290 15.095482 5.895348 12.000000 5.895348 c
+11.021035 5.895348 10.095892 6.125784 9.275852 6.535372 c
+11.844859 10.710011 l
+12.026858 11.005757 12.349257 11.185913 12.696518 11.185913 c
+h
+5.895349 12.000000 m
+5.895349 10.045127 6.814215 8.304866 8.243605 7.187559 c
+10.807167 11.353347 l
+10.988450 11.647931 11.004625 12.015280 10.849936 12.324657 c
+8.508228 17.008072 l
+6.928618 15.904668 5.895349 14.073000 5.895349 12.000000 c
+h
+12.000000 18.104652 m
+11.138405 18.104652 10.318498 17.926159 9.575241 17.604132 c
+11.897492 12.959629 l
+12.066884 12.620845 12.413148 12.406842 12.791920 12.406842 c
+18.091309 12.406842 l
+17.881950 15.588663 15.234796 18.104652 12.000000 18.104652 c
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+ 4761
+endobj
+
+4 0 obj
+ << /Annots []
+ /Type /Page
+ /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
+ /Resources 1 0 R
+ /Contents 2 0 R
+ /Parent 5 0 R
+ >>
+endobj
+
+5 0 obj
+ << /Kids [ 4 0 R ]
+ /Count 1
+ /Type /Pages
+ >>
+endobj
+
+6 0 obj
+ << /Type /Catalog
+ /Pages 5 0 R
+ >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000004851 00000 n
+0000004874 00000 n
+0000005047 00000 n
+0000005121 00000 n
+trailer
+<< /ID [ (some) (id) ]
+ /Root 6 0 R
+ /Size 7
+>>
+startxref
+5180
+%%EOF
\ No newline at end of file
diff --git a/docs/res/icons/new.pdf b/docs/res/icons/new.pdf
new file mode 100644
index 00000000..c7d904f6
--- /dev/null
+++ b/docs/res/icons/new.pdf
@@ -0,0 +1,88 @@
+%PDF-1.7
+
+1 0 obj
+ << >>
+endobj
+
+2 0 obj
+ << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
+0.596078 0.592157 0.572549 scn
+12.000000 0.000000 m
+18.627417 0.000000 24.000000 5.372583 24.000000 12.000000 c
+24.000000 18.627417 18.627417 24.000000 12.000000 24.000000 c
+5.372583 24.000000 0.000000 18.627417 0.000000 12.000000 c
+0.000000 5.372583 5.372583 0.000000 12.000000 0.000000 c
+h
+11.272544 19.262787 m
+11.265584 19.754541 11.632695 20.000000 11.999791 20.000000 c
+12.366895 20.000000 12.734310 19.754541 12.727037 19.262787 c
+12.727037 12.727312 l
+19.262306 12.727312 l
+20.245783 12.741233 20.245783 11.258884 19.262306 11.272775 c
+12.727037 11.272775 l
+12.727037 4.737299 l
+12.732529 4.336187 12.412436 4.006634 12.006896 4.000090 c
+11.601364 3.993753 11.266726 4.327286 11.272544 4.737299 c
+11.272544 11.272775 l
+4.737278 11.272775 l
+4.336182 11.267284 4.006634 11.587388 4.000089 11.992941 c
+3.993754 12.398488 4.327280 12.733130 4.737278 12.727312 c
+11.272544 12.727312 l
+11.272544 19.262787 l
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+ 1007
+endobj
+
+4 0 obj
+ << /Annots []
+ /Type /Page
+ /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
+ /Resources 1 0 R
+ /Contents 2 0 R
+ /Parent 5 0 R
+ >>
+endobj
+
+5 0 obj
+ << /Kids [ 4 0 R ]
+ /Count 1
+ /Type /Pages
+ >>
+endobj
+
+6 0 obj
+ << /Type /Catalog
+ /Pages 5 0 R
+ >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000001097 00000 n
+0000001120 00000 n
+0000001293 00000 n
+0000001367 00000 n
+trailer
+<< /ID [ (some) (id) ]
+ /Root 6 0 R
+ /Size 7
+>>
+startxref
+1426
+%%EOF
\ No newline at end of file
diff --git a/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt b/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt
index d45a211f..87c99180 100644
--- a/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt
+++ b/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt
@@ -14,9 +14,7 @@ import net.dankito.banking.LuceneConfig.Companion.OtherPartyAccountIdFieldName
import net.dankito.banking.LuceneConfig.Companion.OtherPartyBankCodeFieldName
import net.dankito.banking.LuceneConfig.Companion.OtherPartyNameFieldName
import net.dankito.banking.LuceneConfig.Companion.UsageFieldName
-import net.dankito.banking.ui.model.Customer
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.*
import net.dankito.banking.util.ISerializer
import net.dankito.banking.util.JacksonJsonSerializer
import net.dankito.utils.lucene.index.DocumentsWriter
@@ -47,7 +45,7 @@ open class LuceneBankingPersistence(
protected val fields = FieldBuilder()
- override fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List) {
+ override fun saveOrUpdateAccountTransactions(bankAccount: TypedBankAccount, transactions: List) {
val writer = getWriter()
transactions.forEach { transaction ->
@@ -60,7 +58,7 @@ open class LuceneBankingPersistence(
writer.flushChangesToDisk()
}
- protected open fun createFieldsForAccountTransaction(bankAccount: BankAccount, transaction: AccountTransaction): List {
+ protected open fun createFieldsForAccountTransaction(bankAccount: TypedBankAccount, transaction: IAccountTransaction): List {
return listOf(
fields.keywordField(BankAccountIdFieldName, bankAccount.technicalId),
fields.nullableFullTextSearchField(OtherPartyNameFieldName, transaction.otherPartyName, true),
@@ -79,7 +77,7 @@ open class LuceneBankingPersistence(
}
- override fun deleteAccount(customer: Customer, allCustomers: List) {
+ override fun deleteAccount(customer: TypedCustomer, allCustomers: List) {
try {
deleteAccountTransactions(customer.accounts)
} catch (e: Exception) {
@@ -89,7 +87,7 @@ open class LuceneBankingPersistence(
super.deleteAccount(customer, allCustomers)
}
- protected open fun deleteAccountTransactions(bankAccounts: List) {
+ protected open fun deleteAccountTransactions(bankAccounts: List) {
val writer = getWriter()
val bankAccountIds = bankAccounts.map { it.technicalId }
diff --git a/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt b/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt
index d3681437..12d927f6 100644
--- a/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt
+++ b/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt
@@ -5,12 +5,14 @@ import net.dankito.banking.ui.model.Customer
import net.dankito.banking.ui.model.AccountTransaction
import net.dankito.banking.ui.model.BankAccount
import net.dankito.utils.io.FileUtils
+import net.dankito.utils.multiplatform.File
+import net.dankito.utils.multiplatform.toBigDecimal
+import net.dankito.utils.multiplatform.toDate
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito.mock
-import java.io.File
import java.math.BigDecimal
import java.text.SimpleDateFormat
import java.util.*
@@ -211,7 +213,7 @@ class LuceneRemitteeSearcherTest {
otherPartyName: String = randomString(), otherPartyBankCode: String = randomString(),
otherPartyAccountId: String = randomString(), usage: String = randomString()): AccountTransaction {
- return AccountTransaction(bankAccount, amount, "EUR", usage, bookingDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, null, bookingDate)
+ return AccountTransaction(bankAccount, amount.toBigDecimal(), "EUR", usage, bookingDate.toDate(), otherPartyName, otherPartyBankCode, otherPartyAccountId, null, bookingDate.toDate())
}
private fun randomString(): String {
diff --git a/persistence/json/BankingPersistenceJson/build.gradle b/persistence/json/BankingPersistenceJson/build.gradle
index c9eb8ad8..5177cf94 100644
--- a/persistence/json/BankingPersistenceJson/build.gradle
+++ b/persistence/json/BankingPersistenceJson/build.gradle
@@ -17,10 +17,6 @@ compileTestKotlin {
dependencies {
implementation project(':BankingUiCommon')
- implementation("org.mapstruct:mapstruct:$mapStructVersion")
-
- kapt("org.mapstruct:mapstruct-processor:$mapStructVersion")
-
testImplementation "junit:junit:$junitVersion"
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/BankingPersistenceJson.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/BankingPersistenceJson.kt
index 909a906d..32769af6 100644
--- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/BankingPersistenceJson.kt
+++ b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/BankingPersistenceJson.kt
@@ -1,13 +1,9 @@
package net.dankito.banking.persistence
-import net.dankito.banking.persistence.mapper.CustomerConverter
import net.dankito.banking.persistence.model.CustomerEntity
+import net.dankito.banking.ui.model.*
import net.dankito.utils.multiplatform.File
-import net.dankito.banking.ui.model.Customer
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
import net.dankito.banking.util.ISerializer
-import org.mapstruct.factory.Mappers
import java.io.FileOutputStream
import java.net.URL
@@ -17,39 +13,32 @@ open class BankingPersistenceJson(
protected val serializer: ISerializer
) : IBankingPersistence {
- protected val mapper = Mappers.getMapper(CustomerConverter::class.java)
-
-
init {
jsonFile.absoluteFile.parentFile.mkdirs()
}
- override fun saveOrUpdateAccount(customer: Customer, allCustomers: List) {
+ override fun saveOrUpdateAccount(customer: TypedCustomer, allCustomers: List) {
saveAllCustomers(allCustomers)
}
- override fun deleteAccount(customer: Customer, allCustomers: List) {
+ override fun deleteAccount(customer: TypedCustomer, allCustomers: List) {
saveAllCustomers(allCustomers)
}
- override fun readPersistedAccounts(): List {
- val deserializedCustomers = serializer.deserializeListOr(jsonFile, CustomerEntity::class)
-
- return mapper.mapCustomerEntities(deserializedCustomers)
+ override fun readPersistedAccounts(): List {
+ return serializer.deserializeListOr(jsonFile, CustomerEntity::class).map { it as TypedCustomer }
}
- override fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List) {
+ override fun saveOrUpdateAccountTransactions(bankAccount: TypedBankAccount, transactions: List) {
// done when called saveOrUpdateAccount()
// TODO: or also call saveAllCustomers()?
}
- protected open fun saveAllCustomers(allCustomers: List) {
- val mappedCustomers = mapper.mapCustomers(allCustomers)
-
- serializer.serializeObject(mappedCustomers, jsonFile)
+ protected open fun saveAllCustomers(allCustomers: List) {
+ serializer.serializeObject(allCustomers, jsonFile)
}
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/CustomerConverter.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/CustomerConverter.kt
deleted file mode 100644
index 2a1936cb..00000000
--- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/CustomerConverter.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-package net.dankito.banking.persistence.mapper
-
-import net.dankito.banking.persistence.model.AccountTransactionEntity
-import net.dankito.banking.persistence.model.BankAccountEntity
-import net.dankito.banking.persistence.model.CustomerEntity
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
-import net.dankito.banking.ui.model.Customer
-import org.mapstruct.*
-
-
-@Mapper
-abstract class CustomerConverter {
-
- // Context is needed to fix cycle dependencies issue
-
- protected val bankAccountCustomerField = BankAccount::class.java.getDeclaredField(BankAccount::customer.name)
-
-
- init {
- bankAccountCustomerField.isAccessible = true
- }
-
-
- @Mapping(source = "technicalId", target = "id")
- abstract fun mapToEntity(customer: Customer, @Context context: CycleAvoidingMappingContext): CustomerEntity
-
- @InheritInverseConfiguration
- abstract fun mapCustomer(customer: CustomerEntity, @Context context: CycleAvoidingMappingContext): Customer
-
- abstract fun mapCustomers(customers: List, @Context context: CycleAvoidingMappingContext): List
-
- open fun mapCustomers(customers: List): List {
- // create a new context instance each time as otherwise just cached instance would be taken und BankAccounts and AccountTransactions would never get updated
- return mapCustomers(customers, CycleAvoidingMappingContext())
- }
-
- abstract fun mapCustomerEntities(customers: List, @Context context: CycleAvoidingMappingContext): List
-
- open fun mapCustomerEntities(customers: List): List {
- // create a new context instance each time as otherwise just cached instance would be taken und BankAccounts and AccountTransactions would never get updated
- return mapCustomerEntities(customers, CycleAvoidingMappingContext())
- }
-
-
- @Mapping(source = "technicalId", target = "id")
- abstract fun mapBankAccount(account: BankAccount, @Context context: CycleAvoidingMappingContext): BankAccountEntity
-
- @InheritInverseConfiguration
- abstract fun mapBankAccount(account: BankAccountEntity, @Context context: CycleAvoidingMappingContext): BankAccount
-
- abstract fun mapBankAccounts(accounts: List, @Context context: CycleAvoidingMappingContext): List
-
- abstract fun mapBankAccountEntities(accounts: List, @Context context: CycleAvoidingMappingContext): List
-
- @AfterMapping
- open fun mapBankAccountCustomer(serializedAccount: BankAccountEntity, @MappingTarget account: BankAccount, @Context context: CycleAvoidingMappingContext) {
- val mappedCustomer = mapCustomer(serializedAccount.customer, context)
-
- bankAccountCustomerField.set(account, mappedCustomer)
- }
-
-
-
- @Mapping(source = "technicalId", target = "id")
- abstract fun mapTransaction(transaction: AccountTransaction, @Context context: CycleAvoidingMappingContext): AccountTransactionEntity
-
- @InheritInverseConfiguration
- fun mapTransaction(transaction: AccountTransactionEntity, @Context context: CycleAvoidingMappingContext): AccountTransaction {
- val account = mapBankAccount(transaction.bankAccount, context)
-
- val mappedTransaction = AccountTransaction(account, transaction.amount, transaction.currency, transaction.unparsedUsage, transaction.bookingDate,
- transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId, transaction.bookingText,
- transaction.valueDate, transaction.statementNumber, transaction.sequenceNumber, transaction.openingBalance, transaction.closingBalance,
- transaction.endToEndReference, transaction.customerReference, transaction.mandateReference, transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
- transaction.compensationAmount, transaction.originalAmount, transaction.sepaUsage, transaction.deviantOriginator, transaction.deviantRecipient,
- transaction.usageWithNoSpecialType, transaction.primaNotaNumber, transaction.textKeySupplement, transaction.currencyType, transaction.bookingKey,
- transaction.referenceForTheAccountOwner, transaction.referenceOfTheAccountServicingInstitution, transaction.supplementaryDetails,
- transaction.transactionReferenceNumber, transaction.relatedReferenceNumber)
-
- mappedTransaction.technicalId = transaction.id
-
- return mappedTransaction
- }
-
- abstract fun mapTransactions(transactions: List, @Context context: CycleAvoidingMappingContext): List
-
- abstract fun mapTransactionEntities(transactions: List, @Context context: CycleAvoidingMappingContext): List
-
-}
\ No newline at end of file
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/CycleAvoidingMappingContext.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/CycleAvoidingMappingContext.kt
deleted file mode 100644
index fb1cdc35..00000000
--- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/CycleAvoidingMappingContext.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package net.dankito.banking.persistence.mapper
-
-import org.mapstruct.BeforeMapping
-import org.mapstruct.MappingTarget
-import org.mapstruct.TargetType
-import java.util.*
-
-
-open class CycleAvoidingMappingContext {
-
- private val knownInstances: MutableMap = IdentityHashMap()
-
-
- /**
- * Gets an instance out of this context if it is already mapped.
- */
- @BeforeMapping
- open fun getMappedInstance(source: Any, @TargetType targetType: Class): T {
- return targetType.cast(knownInstances[source])
- }
-
- /**
- * Puts an instance into the cache, so that it can be remembered to avoid endless mapping.
- */
- @BeforeMapping
- open fun storeMappedInstance(source: Any, @MappingTarget target: Any) {
- knownInstances[source] = target
- }
-
-}
\ No newline at end of file
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/EntitiesMapper.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/EntitiesMapper.kt
deleted file mode 100644
index b00d1336..00000000
--- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/EntitiesMapper.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-package net.dankito.banking.persistence.mapper
-
-import net.dankito.banking.persistence.model.AccountTransactionEntity
-import net.dankito.banking.persistence.model.BankAccountEntity
-import net.dankito.banking.persistence.model.CustomerEntity
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
-import net.dankito.banking.ui.model.Customer
-
-
-open class EntitiesMapper {
-
- open fun mapCustomers(customers: List): List {
- return customers.map { mapCustomer(it) }
- }
-
- open fun mapCustomer(customer: Customer): CustomerEntity {
- val mappedCustomer = CustomerEntity(
- customer.bankCode, customer.customerId, customer.password, customer.finTsServerAddress,
- customer.bankName, customer.bic, customer.customerName, customer.userId, customer.iconUrl,
- listOf(), customer.supportedTanProcedures, customer.selectedTanProcedure, customer.tanMedia
- )
-
- mappedCustomer.id = customer.technicalId
- mappedCustomer.userSetDisplayName = customer.userSetDisplayName
-
- mappedCustomer.accounts = mapBankAccounts(customer.accounts, mappedCustomer)
-
- return mappedCustomer
- }
-
-
- open fun mapCustomerEntities(customers: List): List {
- return customers.map { mapCustomer(it) }
- }
-
- open fun mapCustomer(customer: CustomerEntity): Customer {
- val mappedCustomer = Customer(
- customer.bankCode, customer.customerId, customer.password, customer.finTsServerAddress,
- customer.bankName, customer.bic, customer.customerName, customer.userId, customer.iconUrl
- )
-
- mappedCustomer.technicalId = customer.id
- mappedCustomer.userSetDisplayName = customer.userSetDisplayName
-
- mappedCustomer.accounts = mapBankAccounts(customer.accounts, mappedCustomer)
-
-
- mappedCustomer.supportedTanProcedures = customer.supportedTanProcedures
- mappedCustomer.selectedTanProcedure = customer.selectedTanProcedure
- mappedCustomer.tanMedia = customer.tanMedia
-
- return mappedCustomer
- }
-
-
- open fun mapBankAccounts(transactions: List, customer: CustomerEntity): List {
- return transactions.map { mapBankAccount(it, customer) }
- }
-
- open fun mapBankAccount(account: BankAccount, customer: CustomerEntity): BankAccountEntity {
- val mappedAccount = BankAccountEntity(
- customer, account.identifier, account.accountHolderName, account.iban, account.subAccountNumber,
- account.customerId, account.balance, account.currency, account.type, account.productName,
- account.accountLimit, account.lastRetrievedTransactionsTimestamp,
- account.supportsRetrievingAccountTransactions, account.supportsRetrievingBalance,
- account.supportsTransferringMoney, account.supportsInstantPaymentMoneyTransfer
- )
-
- mappedAccount.id = account.technicalId
- mappedAccount.userSetDisplayName = account.userSetDisplayName
-
- mappedAccount.bookedTransactions = mapTransactions(account.bookedTransactions, mappedAccount)
-
- return mappedAccount
- }
-
-
- open fun mapBankAccounts(transactions: List, customer: Customer): List {
- return transactions.map { mapBankAccount(it, customer) }
- }
-
- open fun mapBankAccount(account: BankAccountEntity, customer: Customer): BankAccount {
- val mappedAccount = BankAccount(
- customer, account.identifier, account.accountHolderName, account.iban, account.subAccountNumber,
- account.customerId, account.balance, account.currency, account.type, account.productName,
- account.accountLimit, account.lastRetrievedTransactionsTimestamp,
- account.supportsRetrievingAccountTransactions, account.supportsRetrievingBalance,
- account.supportsTransferringMoney, account.supportsInstantPaymentMoneyTransfer
- )
-
- mappedAccount.technicalId = account.id
- mappedAccount.userSetDisplayName = account.userSetDisplayName
-
- mappedAccount.bookedTransactions = mapTransactions(account.bookedTransactions, mappedAccount)
-
- return mappedAccount
- }
-
-
- open fun mapTransactions(transactions: List, account: BankAccountEntity): List {
- return transactions.map { mapTransaction(it, account) }
- }
-
- open fun mapTransaction(transaction: AccountTransaction, account: BankAccountEntity): AccountTransactionEntity {
- return AccountTransactionEntity(account, transaction.amount, transaction.currency, transaction.unparsedUsage, transaction.bookingDate,
- transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId, transaction.bookingText,
- transaction.valueDate, transaction.statementNumber, transaction.sequenceNumber, transaction.openingBalance, transaction.closingBalance,
- transaction.endToEndReference, transaction.customerReference, transaction.mandateReference, transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
- transaction.compensationAmount, transaction.originalAmount, transaction.sepaUsage, transaction.deviantOriginator, transaction.deviantRecipient,
- transaction.usageWithNoSpecialType, transaction.primaNotaNumber, transaction.textKeySupplement, transaction.currencyType, transaction.bookingKey,
- transaction.referenceForTheAccountOwner, transaction.referenceOfTheAccountServicingInstitution, transaction.supplementaryDetails,
- transaction.transactionReferenceNumber, transaction.relatedReferenceNumber, transaction.technicalId)
- }
-
-
- open fun mapTransactions(transactions: List, account: BankAccount): List {
- return transactions.map { mapTransaction(it, account) }
- }
-
- open fun mapTransaction(transaction: AccountTransactionEntity, account: BankAccount): AccountTransaction {
- val mappedTransaction = AccountTransaction(account, transaction.amount, transaction.currency, transaction.unparsedUsage, transaction.bookingDate,
- transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId, transaction.bookingText,
- transaction.valueDate, transaction.statementNumber, transaction.sequenceNumber, transaction.openingBalance, transaction.closingBalance,
- transaction.endToEndReference, transaction.customerReference, transaction.mandateReference, transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
- transaction.compensationAmount, transaction.originalAmount, transaction.sepaUsage, transaction.deviantOriginator, transaction.deviantRecipient,
- transaction.usageWithNoSpecialType, transaction.primaNotaNumber, transaction.textKeySupplement, transaction.currencyType, transaction.bookingKey,
- transaction.referenceForTheAccountOwner, transaction.referenceOfTheAccountServicingInstitution, transaction.supplementaryDetails,
- transaction.transactionReferenceNumber, transaction.relatedReferenceNumber)
-
- mappedTransaction.technicalId = transaction.id
-
- return mappedTransaction
- }
-
-}
\ No newline at end of file
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/EntitiesModelCreator.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/EntitiesModelCreator.kt
new file mode 100644
index 00000000..c63cbfdb
--- /dev/null
+++ b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/mapper/EntitiesModelCreator.kt
@@ -0,0 +1,72 @@
+package net.dankito.banking.persistence.mapper
+
+import net.dankito.banking.persistence.model.AccountTransactionEntity
+import net.dankito.banking.persistence.model.BankAccountEntity
+import net.dankito.banking.persistence.model.CustomerEntity
+import net.dankito.banking.ui.model.IAccountTransaction
+import net.dankito.banking.ui.model.TypedBankAccount
+import net.dankito.banking.ui.model.TypedCustomer
+import net.dankito.banking.ui.model.mapper.IModelCreator
+import net.dankito.utils.multiplatform.BigDecimal
+import net.dankito.utils.multiplatform.Date
+
+
+open class EntitiesModelCreator : IModelCreator {
+
+ override fun createCustomer(bankCode: String, customerId: String, password: String, finTsServerAddress: String, bankName: String, bic: String,
+ customerName: String, userId: String, iconUrl: String?): TypedCustomer {
+
+ return CustomerEntity(bankCode, customerId, password, finTsServerAddress, bankName, bic, customerName, userId, iconUrl) as TypedCustomer
+ }
+
+
+ override fun createBankAccount(customer: TypedCustomer, productName: String?, identifier: String): TypedBankAccount {
+ return BankAccountEntity(customer as CustomerEntity, identifier, "", null, null, "", productName = productName) as TypedBankAccount
+ }
+
+ override fun createTransaction(
+ bankAccount: TypedBankAccount,
+ amount: BigDecimal,
+ currency: String,
+ unparsedUsage: String,
+ bookingDate: Date,
+ otherPartyName: String?,
+ otherPartyBankCode: String?,
+ otherPartyAccountId: String?,
+ bookingText: String?,
+ valueDate: Date,
+ statementNumber: Int,
+ sequenceNumber: Int?,
+ openingBalance: BigDecimal?,
+ closingBalance: BigDecimal?,
+ endToEndReference: String?,
+ customerReference: String?,
+ mandateReference: String?,
+ creditorIdentifier: String?,
+ originatorsIdentificationCode: String?,
+ compensationAmount: String?,
+ originalAmount: String?,
+ sepaUsage: String?,
+ deviantOriginator: String?,
+ deviantRecipient: String?,
+ usageWithNoSpecialType: String?,
+ primaNotaNumber: String?,
+ textKeySupplement: String?,
+ currencyType: String?,
+ bookingKey: String,
+ referenceForTheAccountOwner: String,
+ referenceOfTheAccountServicingInstitution: String?,
+ supplementaryDetails: String?,
+ transactionReferenceNumber: String,
+ relatedReferenceNumber: String?
+ ) : IAccountTransaction {
+
+ return AccountTransactionEntity(bankAccount as BankAccountEntity, amount, currency, unparsedUsage, bookingDate,
+ otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, valueDate, statementNumber, sequenceNumber,
+ openingBalance, closingBalance, endToEndReference, customerReference, mandateReference, creditorIdentifier,
+ originatorsIdentificationCode, compensationAmount, originalAmount, sepaUsage, deviantOriginator, deviantRecipient,
+ usageWithNoSpecialType, primaNotaNumber, textKeySupplement, currencyType, bookingKey, referenceForTheAccountOwner,
+ referenceOfTheAccountServicingInstitution, supplementaryDetails, transactionReferenceNumber, relatedReferenceNumber)
+ }
+
+}
\ No newline at end of file
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/AccountTransactionEntity.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/AccountTransactionEntity.kt
index 2d0039d9..df72e5bb 100644
--- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/AccountTransactionEntity.kt
+++ b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/AccountTransactionEntity.kt
@@ -2,57 +2,63 @@ package net.dankito.banking.persistence.model
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
+import net.dankito.banking.ui.model.IAccountTransaction
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.utils.multiplatform.Date
import net.dankito.utils.multiplatform.UUID
-@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
+@JsonIdentityInfo(property = "technicalId", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
// had to define all properties as 'var' 'cause MapStruct cannot handle vals
open class AccountTransactionEntity(
- open var bankAccount: BankAccountEntity,
- open var amount: BigDecimal,
- open var currency: String,
- open var unparsedUsage: String,
- open var bookingDate: Date,
- open var otherPartyName: String?,
- open var otherPartyBankCode: String?,
- open var otherPartyAccountId: String?,
- open var bookingText: String?,
- open var valueDate: Date,
- open var statementNumber: Int,
- open var sequenceNumber: Int?,
- open var openingBalance: BigDecimal?,
- open var closingBalance: BigDecimal?,
+ override var bankAccount: BankAccountEntity,
+ override var amount: BigDecimal,
+ override var currency: String,
+ override var unparsedUsage: String,
+ override var bookingDate: Date,
+ override var otherPartyName: String?,
+ override var otherPartyBankCode: String?,
+ override var otherPartyAccountId: String?,
+ override var bookingText: String?,
+ override var valueDate: Date,
+ override var statementNumber: Int,
+ override var sequenceNumber: Int?,
+ override var openingBalance: BigDecimal?,
+ override var closingBalance: BigDecimal?,
- open var endToEndReference: String?,
- open var customerReference: String?,
- open var mandateReference: String?,
- open var creditorIdentifier: String?,
- open var originatorsIdentificationCode: String?,
- open var compensationAmount: String?,
- open var originalAmount: String?,
- open var sepaUsage: String?,
- open var deviantOriginator: String?,
- open var deviantRecipient: String?,
- open var usageWithNoSpecialType: String?,
- open var primaNotaNumber: String?,
- open var textKeySupplement: String?,
+ override var endToEndReference: String?,
+ override var customerReference: String?,
+ override var mandateReference: String?,
+ override var creditorIdentifier: String?,
+ override var originatorsIdentificationCode: String?,
+ override var compensationAmount: String?,
+ override var originalAmount: String?,
+ override var sepaUsage: String?,
+ override var deviantOriginator: String?,
+ override var deviantRecipient: String?,
+ override var usageWithNoSpecialType: String?,
+ override var primaNotaNumber: String?,
+ override var textKeySupplement: String?,
- open var currencyType: String?,
- open var bookingKey: String,
- open var referenceForTheAccountOwner: String,
- open var referenceOfTheAccountServicingInstitution: String?,
- open var supplementaryDetails: String?,
+ override var currencyType: String?,
+ override var bookingKey: String,
+ override var referenceForTheAccountOwner: String,
+ override var referenceOfTheAccountServicingInstitution: String?,
+ override var supplementaryDetails: String?,
- open var transactionReferenceNumber: String,
- open var relatedReferenceNumber: String?,
- var id: String = UUID.random().toString()
-) {
+ override var transactionReferenceNumber: String,
+ override var relatedReferenceNumber: String?,
+ override var technicalId: String = UUID.random()
+) : IAccountTransaction {
// for object deserializers
internal constructor() : this(BankAccountEntity(), BigDecimal.Zero, "", "", Date(), null, null, null, null, Date(),
-1, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "", "", null,
null, "", null)
+ constructor(bankAccount: BankAccountEntity, otherPartyName: String?, unparsedUsage: String, amount: BigDecimal, valueDate: Date, bookingText: String?)
+ : this(bankAccount, amount, "EUR", unparsedUsage, valueDate, otherPartyName, null, null, bookingText, valueDate, 0, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, "", "", null, null, "", null)
+
}
\ No newline at end of file
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankAccountEntity.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankAccountEntity.kt
index e03dc2b6..56d24334 100644
--- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankAccountEntity.kt
+++ b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankAccountEntity.kt
@@ -2,37 +2,39 @@ package net.dankito.banking.persistence.model
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
-import net.dankito.banking.ui.model.BankAccountType
+import net.dankito.banking.ui.model.*
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.utils.multiplatform.Date
import net.dankito.utils.multiplatform.UUID
-@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
+@JsonIdentityInfo(property = "technicalId", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
// had to define all properties as 'var' 'cause MapStruct cannot handle vals (and cannot use Pozo's mapstruct-kotlin as SerializableBankAccountBuilder would fail with @Context)
open class BankAccountEntity(
- open var customer: CustomerEntity,
- open var identifier: String,
- open var accountHolderName: String,
- open var iban: String?,
- open var subAccountNumber: String?,
- open var customerId: String,
- open var balance: BigDecimal = BigDecimal.Zero,
- open var currency: String = "EUR",
- open var type: BankAccountType = BankAccountType.Girokonto,
- open var productName: String? = null,
- open var accountLimit: String? = null,
- open var lastRetrievedTransactionsTimestamp: Date? = null,
- open var supportsRetrievingAccountTransactions: Boolean = false,
- open var supportsRetrievingBalance: Boolean = false,
- open var supportsTransferringMoney: Boolean = false,
- open var supportsInstantPaymentMoneyTransfer: Boolean = false,
- open var bookedTransactions: List = listOf(),
- open var unbookedTransactions: List = listOf(),
- open var id: String = UUID.random().toString(),
- open var userSetDisplayName: String? = null
+ override var customer: CustomerEntity,
+ override var identifier: String,
+ override var accountHolderName: String,
+ override var iban: String?,
+ override var subAccountNumber: String?,
+ override var customerId: String,
+ override var balance: BigDecimal = BigDecimal.Zero,
+ override var currency: String = "EUR",
+ override var type: BankAccountType = BankAccountType.Girokonto,
+ override var productName: String? = null,
+ override var accountLimit: String? = null,
+ override var lastRetrievedTransactionsTimestamp: Date? = null,
+ override var supportsRetrievingAccountTransactions: Boolean = false,
+ override var supportsRetrievingBalance: Boolean = false,
+ override var supportsTransferringMoney: Boolean = false,
+ override var supportsInstantPaymentMoneyTransfer: Boolean = false,
+ override var bookedTransactions: List = listOf(),
+ override var unbookedTransactions: List = listOf(),
+ override var technicalId: String = UUID.random(),
+ override var userSetDisplayName: String? = null,
+ override var haveAllTransactionsBeenFetched: Boolean = false,
+ override var displayIndex: Int = 0
-) {
+) : IBankAccount {
internal constructor() : this(CustomerEntity(), "", "", null, null, "") // for object deserializers
diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/CustomerEntity.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/CustomerEntity.kt
index 1af860a1..9aa46cc8 100644
--- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/CustomerEntity.kt
+++ b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/CustomerEntity.kt
@@ -1,30 +1,32 @@
package net.dankito.banking.persistence.model
import com.fasterxml.jackson.annotation.*
+import net.dankito.banking.ui.model.ICustomer
import net.dankito.banking.ui.model.tan.TanMedium
import net.dankito.banking.ui.model.tan.TanProcedure
import java.util.*
-@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
+@JsonIdentityInfo(property = "technicalId", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
// had to define all properties as 'var' 'cause MapStruct cannot handle vals (and cannot use Pozo's mapstruct-kotlin as SerializableCustomerBuilder would fail with @Context)
open class CustomerEntity(
- var bankCode: String,
- var customerId: String,
- var password: String,
- var finTsServerAddress: String,
- var bankName: String,
- var bic: String,
- var customerName: String,
- var userId: String = customerId,
- var iconUrl: String? = null,
- var accounts: List = listOf(),
- var supportedTanProcedures: List = listOf(),
- var selectedTanProcedure: TanProcedure? = null,
- var tanMedia: List = listOf(),
- var id: String = UUID.randomUUID().toString(),
- var userSetDisplayName: String? = null
-) {
+ override var bankCode: String,
+ override var customerId: String,
+ override var password: String,
+ override var finTsServerAddress: String,
+ override var bankName: String,
+ override var bic: String,
+ override var customerName: String,
+ override var userId: String = customerId,
+ override var iconUrl: String? = null,
+ override var accounts: List = listOf(),
+ override var supportedTanProcedures: List = listOf(),
+ override var selectedTanProcedure: TanProcedure? = null,
+ override var tanMedia: List = listOf(),
+ override var technicalId: String = UUID.randomUUID().toString(),
+ override var userSetDisplayName: String? = null,
+ override var displayIndex: Int = 0
+) : ICustomer {
internal constructor() : this("", "", "", "", "", "", "") // for object deserializers
diff --git a/persistence/json/BankingPersistenceJson/src/test/kotlin/net/dankito/banking/persistence/BankingPersistenceJsonTest.kt b/persistence/json/BankingPersistenceJson/src/test/kotlin/net/dankito/banking/persistence/BankingPersistenceJsonTest.kt
index 1eb72b0c..62732c25 100644
--- a/persistence/json/BankingPersistenceJson/src/test/kotlin/net/dankito/banking/persistence/BankingPersistenceJsonTest.kt
+++ b/persistence/json/BankingPersistenceJson/src/test/kotlin/net/dankito/banking/persistence/BankingPersistenceJsonTest.kt
@@ -1,13 +1,9 @@
package net.dankito.banking.persistence
-import net.dankito.banking.persistence.mapper.CustomerConverter
-import net.dankito.banking.persistence.mapper.CycleAvoidingMappingContext
import net.dankito.banking.persistence.model.AccountTransactionEntity
import net.dankito.banking.persistence.model.BankAccountEntity
import net.dankito.banking.persistence.model.CustomerEntity
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.*
import net.dankito.banking.util.JacksonJsonSerializer
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.utils.multiplatform.Date
@@ -15,7 +11,6 @@ import net.dankito.utils.multiplatform.File
import org.assertj.core.api.Assertions.assertThat
import org.junit.Assert
import org.junit.Test
-import org.mapstruct.factory.Mappers
import kotlin.random.Random
@@ -72,7 +67,7 @@ class BankingPersistenceJsonTest {
// when
- underTest.saveOrUpdateAccount(customers.first(), customers)
+ underTest.saveOrUpdateAccount(customers.first() as TypedCustomer, customers.map { it as TypedCustomer })
// then
@@ -89,13 +84,13 @@ class BankingPersistenceJsonTest {
// when
- underTest.saveOrUpdateAccount(customer, listOf(customer))
+ underTest.saveOrUpdateAccount(customer as TypedCustomer, listOf(customer).map { it as TypedCustomer })
// then
val result = serializer.deserializeListOr(file, CustomerEntity::class)
- assertCustomersEqual(result, listOf(customer))
+ assertCustomersEqual(result, listOf(customer) as List)
}
@@ -107,9 +102,8 @@ class BankingPersistenceJsonTest {
createCustomer(2),
createCustomer(3)
)
- val serializableCustomers = Mappers.getMapper(CustomerConverter::class.java).mapCustomers(customers, CycleAvoidingMappingContext())
- serializer.serializeObject(serializableCustomers, file)
+ serializer.serializeObject(customers, file)
// when
@@ -117,19 +111,19 @@ class BankingPersistenceJsonTest {
// then
- assertCustomersEqual(serializableCustomers, result)
+ assertCustomersEqual(customers, result as List)
}
- private fun createCustomer(countBankAccounts: Int = 0, customerId: String = CustomerId): Customer {
- val result = Customer(BankCode, customerId, Password, FinTsServerAddress, BankName, Bic, CustomerName, UserId, IconUrl)
+ private fun createCustomer(countBankAccounts: Int = 0, customerId: String = CustomerId): CustomerEntity {
+ val result = CustomerEntity(BankCode, customerId, Password, FinTsServerAddress, BankName, Bic, CustomerName, UserId, IconUrl)
result.accounts = createBankAccounts(countBankAccounts, result)
return result
}
- private fun createBankAccounts(count: Int, customer: Customer): List {
+ private fun createBankAccounts(count: Int, customer: CustomerEntity): List {
val random = Random(System.nanoTime())
return IntRange(1, count).map { accountIndex ->
@@ -137,8 +131,8 @@ class BankingPersistenceJsonTest {
}
}
- private fun createBankAccount(productName: String, customer: Customer, countTransactions: Int = 0): BankAccount {
- val result = BankAccount(customer, customer.customerId, "AccountHolder", "DE00" + customer.bankCode + customer.customerId, null,
+ private fun createBankAccount(productName: String, customer: CustomerEntity, countTransactions: Int = 0): BankAccountEntity {
+ val result = BankAccountEntity(customer, customer.customerId, "AccountHolder", "DE00" + customer.bankCode + customer.customerId, null,
customer.customerId, BigDecimal(84.25), productName = productName)
result.bookedTransactions = createAccountTransactions(countTransactions, result)
@@ -146,14 +140,14 @@ class BankingPersistenceJsonTest {
return result
}
- private fun createAccountTransactions(countTransactions: Int, account: BankAccount): List {
+ private fun createAccountTransactions(countTransactions: Int, account: BankAccountEntity): List {
return IntRange(1, countTransactions).map { transactionIndex ->
createAccountTransaction(transactionIndex, account)
}
}
- private fun createAccountTransaction(transactionIndex: Int, account: BankAccount): AccountTransaction {
- return AccountTransaction(account, "OtherParty_$transactionIndex", "Usage_$transactionIndex", BigDecimal(transactionIndex.toDouble()), createDate(), null)
+ private fun createAccountTransaction(transactionIndex: Int, account: BankAccountEntity): AccountTransactionEntity {
+ return AccountTransactionEntity(account, "OtherParty_$transactionIndex", "Usage_$transactionIndex", BigDecimal(transactionIndex.toDouble()), createDate(), null)
}
private fun createDate(): Date {
@@ -161,11 +155,11 @@ class BankingPersistenceJsonTest {
}
- private fun assertCustomersEqual(deserializedCustomers: List, customers: List) {
+ private fun assertCustomersEqual(deserializedCustomers: List, customers: List) {
assertThat(deserializedCustomers.size).isEqualTo(customers.size)
deserializedCustomers.forEach { deserializedCustomer ->
- val customer = customers.firstOrNull { it.technicalId == deserializedCustomer.id }
+ val customer = customers.firstOrNull { it.technicalId == deserializedCustomer.technicalId }
if (customer == null) {
Assert.fail("Could not find matching customer for deserialized customer $deserializedCustomer. customers = $customers")
@@ -176,7 +170,7 @@ class BankingPersistenceJsonTest {
}
}
- private fun assertCustomersEqual(deserializedCustomer: CustomerEntity, customer: Customer) {
+ private fun assertCustomersEqual(deserializedCustomer: CustomerEntity, customer: CustomerEntity) {
assertThat(deserializedCustomer.bankCode).isEqualTo(customer.bankCode)
assertThat(deserializedCustomer.customerId).isEqualTo(customer.customerId)
assertThat(deserializedCustomer.password).isEqualTo(customer.password)
@@ -191,11 +185,11 @@ class BankingPersistenceJsonTest {
assertBankAccountsEqual(deserializedCustomer.accounts, customer.accounts)
}
- private fun assertBankAccountsEqual(deserializedAccounts: List, accounts: List) {
+ private fun assertBankAccountsEqual(deserializedAccounts: List, accounts: List) {
assertThat(deserializedAccounts.size).isEqualTo(accounts.size)
deserializedAccounts.forEach { deserializedAccount ->
- val account = accounts.firstOrNull { it.technicalId == deserializedAccount.id }
+ val account = accounts.firstOrNull { it.technicalId == deserializedAccount.technicalId }
if (account == null) {
Assert.fail("Could not find matching account for deserialized account $deserializedAccount. accounts = $accounts")
@@ -206,9 +200,9 @@ class BankingPersistenceJsonTest {
}
}
- private fun assertBankAccountsEqual(deserializedAccount: BankAccountEntity, account: BankAccount) {
+ private fun assertBankAccountsEqual(deserializedAccount: BankAccountEntity, account: BankAccountEntity) {
// to check if MapStruct created reference correctly
- assertThat(deserializedAccount.customer.id).isEqualTo(account.customer.technicalId)
+ assertThat(deserializedAccount.customer.technicalId).isEqualTo(account.customer.technicalId)
assertThat(deserializedAccount.identifier).isEqualTo(account.identifier)
assertThat(deserializedAccount.iban).isEqualTo(account.iban)
@@ -219,11 +213,11 @@ class BankingPersistenceJsonTest {
assertAccountTransactionsEqual(deserializedAccount.bookedTransactions, account.bookedTransactions)
}
- private fun assertAccountTransactionsEqual(deserializedTransactions: List, transactions: List) {
+ private fun assertAccountTransactionsEqual(deserializedTransactions: List, transactions: List) {
assertThat(deserializedTransactions.size).isEqualTo(transactions.size)
deserializedTransactions.forEach { deserializedTransaction ->
- val transaction = transactions.firstOrNull { it.technicalId == deserializedTransaction.id }
+ val transaction = transactions.firstOrNull { it.technicalId == deserializedTransaction.technicalId }
if (transaction == null) {
Assert.fail("Could not find matching transaction for deserialized transaction $deserializedTransaction. transactions = $transactions")
@@ -234,9 +228,9 @@ class BankingPersistenceJsonTest {
}
}
- private fun assertAccountTransactionsEqual(deserializedTransaction: AccountTransactionEntity, transaction: AccountTransaction) {
+ private fun assertAccountTransactionsEqual(deserializedTransaction: AccountTransactionEntity, transaction: AccountTransactionEntity) {
// to check if MapStruct created reference correctly
- assertThat(deserializedTransaction.bankAccount.id).isEqualTo(transaction.bankAccount.technicalId)
+ assertThat(deserializedTransaction.bankAccount.technicalId).isEqualTo(transaction.bankAccount.technicalId)
assertThat(deserializedTransaction.otherPartyName).isEqualTo(transaction.otherPartyName)
assertThat(deserializedTransaction.unparsedUsage).isEqualTo(transaction.unparsedUsage)
diff --git a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/RouterAndroid.kt b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/RouterAndroid.kt
index 61dc1953..196e5178 100644
--- a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/RouterAndroid.kt
+++ b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/RouterAndroid.kt
@@ -3,7 +3,7 @@ package net.dankito.banking.ui.android
import net.dankito.banking.ui.android.util.CurrentActivityTracker
import net.dankito.banking.ui.IRouter
import net.dankito.banking.ui.android.dialogs.*
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
import net.dankito.banking.ui.model.tan.EnterTanResult
@@ -20,7 +20,7 @@ open class RouterAndroid(protected val activityTracker: CurrentActivityTracker)
}
}
- override fun getTanFromUserFromNonUiThread(customer: Customer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: (EnterTanResult) -> Unit) {
+ override fun getTanFromUserFromNonUiThread(customer: TypedCustomer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: (EnterTanResult) -> Unit) {
activityTracker.currentOrNextActivity { activity ->
activity.runOnUiThread {
EnterTanDialog().show(customer, tanChallenge, activity, false) { result ->
diff --git a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/AccountTransactionAdapter.kt b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/AccountTransactionAdapter.kt
index e1abcc77..7eaa22a8 100644
--- a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/AccountTransactionAdapter.kt
+++ b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/AccountTransactionAdapter.kt
@@ -6,7 +6,7 @@ import android.view.View
import net.dankito.banking.ui.android.R
import net.dankito.banking.ui.android.adapter.viewholder.AccountTransactionViewHolder
import net.dankito.banking.ui.android.extensions.showAmount
-import net.dankito.banking.ui.model.AccountTransaction
+import net.dankito.banking.ui.model.IAccountTransaction
import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.utils.android.extensions.asActivity
import net.dankito.utils.android.ui.adapter.ListRecyclerAdapter
@@ -14,14 +14,14 @@ import java.text.DateFormat
open class AccountTransactionAdapter(protected val presenter: BankingPresenter)
- : ListRecyclerAdapter() {
+ : ListRecyclerAdapter() {
companion object {
val ValueDateFormat = DateFormat.getDateInstance(DateFormat.SHORT)
}
- var selectedTransaction: AccountTransaction? = null
+ var selectedTransaction: IAccountTransaction? = null
override fun getListItemLayoutId() = R.layout.list_item_account_transaction
@@ -34,7 +34,7 @@ open class AccountTransactionAdapter(protected val presenter: BankingPresenter)
return viewHolder
}
- override fun bindItemToView(viewHolder: AccountTransactionViewHolder, item: AccountTransaction) {
+ override fun bindItemToView(viewHolder: AccountTransactionViewHolder, item: IAccountTransaction) {
viewHolder.txtvwDate.text = ValueDateFormat.format(item.valueDate)
val label = if (item.showOtherPartyName) item.otherPartyName else item.bookingText
diff --git a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/BankAccountsAdapter.kt b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/BankAccountsAdapter.kt
index 46483671..0cc617b4 100644
--- a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/BankAccountsAdapter.kt
+++ b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/adapter/BankAccountsAdapter.kt
@@ -8,11 +8,11 @@ import android.view.ViewGroup
import android.widget.ImageView
import kotlinx.android.synthetic.main.list_item_bank_account.view.*
import net.dankito.banking.ui.android.R
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.TypedBankAccount
import net.dankito.utils.android.ui.adapter.ListAdapter
-open class BankAccountsAdapter(bankAccounts: List) : ListAdapter(bankAccounts) {
+open class BankAccountsAdapter(bankAccounts: List) : ListAdapter(bankAccounts) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
@@ -30,7 +30,7 @@ open class BankAccountsAdapter(bankAccounts: List) : ListAdapter Unit) {
this.customer = customer
diff --git a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/dialogs/TransferMoneyDialog.kt b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/dialogs/TransferMoneyDialog.kt
index bc99e0ce..b9d09435 100644
--- a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/dialogs/TransferMoneyDialog.kt
+++ b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/dialogs/TransferMoneyDialog.kt
@@ -27,7 +27,7 @@ import net.dankito.banking.ui.android.listener.ListItemSelectedListener
import net.dankito.banking.ui.android.util.StandardAutocompleteCallback
import net.dankito.banking.ui.android.util.StandardTextWatcher
import net.dankito.banking.search.Remittee
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.TypedBankAccount
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.responses.BankingClientResponse
import net.dankito.banking.ui.presenter.BankingPresenter
@@ -52,7 +52,7 @@ open class TransferMoneyDialog : DialogFragment() {
}
- protected lateinit var bankAccount: BankAccount
+ protected lateinit var bankAccount: TypedBankAccount
protected var preselectedValues: TransferMoneyData? = null
diff --git a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/views/DrawerView.kt b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/views/DrawerView.kt
index 38b14ae0..988ed5c6 100644
--- a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/views/DrawerView.kt
+++ b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/views/DrawerView.kt
@@ -20,7 +20,7 @@ import com.mikepenz.materialdrawer.util.removeItemByPosition
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
import net.dankito.banking.ui.android.R
import net.dankito.banking.ui.android.extensions.withIcon
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.ui.presenter.BankingPresenter
import org.slf4j.LoggerFactory
@@ -139,7 +139,7 @@ open class DrawerView(
}.flatten()
}
- private fun createAccountDrawerItem(customer: Customer): IDrawerItem<*> {
+ private fun createAccountDrawerItem(customer: TypedCustomer): IDrawerItem<*> {
val accountItem = AccountDrawerItem()
.withName(customer.displayName)
@@ -160,7 +160,7 @@ open class DrawerView(
return accountItem
}
- private fun createBankAccountsDrawerItems(customer: Customer): List> {
+ private fun createBankAccountsDrawerItems(customer: TypedCustomer): List> {
return customer.accounts.map { bankAccount ->
SecondaryDrawerItem()
.withName(bankAccount.displayName)
@@ -176,13 +176,13 @@ open class DrawerView(
return false
}
- private fun closeDrawerAndEditAccount(customer: Customer) {
+ private fun closeDrawerAndEditAccount(customer: TypedCustomer) {
closeDrawer()
editAccount(customer)
}
- private fun editAccount(customer: Customer) {
+ private fun editAccount(customer: TypedCustomer) {
// TODO: implement editing account (e.g. displayed name etc.)
AlertDialog.Builder(activity)
diff --git a/ui/BankingJavaFxApp/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/mainwindow/MainWindow.kt b/ui/BankingJavaFxApp/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/mainwindow/MainWindow.kt
index 60066a33..e7a96376 100755
--- a/ui/BankingJavaFxApp/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/mainwindow/MainWindow.kt
+++ b/ui/BankingJavaFxApp/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/mainwindow/MainWindow.kt
@@ -11,6 +11,7 @@ import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.util.BankIconFinder
import net.dankito.banking.bankfinder.LuceneBankFinder
import net.dankito.banking.persistence.LuceneBankingPersistence
+import net.dankito.banking.persistence.mapper.EntitiesModelCreator
import net.dankito.banking.search.LuceneRemitteeSearcher
import net.dankito.banking.util.JacksonJsonSerializer
import net.dankito.banking.util.extraction.JavaTextExtractorRegistry
@@ -32,6 +33,8 @@ class MainWindow : View(messages["application.title"]) {
private val indexFolder = ensureFolderExists(dataFolder, "index")
+ private val modelCreator = EntitiesModelCreator()
+
private val serializer = JacksonJsonSerializer()
private val tesseractTextExtractor = Tesseract4CommandlineImageTextExtractor(TesseractConfig(listOf(OcrLanguage.English, OcrLanguage.German)))
@@ -42,11 +45,11 @@ class MainWindow : View(messages["application.title"]) {
tesseractTextExtractor, TikaTextExtractor()
)))
- private val presenter = BankingPresenter(fints4kBankingClientCreator(serializer),
+ private val presenter = BankingPresenter(fints4kBankingClientCreator(modelCreator, serializer),
LuceneBankFinder(indexFolder), dataFolder, LuceneBankingPersistence(indexFolder, databaseFolder),
- RouterJavaFx(), LuceneRemitteeSearcher(indexFolder), BankIconFinder(), textExtractorRegistry)
+ RouterJavaFx(), modelCreator, LuceneRemitteeSearcher(indexFolder), BankIconFinder(), textExtractorRegistry)
// private val presenter = BankingPresenter(hbci4jBankingClientCreator(), LuceneBankFinder(indexFolder),
-// dataFolder, LuceneBankingPersistence(indexFolder, databaseFolder), RouterJavaFx(), LuceneRemitteeSearcher(indexFolder),
+// dataFolder, LuceneBankingPersistence(indexFolder, databaseFolder), RouterJavaFx(), modelCreator, LuceneRemitteeSearcher(indexFolder),
// BankIconFinder(), textExtractorRegistry)
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/RouterJavaFx.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/RouterJavaFx.kt
index e29d5ef6..b6dcb06c 100644
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/RouterJavaFx.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/RouterJavaFx.kt
@@ -4,7 +4,7 @@ import net.dankito.banking.ui.IRouter
import net.dankito.banking.ui.javafx.dialogs.AddAccountDialog
import net.dankito.banking.ui.javafx.dialogs.cashtransfer.TransferMoneyDialog
import net.dankito.banking.ui.javafx.dialogs.tan.EnterTanDialog
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
import net.dankito.banking.ui.model.tan.EnterTanResult
@@ -22,7 +22,7 @@ open class RouterJavaFx : IRouter {
AddAccountDialog(presenter).show(messages["add.account.dialog.title"])
}
- override fun getTanFromUserFromNonUiThread(customer: Customer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: (EnterTanResult) -> Unit) {
+ override fun getTanFromUserFromNonUiThread(customer: TypedCustomer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: (EnterTanResult) -> Unit) {
FX.runAndWait {
EnterTanDialog(customer, tanChallenge, presenter) { result ->
callback(result)
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsControlView.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsControlView.kt
index 019a1afe..d920b866 100644
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsControlView.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsControlView.kt
@@ -141,7 +141,7 @@ open class AccountTransactionsControlView(
protected open fun updateAccountTransactions(processingIndicatorButton: ProcessingIndicatorButton) {
// TODO: or only update transactions of selected accounts?
- presenter.updateAccountsTransactionsAsync { transactions ->
+ presenter.updateAccountsTransactionsAsync {
runLater {
processingIndicatorButton.resetIsProcessing()
}
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt
index 8372e8b0..9b79bfac 100644
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt
@@ -11,7 +11,7 @@ import javafx.scene.control.TableView
import javafx.scene.layout.Priority
import javafx.scene.paint.Color
import javafx.util.Callback
-import net.dankito.banking.ui.model.AccountTransaction
+import net.dankito.banking.ui.model.IAccountTransaction
import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.utils.javafx.ui.extensions.ensureOnlyUsesSpaceIfVisible
import tornadofx.*
@@ -21,8 +21,8 @@ import java.text.DateFormat
open class AccountTransactionsTable @JvmOverloads constructor(
protected val presenter: BankingPresenter,
- transactions: ObservableList = FXCollections.emptyObservableList()
-) : TableView(transactions) {
+ transactions: ObservableList = FXCollections.emptyObservableList()
+) : TableView(transactions) {
companion object {
@@ -38,7 +38,7 @@ open class AccountTransactionsTable @JvmOverloads constructor(
protected open fun initUi() {
- column(messages["account.transactions.table.column.header.value.date"], AccountTransaction::valueDate) {
+ column(messages["account.transactions.table.column.header.value.date"], IAccountTransaction::valueDate) {
prefWidth = 115.0
cellFormat {
@@ -48,7 +48,7 @@ open class AccountTransactionsTable @JvmOverloads constructor(
}
}
- columns.add(TableColumn(messages["account.transactions.table.column.header.usage"]).apply {
+ columns.add(TableColumn(messages["account.transactions.table.column.header.usage"]).apply {
this.cellFormat {
contentDisplay = ContentDisplay.GRAPHIC_ONLY
@@ -80,8 +80,8 @@ open class AccountTransactionsTable @JvmOverloads constructor(
}
}
- cellValueFactory = Callback { object : ObjectBinding() {
- override fun computeValue(): AccountTransaction {
+ cellValueFactory = Callback { object : ObjectBinding() {
+ override fun computeValue(): IAccountTransaction {
return it.value
}
@@ -90,7 +90,7 @@ open class AccountTransactionsTable @JvmOverloads constructor(
weightedWidth(4.0)
})
- columns.add(TableColumn(messages["account.transactions.table.column.header.amount"]).apply {
+ columns.add(TableColumn(messages["account.transactions.table.column.header.amount"]).apply {
prefWidth = 85.0
this.cellFormat {
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt
index 7a906bb3..b80ec828 100644
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt
@@ -8,8 +8,8 @@ import javafx.scene.input.ContextMenuEvent
import javafx.scene.input.MouseButton
import javafx.scene.input.MouseEvent
import net.dankito.banking.ui.javafx.dialogs.JavaFxDialogService
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.IAccountTransaction
+import net.dankito.banking.ui.model.TypedBankAccount
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.responses.GetTransactionsResponse
import net.dankito.banking.ui.presenter.BankingPresenter
@@ -24,7 +24,7 @@ open class AccountTransactionsView(private val presenter: BankingPresenter) : Vi
protected val balance = SimpleStringProperty("")
- protected val transactionsToDisplay = FXCollections.observableArrayList(listOf())
+ protected val transactionsToDisplay = FXCollections.observableArrayList(listOf())
protected var currentMenu: ContextMenu? = null
@@ -56,7 +56,7 @@ open class AccountTransactionsView(private val presenter: BankingPresenter) : Vi
}
- protected open fun tableClicked(event: MouseEvent, selectedItem: AccountTransaction?) {
+ protected open fun tableClicked(event: MouseEvent, selectedItem: IAccountTransaction?) {
if (event.button == MouseButton.PRIMARY || event.button == MouseButton.MIDDLE) {
currentMenu?.hide()
}
@@ -79,7 +79,7 @@ open class AccountTransactionsView(private val presenter: BankingPresenter) : Vi
}
}
- protected open fun createContextMenuForItems(selectedItem: AccountTransaction): ContextMenu {
+ protected open fun createContextMenuForItems(selectedItem: IAccountTransaction): ContextMenu {
val contextMenu = ContextMenu()
contextMenu.apply {
@@ -105,21 +105,21 @@ open class AccountTransactionsView(private val presenter: BankingPresenter) : Vi
return contextMenu
}
- protected open fun showTransactionDetailsDialog(transaction: AccountTransaction) {
+ protected open fun showTransactionDetailsDialog(transaction: IAccountTransaction) {
// TODO:
// presenter.showTransactionDetailsWindow(transaction.item)
}
- protected open fun newTransferToSameRemittee(transaction: AccountTransaction) {
+ protected open fun newTransferToSameRemittee(transaction: IAccountTransaction) {
presenter.showTransferMoneyDialog(TransferMoneyData.fromAccountTransactionWithoutAmountAndUsage(transaction))
}
- protected open fun newTransferWithSameData(transaction: AccountTransaction) {
+ protected open fun newTransferWithSameData(transaction: IAccountTransaction) {
presenter.showTransferMoneyDialog(TransferMoneyData.fromAccountTransaction(transaction))
}
- protected open fun handleSelectedBankAccountsChanged(selectedBankAccounts: List) {
+ protected open fun handleSelectedBankAccountsChanged(selectedBankAccounts: List) {
runLater {
isAccountSelected.value = selectedBankAccounts.isNotEmpty()
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsTreeView.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsTreeView.kt
index fbaa34a2..b939dcf6 100644
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsTreeView.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsTreeView.kt
@@ -10,13 +10,13 @@ import javafx.scene.input.KeyCode
import net.dankito.banking.ui.javafx.dialogs.JavaFxDialogService
import net.dankito.banking.ui.javafx.model.AccountsAccountTreeItem
import net.dankito.banking.ui.javafx.model.AccountsRootTreeItem
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.ui.presenter.BankingPresenter
import tornadofx.*
import tornadofx.FX.Companion.messages
-open class AccountsTreeView(customers: ObservableList, protected val presenter: BankingPresenter)
+open class AccountsTreeView(customers: ObservableList, protected val presenter: BankingPresenter)
: TreeView(AccountsRootTreeItem(customers)) {
protected var currentMenu: ContextMenu? = null
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/cashtransfer/TransferMoneyDialog.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/cashtransfer/TransferMoneyDialog.kt
index 906d81c7..6bcf6431 100644
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/cashtransfer/TransferMoneyDialog.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/cashtransfer/TransferMoneyDialog.kt
@@ -12,7 +12,7 @@ import javafx.scene.image.ImageView
import javafx.scene.layout.Priority
import kotlinx.coroutines.*
import net.dankito.banking.ui.javafx.dialogs.JavaFxDialogService
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.TypedBankAccount
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.responses.BankingClientResponse
import net.dankito.banking.ui.presenter.BankingPresenter
@@ -49,7 +49,7 @@ open class TransferMoneyDialog @JvmOverloads constructor(
protected val bankAccountsSupportingTransferringMoney = FXCollections.observableArrayList(presenter.bankAccounts.filter { it.supportsTransferringMoney })
- protected val selectedBankAccount = SimpleObjectProperty(preselectedValues?.account ?: bankAccountsSupportingTransferringMoney.firstOrNull())
+ protected val selectedBankAccount = SimpleObjectProperty(preselectedValues?.account ?: bankAccountsSupportingTransferringMoney.firstOrNull())
protected val showBankAccounts = SimpleBooleanProperty(bankAccountsSupportingTransferringMoney.size > 1)
@@ -268,7 +268,7 @@ open class TransferMoneyDialog @JvmOverloads constructor(
}
- private fun selectedBankAccountChanged(newValue: BankAccount?) {
+ private fun selectedBankAccountChanged(newValue: TypedBankAccount?) {
supportsInstantPayment.value = newValue?.supportsInstantPaymentMoneyTransfer ?: false
if (supportsInstantPayment.value == false) {
@@ -345,7 +345,7 @@ open class TransferMoneyDialog @JvmOverloads constructor(
}
protected open fun transferMoney() {
- remitteeBank.value?.let { remitteeBank ->
+ remitteeBank.value?.let {
val bankAccount = selectedBankAccount.value
val data = TransferMoneyData(
@@ -366,7 +366,7 @@ open class TransferMoneyDialog @JvmOverloads constructor(
}
}
- protected open fun handleTransferMoneyResultOnUiThread(bankAccount: BankAccount, transferData: TransferMoneyData, response: BankingClientResponse) {
+ protected open fun handleTransferMoneyResultOnUiThread(bankAccount: TypedBankAccount, transferData: TransferMoneyData, response: BankingClientResponse) {
val currency = bankAccount.currency
if (response.isSuccessful) {
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/tan/EnterTanDialog.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/tan/EnterTanDialog.kt
index 99bd53d1..806198f4 100644
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/tan/EnterTanDialog.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/dialogs/tan/EnterTanDialog.kt
@@ -10,7 +10,7 @@ import javafx.scene.text.FontWeight
import net.dankito.banking.ui.javafx.dialogs.tan.controls.ChipTanFlickerCodeView
import net.dankito.banking.ui.javafx.dialogs.JavaFxDialogService
import net.dankito.banking.ui.javafx.dialogs.tan.controls.TanImageView
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.ui.model.responses.BankingClientResponse
import net.dankito.banking.ui.model.tan.*
import net.dankito.banking.ui.presenter.BankingPresenter
@@ -20,7 +20,7 @@ import tornadofx.*
open class EnterTanDialog(
- protected val customer: Customer,
+ protected val customer: TypedCustomer,
protected val challenge: TanChallenge,
protected val presenter: BankingPresenter,
protected val tanEnteredCallback: (EnterTanResult) -> Unit
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt
index d60246e2..a7e19a67 100755
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt
@@ -2,10 +2,10 @@ package net.dankito.banking.ui.javafx.model
import javafx.scene.Node
import javafx.scene.image.ImageView
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
-open class AccountsAccountTreeItem(val customer: Customer) : AccountsTreeItemBase(customer.displayName) {
+open class AccountsAccountTreeItem(val customer: TypedCustomer) : AccountsTreeItemBase(customer.displayName) {
companion object {
private const val IconSize = 16.0
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt
index 02c8ed54..1ca6fced 100755
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt
@@ -1,6 +1,6 @@
package net.dankito.banking.ui.javafx.model
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.TypedBankAccount
-open class AccountsBankAccountTreeItem(val bankAccount: BankAccount) : AccountsTreeItemBase(bankAccount.displayName)
\ No newline at end of file
+open class AccountsBankAccountTreeItem(val bankAccount: TypedBankAccount) : AccountsTreeItemBase(bankAccount.displayName)
\ No newline at end of file
diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsRootTreeItem.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsRootTreeItem.kt
index afe36f63..215cae6f 100755
--- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsRootTreeItem.kt
+++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsRootTreeItem.kt
@@ -2,13 +2,13 @@ package net.dankito.banking.ui.javafx.model
import javafx.collections.ListChangeListener
import javafx.collections.ObservableList
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import tornadofx.FX.Companion.messages
import tornadofx.get
import tornadofx.runLater
-open class AccountsRootTreeItem(customers: ObservableList) : AccountsTreeItemBase(messages["accounts.view.all.accounts"]) {
+open class AccountsRootTreeItem(customers: ObservableList) : AccountsTreeItemBase(messages["accounts.view.all.accounts"]) {
init {
setAccounts(customers)
@@ -18,7 +18,7 @@ open class AccountsRootTreeItem(customers: ObservableList) : AccountsT
})
}
- protected open fun setAccounts(customers: List) {
+ protected open fun setAccounts(customers: List) {
isExpanded = customers.isNotEmpty()
children.setAll(customers.map { AccountsAccountTreeItem(it) })
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/IBankingPersistence.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/IBankingPersistence.kt
index b51b2e33..350ee25d 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/IBankingPersistence.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/IBankingPersistence.kt
@@ -1,21 +1,19 @@
package net.dankito.banking.persistence
+import net.dankito.banking.ui.model.*
import net.dankito.utils.multiplatform.File
-import net.dankito.banking.ui.model.Customer
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
interface IBankingPersistence {
- fun saveOrUpdateAccount(customer: Customer, allCustomers: List)
+ fun saveOrUpdateAccount(customer: TypedCustomer, allCustomers: List)
- fun deleteAccount(customer: Customer, allCustomers: List)
+ fun deleteAccount(customer: TypedCustomer, allCustomers: List)
- fun readPersistedAccounts(): List
+ fun readPersistedAccounts(): List
- fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List)
+ fun saveOrUpdateAccountTransactions(bankAccount: TypedBankAccount, transactions: List)
fun saveUrlToFile(url: String, file: File)
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/NoOpBankingPersistence.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/NoOpBankingPersistence.kt
index c607a575..939c2221 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/NoOpBankingPersistence.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/persistence/NoOpBankingPersistence.kt
@@ -1,27 +1,25 @@
package net.dankito.banking.persistence
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.*
import net.dankito.utils.multiplatform.File
open class NoOpBankingPersistence : IBankingPersistence {
- override fun saveOrUpdateAccount(customer: Customer, allCustomers: List) {
+ override fun saveOrUpdateAccount(customer: TypedCustomer, allCustomers: List) {
}
- override fun deleteAccount(customer: Customer, allCustomers: List) {
+ override fun deleteAccount(customer: TypedCustomer, allCustomers: List) {
}
- override fun readPersistedAccounts(): List {
+ override fun readPersistedAccounts(): List {
return listOf()
}
- override fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List) {
+ override fun saveOrUpdateAccountTransactions(bankAccount: TypedBankAccount, transactions: List) {
}
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/BankingClientCallback.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/BankingClientCallback.kt
index f7e85ccc..614103d3 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/BankingClientCallback.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/BankingClientCallback.kt
@@ -1,6 +1,6 @@
package net.dankito.banking.ui
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
import net.dankito.banking.ui.model.tan.EnterTanResult
import net.dankito.banking.ui.model.tan.TanChallenge
@@ -9,7 +9,7 @@ import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium
interface BankingClientCallback {
- fun enterTan(customer: Customer, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit)
+ fun enterTan(customer: TypedCustomer, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit)
/**
* This method gets called for chipTan TAN generators when the bank asks the customer to synchronize her/his TAN generator.
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClient.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClient.kt
index 1a122888..8dab3924 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClient.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClient.kt
@@ -1,8 +1,6 @@
package net.dankito.banking.ui
-import net.dankito.banking.ui.model.BankAccount
-import net.dankito.banking.ui.model.Customer
-import net.dankito.banking.ui.model.MessageLogEntry
+import net.dankito.banking.ui.model.*
import net.dankito.banking.ui.model.parameters.GetTransactionsParameter
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.responses.AddAccountResponse
@@ -18,7 +16,7 @@ interface IBankingClient {
fun addAccountAsync(callback: (AddAccountResponse) -> Unit)
fun getTransactionsAsync(
- bankAccount: BankAccount,
+ bankAccount: TypedBankAccount,
parameter: GetTransactionsParameter,
callback: (GetTransactionsResponse) -> Unit
)
@@ -26,6 +24,6 @@ interface IBankingClient {
fun transferMoneyAsync(data: TransferMoneyData, callback: (BankingClientResponse) -> Unit)
- fun dataChanged(customer: Customer)
+ fun dataChanged(customer: TypedCustomer)
}
\ No newline at end of file
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClientCreator.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClientCreator.kt
index bab34274..381bf098 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClientCreator.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IBankingClientCreator.kt
@@ -1,14 +1,14 @@
package net.dankito.banking.ui
import net.dankito.utils.multiplatform.File
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.util.IAsyncRunner
interface IBankingClientCreator {
fun createClient(
- customer: Customer,
+ customer: TypedCustomer,
dataFolder: File,
asyncRunner: IAsyncRunner,
callback: BankingClientCallback
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IRouter.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IRouter.kt
index 202b6d19..ebc99d00 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IRouter.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/IRouter.kt
@@ -1,7 +1,6 @@
package net.dankito.banking.ui
-import net.dankito.banking.ui.model.Customer
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.TypedCustomer
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
import net.dankito.banking.ui.model.tan.EnterTanResult
@@ -14,7 +13,7 @@ interface IRouter {
fun showAddAccountDialog(presenter: BankingPresenter)
- fun getTanFromUserFromNonUiThread(customer: Customer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: (EnterTanResult) -> Unit)
+ fun getTanFromUserFromNonUiThread(customer: TypedCustomer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: (EnterTanResult) -> Unit)
fun getAtcFromUserFromNonUiThread(tanMedium: TanGeneratorTanMedium, callback: (EnterTanGeneratorAtcResult) -> Unit)
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/AccountTransaction.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/AccountTransaction.kt
index 95fae62b..0e69c2fd 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/AccountTransaction.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/AccountTransaction.kt
@@ -7,49 +7,44 @@ import net.dankito.utils.multiplatform.DateFormatter
open class AccountTransaction(
- open val bankAccount: BankAccount,
- open val amount: BigDecimal,
- open val currency: String,
- open val unparsedUsage: String,
- open val bookingDate: Date,
- open val otherPartyName: String?,
- open val otherPartyBankCode: String?,
- open val otherPartyAccountId: String?,
- open val bookingText: String?,
- open val valueDate: Date,
- open val statementNumber: Int,
- open val sequenceNumber: Int?,
- open val openingBalance: BigDecimal?,
- open val closingBalance: BigDecimal?,
+ override val bankAccount: TypedBankAccount,
+ override val amount: BigDecimal,
+ override val currency: String,
+ override val unparsedUsage: String,
+ override val bookingDate: Date,
+ override val otherPartyName: String?,
+ override val otherPartyBankCode: String?,
+ override val otherPartyAccountId: String?,
+ override val bookingText: String?,
+ override val valueDate: Date,
+ override val statementNumber: Int,
+ override val sequenceNumber: Int?,
+ override val openingBalance: BigDecimal?,
+ override val closingBalance: BigDecimal?,
- open val endToEndReference: String?,
- open val customerReference: String?,
- open val mandateReference: String?,
- open val creditorIdentifier: String?,
- open val originatorsIdentificationCode: String?,
- open val compensationAmount: String?,
- open val originalAmount: String?,
- open val sepaUsage: String?,
- open val deviantOriginator: String?,
- open val deviantRecipient: String?,
- open val usageWithNoSpecialType: String?,
- open val primaNotaNumber: String?,
- open val textKeySupplement: String?,
+ override val endToEndReference: String?,
+ override val customerReference: String?,
+ override val mandateReference: String?,
+ override val creditorIdentifier: String?,
+ override val originatorsIdentificationCode: String?,
+ override val compensationAmount: String?,
+ override val originalAmount: String?,
+ override val sepaUsage: String?,
+ override val deviantOriginator: String?,
+ override val deviantRecipient: String?,
+ override val usageWithNoSpecialType: String?,
+ override val primaNotaNumber: String?,
+ override val textKeySupplement: String?,
- open val currencyType: String?,
- open val bookingKey: String,
- open val referenceForTheAccountOwner: String,
- open val referenceOfTheAccountServicingInstitution: String?,
- open val supplementaryDetails: String?,
-
- open val transactionReferenceNumber: String,
- open val relatedReferenceNumber: String?
-) {
-
- companion object {
- val IdDateFormat = DateFormatter("yyyy.MM.dd")
- }
+ override val currencyType: String?,
+ override val bookingKey: String,
+ override val referenceForTheAccountOwner: String,
+ override val referenceOfTheAccountServicingInstitution: String?,
+ override val supplementaryDetails: String?,
+ override val transactionReferenceNumber: String,
+ override val relatedReferenceNumber: String?
+) : IAccountTransaction {
// for object deserializers
internal constructor() : this(BankAccount(), null, "", BigDecimal.Zero, Date(), null)
@@ -69,29 +64,7 @@ open class AccountTransaction(
0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "", "", null, null, "", null)
- open var technicalId: String = buildTransactionIdentifier()
-
- open val transactionIdentifier: String
- get() = buildTransactionIdentifier()
-
- protected fun buildTransactionIdentifier() : String {
- if (bankAccount != null) {
- return "${bankAccount.technicalId} ${IdDateFormat.format(bookingDate)} ${IdDateFormat.format(valueDate)} $amount $currency $unparsedUsage $otherPartyName $otherPartyBankCode $otherPartyAccountId"
- }
- else { // happens for derived classes during initialization. These have to set technicalId after initialization by themselves
- return " ${IdDateFormat.format(bookingDate)} ${IdDateFormat.format(valueDate)} $amount $currency $unparsedUsage $otherPartyName $otherPartyBankCode $otherPartyAccountId"
- }
- }
-
-
- open val showOtherPartyName: Boolean
- get() = otherPartyName.isNullOrBlank() == false /* && type != "ENTGELTABSCHLUSS" && type != "AUSZAHLUNG" */ // TODO
-
- open val canCreateMoneyTransferFrom: Boolean
- get() = otherPartyAccountId != null && bankAccount.supportsTransferringMoney
-
- open val usage: String
- get() = sepaUsage ?: unparsedUsage
+ override var technicalId: String = buildTransactionIdentifier()
override fun equals(other: Any?): Boolean {
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt
index 1a263eac..3b3df0a0 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt
@@ -7,69 +7,47 @@ import kotlin.jvm.JvmOverloads
open class BankAccount @JvmOverloads constructor(
- open val customer: Customer,
- open var identifier: String,
- open var accountHolderName: String,
- open var iban: String?,
- open var subAccountNumber: String?,
- open var customerId: String,
- open var balance: BigDecimal = BigDecimal.Zero,
- open var currency: String = "EUR",
- open var type: BankAccountType = BankAccountType.Girokonto,
- open var productName: String? = null,
- open var accountLimit: String? = null,
- open var lastRetrievedTransactionsTimestamp: Date? = null,
- open var supportsRetrievingAccountTransactions: Boolean = false,
- open var supportsRetrievingBalance: Boolean = false,
- open var supportsTransferringMoney: Boolean = false,
- open var supportsInstantPaymentMoneyTransfer: Boolean = false,
- open var bookedTransactions: List = listOf(),
- open var unbookedTransactions: List = listOf()
-) : OrderedDisplayable {
+ override val customer: TypedCustomer,
+ override var identifier: String,
+ override var accountHolderName: String,
+ override var iban: String?,
+ override var subAccountNumber: String?,
+ override var customerId: String,
+ override var balance: BigDecimal = BigDecimal.Zero,
+ override var currency: String = "EUR",
+ override var type: BankAccountType = BankAccountType.Girokonto,
+ override var productName: String? = null,
+ override var accountLimit: String? = null,
+ override var lastRetrievedTransactionsTimestamp: Date? = null,
+ override var supportsRetrievingAccountTransactions: Boolean = false,
+ override var supportsRetrievingBalance: Boolean = false,
+ override var supportsTransferringMoney: Boolean = false,
+ override var supportsInstantPaymentMoneyTransfer: Boolean = false,
+ override var bookedTransactions: List = listOf(),
+ override var unbookedTransactions: List = listOf()
+) : TypedBankAccount {
internal constructor() : this(Customer(), null, "") // for object deserializers
/* convenience constructors for languages not supporting default values */
- constructor(customer: Customer, productName: String?, identifier: String) : this(customer, productName, identifier, BankAccountType.Girokonto)
+ constructor(customer: TypedCustomer, productName: String?, identifier: String) : this(customer, productName, identifier, BankAccountType.Girokonto)
- constructor(customer: Customer, productName: String?, identifier: String, type: BankAccountType = BankAccountType.Girokonto, balance: BigDecimal = BigDecimal.Zero)
+ constructor(customer: TypedCustomer, productName: String?, identifier: String, type: BankAccountType = BankAccountType.Girokonto, balance: BigDecimal = BigDecimal.Zero)
: this(customer, identifier, "", null, null, "", balance, "EUR", type, productName)
- open var technicalId: String = UUID.random()
+ override var technicalId: String = UUID.random()
- open var haveAllTransactionsBeenFetched: Boolean = false
+ override var haveAllTransactionsBeenFetched: Boolean = false
- open var userSetDisplayName: String? = null
-
- override val displayName: String
- get() {
- return userSetDisplayName ?: productName ?: subAccountNumber ?: identifier
- }
+ override var userSetDisplayName: String? = null
override var displayIndex: Int = 0
- open fun addBookedTransactions(retrievedBookedTransactions: List) {
- val uniqueTransactions = this.bookedTransactions.toMutableSet()
-
- uniqueTransactions.addAll(retrievedBookedTransactions)
-
- this.bookedTransactions = uniqueTransactions.toList()
- }
-
- open fun addUnbookedTransactions(retrievedUnbookedTransactions: List) {
- val uniqueUnbookedTransactions = this.unbookedTransactions.toMutableSet()
-
- uniqueUnbookedTransactions.addAll(retrievedUnbookedTransactions)
-
- this.unbookedTransactions = uniqueUnbookedTransactions.toList()
- }
-
-
override fun toString(): String {
return "$accountHolderName ($identifier)"
}
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt
index cbac8a6e..bf71546f 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt
@@ -1,26 +1,22 @@
package net.dankito.banking.ui.model
-import net.dankito.utils.multiplatform.BigDecimal
-import net.dankito.utils.multiplatform.sum
import net.dankito.banking.ui.model.tan.TanMedium
-import net.dankito.banking.ui.model.tan.TanMediumStatus
import net.dankito.banking.ui.model.tan.TanProcedure
-import net.dankito.banking.util.sortedByDisplayIndex
import net.dankito.utils.multiplatform.UUID
open class Customer(
- open var bankCode: String,
- open var customerId: String,
- open var password: String,
- open var finTsServerAddress: String,
- open var bankName: String,
- open var bic: String,
- open var customerName: String,
- open var userId: String = customerId,
- open var iconUrl: String? = null,
- open var accounts: List = listOf()
-) : OrderedDisplayable {
+ override var bankCode: String,
+ override var customerId: String,
+ override var password: String,
+ override var finTsServerAddress: String,
+ override var bankName: String,
+ override var bic: String,
+ override var customerName: String,
+ override var userId: String = customerId,
+ override var iconUrl: String? = null,
+ override var accounts: List = listOf()
+) : TypedCustomer {
internal constructor() : this("", "", "", "", "", "", "") // for object deserializers
@@ -31,40 +27,23 @@ open class Customer(
: this(bankCode, customerId, password, finTsServerAddress, "", "", "")
- open var technicalId: String = UUID.random()
+ override var technicalId: String = UUID.random()
- open var supportedTanProcedures: List = listOf()
+ override var supportedTanProcedures: List = listOf()
- open var selectedTanProcedure: TanProcedure? = null
+ override var selectedTanProcedure: TanProcedure? = null
- open var tanMedia: List = listOf()
-
- open val tanMediaSorted: List
- get() = tanMedia.sortedByDescending { it.status == TanMediumStatus.Used }
+ override var tanMedia: List = listOf()
- open var userSetDisplayName: String? = null
-
- override val displayName: String
- get() = userSetDisplayName ?: bankName
+ override var userSetDisplayName: String? = null
override var displayIndex: Int = 0
- open val accountsSorted: List
- get() = accounts.sortedByDisplayIndex()
-
-
- open val balance: BigDecimal
- get() = accounts.map { it.balance }.sum()
-
- open val transactions: List
- get() = accounts.flatMap { it.bookedTransactions }
-
-
override fun toString(): String {
- return "$customerName ($customerId)"
+ return "$bankName $customerId"
}
}
\ No newline at end of file
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IAccountTransaction.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IAccountTransaction.kt
new file mode 100644
index 00000000..07262874
--- /dev/null
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IAccountTransaction.kt
@@ -0,0 +1,76 @@
+package net.dankito.banking.ui.model
+
+import net.dankito.utils.multiplatform.BigDecimal
+import net.dankito.utils.multiplatform.Date
+import net.dankito.utils.multiplatform.DateFormatter
+
+
+interface IAccountTransaction {
+
+ companion object {
+ val IdDateFormat = DateFormatter("yyyy.MM.dd")
+ }
+
+
+ val bankAccount: IBankAccount<*>
+ val amount: BigDecimal
+ val currency: String
+ val unparsedUsage: String
+ val bookingDate: Date
+ val otherPartyName: String?
+ val otherPartyBankCode: String?
+ val otherPartyAccountId: String?
+ val bookingText: String?
+ val valueDate: Date
+ val statementNumber: Int
+ val sequenceNumber: Int?
+ val openingBalance: BigDecimal?
+ val closingBalance: BigDecimal?
+
+ val endToEndReference: String?
+ val customerReference: String?
+ val mandateReference: String?
+ val creditorIdentifier: String?
+ val originatorsIdentificationCode: String?
+ val compensationAmount: String?
+ val originalAmount: String?
+ val sepaUsage: String?
+ val deviantOriginator: String?
+ val deviantRecipient: String?
+ val usageWithNoSpecialType: String?
+ val primaNotaNumber: String?
+ val textKeySupplement: String?
+
+ val currencyType: String?
+ val bookingKey: String
+ val referenceForTheAccountOwner: String
+ val referenceOfTheAccountServicingInstitution: String?
+ val supplementaryDetails: String?
+
+ val transactionReferenceNumber: String
+ val relatedReferenceNumber: String?
+
+
+ var technicalId: String
+
+
+ val showOtherPartyName: Boolean
+ get() = otherPartyName.isNullOrBlank() == false /* && type != "ENTGELTABSCHLUSS" && type != "AUSZAHLUNG" */ // TODO
+
+ val canCreateMoneyTransferFrom: Boolean
+ get() = otherPartyAccountId != null && bankAccount.supportsTransferringMoney
+
+ val usage: String
+ get() = sepaUsage ?: unparsedUsage
+
+
+ fun buildTransactionIdentifier() : String {
+ if (bankAccount != null) {
+ return "${bankAccount.technicalId} ${IdDateFormat.format(bookingDate)} ${IdDateFormat.format(valueDate)} $amount $currency $unparsedUsage $otherPartyName $otherPartyBankCode $otherPartyAccountId"
+ }
+ else { // happens for derived classes during initialization. These have to set technicalId after initialization by themselves
+ return " ${IdDateFormat.format(bookingDate)} ${IdDateFormat.format(valueDate)} $amount $currency $unparsedUsage $otherPartyName $otherPartyBankCode $otherPartyAccountId"
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IBankAccount.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IBankAccount.kt
new file mode 100644
index 00000000..d1ffa9f4
--- /dev/null
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IBankAccount.kt
@@ -0,0 +1,56 @@
+package net.dankito.banking.ui.model
+
+import net.dankito.utils.multiplatform.BigDecimal
+import net.dankito.utils.multiplatform.Date
+
+
+typealias TypedBankAccount = IBankAccount
+
+
+interface IBankAccount : OrderedDisplayable {
+ val customer: ICustomer<*, *>
+ var identifier: String
+ var accountHolderName: String
+ var iban: String?
+ var subAccountNumber: String?
+ var customerId: String
+ var balance: BigDecimal
+ var currency: String
+ var type: BankAccountType
+ var productName: String?
+ var accountLimit: String?
+ var lastRetrievedTransactionsTimestamp: Date?
+ var supportsRetrievingAccountTransactions: Boolean
+ var supportsRetrievingBalance: Boolean
+ var supportsTransferringMoney: Boolean
+ var supportsInstantPaymentMoneyTransfer: Boolean
+ var bookedTransactions: List
+ var unbookedTransactions: List
+ var technicalId: String
+ var haveAllTransactionsBeenFetched: Boolean
+ var userSetDisplayName: String?
+
+
+ override val displayName: String
+ get() {
+ return userSetDisplayName ?: productName ?: subAccountNumber ?: identifier
+ }
+
+
+ fun addBookedTransactions(retrievedBookedTransactions: List) {
+ val uniqueTransactions = this.bookedTransactions.toMutableSet()
+
+ uniqueTransactions.addAll(retrievedBookedTransactions)
+
+ this.bookedTransactions = uniqueTransactions.toList()
+ }
+
+ fun addUnbookedTransactions(retrievedUnbookedTransactions: List) {
+ val uniqueUnbookedTransactions = this.unbookedTransactions.toMutableSet()
+
+ uniqueUnbookedTransactions.addAll(retrievedUnbookedTransactions)
+
+ this.unbookedTransactions = uniqueUnbookedTransactions.toList()
+ }
+
+}
\ No newline at end of file
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/ICustomer.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/ICustomer.kt
new file mode 100644
index 00000000..29ed0a76
--- /dev/null
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/ICustomer.kt
@@ -0,0 +1,56 @@
+package net.dankito.banking.ui.model
+
+import net.dankito.banking.ui.model.tan.TanMedium
+import net.dankito.banking.ui.model.tan.TanMediumStatus
+import net.dankito.banking.ui.model.tan.TanProcedure
+import net.dankito.banking.util.sortedByDisplayIndex
+import net.dankito.utils.multiplatform.BigDecimal
+import net.dankito.utils.multiplatform.sum
+
+
+typealias TypedCustomer = ICustomer, IAccountTransaction>
+
+
+interface ICustomer, TAccountTransaction: IAccountTransaction> : OrderedDisplayable {
+
+ var bankCode: String
+ var customerId: String
+ var password: String
+ var finTsServerAddress: String
+
+ var bankName: String
+ var bic: String
+ var customerName: String
+ var userId: String
+
+ var iconUrl: String?
+
+ var accounts: List
+
+ var supportedTanProcedures: List
+ var selectedTanProcedure: TanProcedure?
+ var tanMedia: List
+
+ var userSetDisplayName: String?
+
+ var technicalId: String
+
+
+ override val displayName: String
+ get() = userSetDisplayName ?: bankName
+
+
+ val accountsSorted: List
+ get() = accounts.sortedByDisplayIndex()
+
+
+ val balance: BigDecimal
+ get() = accounts.map { it.balance }.sum()
+
+ val transactions: List
+ get() = accounts.flatMap { it.bookedTransactions }
+
+ val tanMediaSorted: List
+ get() = tanMedia.sortedByDescending { it.status == TanMediumStatus.Used }
+
+}
\ No newline at end of file
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/MessageLogEntry.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/MessageLogEntry.kt
index ff5050d6..abed10af 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/MessageLogEntry.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/MessageLogEntry.kt
@@ -6,7 +6,7 @@ import net.dankito.utils.multiplatform.Date
open class MessageLogEntry(
val message: String,
val time: Date,
- val customer: Customer
+ val customer: TypedCustomer
) {
override fun toString(): String {
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/mapper/DefaultModelCreator.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/mapper/DefaultModelCreator.kt
new file mode 100644
index 00000000..50d2091a
--- /dev/null
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/mapper/DefaultModelCreator.kt
@@ -0,0 +1,66 @@
+package net.dankito.banking.ui.model.mapper
+
+import net.dankito.banking.ui.model.*
+import net.dankito.utils.multiplatform.BigDecimal
+import net.dankito.utils.multiplatform.Date
+
+
+open class DefaultModelCreator : IModelCreator {
+
+ override fun createCustomer(bankCode: String, customerId: String, password: String, finTsServerAddress: String, bankName: String, bic: String,
+ customerName: String, userId: String, iconUrl: String?): TypedCustomer {
+
+ return Customer(bankCode, customerId, password, finTsServerAddress, bankName, bic, customerName, userId, iconUrl)
+ }
+
+
+ override fun createBankAccount(customer: TypedCustomer, productName: String?, identifier: String): TypedBankAccount {
+ return BankAccount(customer, productName, identifier)
+ }
+
+ override fun createTransaction(
+ bankAccount: TypedBankAccount,
+ amount: BigDecimal,
+ currency: String,
+ unparsedUsage: String,
+ bookingDate: Date,
+ otherPartyName: String?,
+ otherPartyBankCode: String?,
+ otherPartyAccountId: String?,
+ bookingText: String?,
+ valueDate: Date,
+ statementNumber: Int,
+ sequenceNumber: Int?,
+ openingBalance: BigDecimal?,
+ closingBalance: BigDecimal?,
+ endToEndReference: String?,
+ customerReference: String?,
+ mandateReference: String?,
+ creditorIdentifier: String?,
+ originatorsIdentificationCode: String?,
+ compensationAmount: String?,
+ originalAmount: String?,
+ sepaUsage: String?,
+ deviantOriginator: String?,
+ deviantRecipient: String?,
+ usageWithNoSpecialType: String?,
+ primaNotaNumber: String?,
+ textKeySupplement: String?,
+ currencyType: String?,
+ bookingKey: String,
+ referenceForTheAccountOwner: String,
+ referenceOfTheAccountServicingInstitution: String?,
+ supplementaryDetails: String?,
+ transactionReferenceNumber: String,
+ relatedReferenceNumber: String?
+ ) : IAccountTransaction {
+
+ return AccountTransaction(bankAccount, amount, currency, unparsedUsage, bookingDate,
+ otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, valueDate, statementNumber, sequenceNumber,
+ openingBalance, closingBalance, endToEndReference, customerReference, mandateReference, creditorIdentifier,
+ originatorsIdentificationCode, compensationAmount, originalAmount, sepaUsage, deviantOriginator, deviantRecipient,
+ usageWithNoSpecialType, primaNotaNumber, textKeySupplement, currencyType, bookingKey, referenceForTheAccountOwner,
+ referenceOfTheAccountServicingInstitution, supplementaryDetails, transactionReferenceNumber, relatedReferenceNumber)
+ }
+
+}
\ No newline at end of file
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/mapper/IModelCreator.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/mapper/IModelCreator.kt
new file mode 100644
index 00000000..3de107cb
--- /dev/null
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/mapper/IModelCreator.kt
@@ -0,0 +1,57 @@
+package net.dankito.banking.ui.model.mapper
+
+import net.dankito.banking.ui.model.*
+import net.dankito.utils.multiplatform.BigDecimal
+import net.dankito.utils.multiplatform.Date
+
+
+interface IModelCreator {
+
+ fun createCustomer(bankCode: String, customerId: String, password: String, finTsServerAddress: String, bankName: String, bic: String,
+ customerName: String = "", userId: String = customerId, iconUrl: String? = null): TypedCustomer
+
+
+ fun createBankAccount(customer: TypedCustomer, productName: String?, identifier: String) : TypedBankAccount
+
+
+ fun createTransaction(
+ bankAccount: TypedBankAccount,
+ amount: BigDecimal,
+ currency: String,
+ unparsedUsage: String,
+ bookingDate: Date,
+ otherPartyName: String?,
+ otherPartyBankCode: String?,
+ otherPartyAccountId: String?,
+ bookingText: String?,
+ valueDate: Date,
+ statementNumber: Int,
+ sequenceNumber: Int?,
+ openingBalance: BigDecimal?,
+ closingBalance: BigDecimal?,
+
+ endToEndReference: String?,
+ customerReference: String?,
+ mandateReference: String?,
+ creditorIdentifier: String?,
+ originatorsIdentificationCode: String?,
+ compensationAmount: String?,
+ originalAmount: String?,
+ sepaUsage: String?,
+ deviantOriginator: String?,
+ deviantRecipient: String?,
+ usageWithNoSpecialType: String?,
+ primaNotaNumber: String?,
+ textKeySupplement: String?,
+
+ currencyType: String?,
+ bookingKey: String,
+ referenceForTheAccountOwner: String,
+ referenceOfTheAccountServicingInstitution: String?,
+ supplementaryDetails: String?,
+
+ transactionReferenceNumber: String,
+ relatedReferenceNumber: String?
+ ) : IAccountTransaction
+
+}
\ No newline at end of file
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/GetTransactionsParameter.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/GetTransactionsParameter.kt
index 222c7733..0f6f8aa4 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/GetTransactionsParameter.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/GetTransactionsParameter.kt
@@ -1,7 +1,7 @@
package net.dankito.banking.ui.model.parameters
import net.dankito.utils.multiplatform.Date
-import net.dankito.banking.ui.model.AccountTransaction
+import net.dankito.banking.ui.model.IAccountTransaction
open class GetTransactionsParameter(
@@ -9,7 +9,7 @@ open class GetTransactionsParameter(
val fromDate: Date? = null,
val toDate: Date? = null,
val abortIfTanIsRequired: Boolean = false,
- val retrievedChunkListener: ((List) -> Unit)? = null
+ val retrievedChunkListener: ((List) -> Unit)? = null
) {
constructor() : this(true, null, null) // for Java
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/TransferMoneyData.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/TransferMoneyData.kt
index 9f336196..c3a0a263 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/TransferMoneyData.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/parameters/TransferMoneyData.kt
@@ -1,12 +1,11 @@
package net.dankito.banking.ui.model.parameters
+import net.dankito.banking.ui.model.*
import net.dankito.utils.multiplatform.BigDecimal
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
open class TransferMoneyData(
- val account: BankAccount,
+ val account: TypedBankAccount,
val creditorName: String,
val creditorIban: String,
val creditorBic: String,
@@ -17,9 +16,9 @@ open class TransferMoneyData(
companion object {
- fun fromAccountTransactionWithoutAmountAndUsage(transaction: AccountTransaction): TransferMoneyData {
+ fun fromAccountTransactionWithoutAmountAndUsage(transaction: IAccountTransaction): TransferMoneyData {
return TransferMoneyData(
- transaction.bankAccount,
+ transaction.bankAccount as TypedBankAccount,
transaction.otherPartyName ?: "",
transaction.otherPartyAccountId ?: "",
transaction.otherPartyBankCode ?: "",
@@ -28,9 +27,9 @@ open class TransferMoneyData(
)
}
- fun fromAccountTransaction(transaction: AccountTransaction): TransferMoneyData {
+ fun fromAccountTransaction(transaction: IAccountTransaction): TransferMoneyData {
return TransferMoneyData(
- transaction.bankAccount,
+ transaction.bankAccount as TypedBankAccount,
transaction.otherPartyName ?: "",
transaction.otherPartyAccountId ?: "",
transaction.otherPartyBankCode ?: "",
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/AddAccountResponse.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/AddAccountResponse.kt
index e56815cb..8962823c 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/AddAccountResponse.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/AddAccountResponse.kt
@@ -1,19 +1,17 @@
package net.dankito.banking.ui.model.responses
+import net.dankito.banking.ui.model.*
import net.dankito.utils.multiplatform.BigDecimal
-import net.dankito.banking.ui.model.Customer
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
open class AddAccountResponse(
isSuccessful: Boolean,
errorToShowToUser: String?,
- val customer: Customer,
+ val customer: TypedCustomer,
val supportsRetrievingTransactionsOfLast90DaysWithoutTan: Boolean = false,
- val bookedTransactionsOfLast90Days: Map> = mapOf(),
- val unbookedTransactionsOfLast90Days: Map> = mapOf(),
- val balances: Map = mapOf(),
+ val bookedTransactionsOfLast90Days: Map> = mapOf(),
+ val unbookedTransactionsOfLast90Days: Map> = mapOf(),
+ val balances: Map = mapOf(),
userCancelledAction: Boolean = false
)
: BankingClientResponse(isSuccessful, errorToShowToUser, userCancelledAction) {
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/GetTransactionsResponse.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/GetTransactionsResponse.kt
index 9ef13977..2ea46a37 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/GetTransactionsResponse.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/responses/GetTransactionsResponse.kt
@@ -1,15 +1,15 @@
package net.dankito.banking.ui.model.responses
import net.dankito.utils.multiplatform.BigDecimal
-import net.dankito.banking.ui.model.AccountTransaction
-import net.dankito.banking.ui.model.BankAccount
+import net.dankito.banking.ui.model.IAccountTransaction
+import net.dankito.banking.ui.model.TypedBankAccount
open class GetTransactionsResponse(
- val bankAccount: BankAccount,
+ val bankAccount: TypedBankAccount,
isSuccessful: Boolean,
errorToShowToUser: String?,
- val bookedTransactions: List = listOf(),
+ val bookedTransactions: List = listOf(),
val unbookedTransactions: List = listOf(),
val balance: BigDecimal? = null,
userCancelledAction: Boolean = false,
diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt
index e256ad08..221f3125 100644
--- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt
+++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt
@@ -15,6 +15,8 @@ import net.dankito.banking.bankfinder.BankInfo
import net.dankito.banking.search.IRemitteeSearcher
import net.dankito.banking.search.NoOpRemitteeSearcher
import net.dankito.banking.search.Remittee
+import net.dankito.banking.ui.model.mapper.DefaultModelCreator
+import net.dankito.banking.ui.model.mapper.IModelCreator
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResult
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResultType
import net.dankito.banking.ui.model.parameters.GetTransactionsParameter
@@ -30,12 +32,13 @@ import net.dankito.utils.multiplatform.log.LoggerFactory
import kotlin.collections.ArrayList
-open class BankingPresenter(
+open class BankingPresenter constructor(
protected val bankingClientCreator: IBankingClientCreator,
protected val bankFinder: IBankFinder,
protected val dataFolder: File,
protected val persister: IBankingPersistence,
protected val router: IRouter,
+ protected val modelCreator: IModelCreator = DefaultModelCreator(),
protected val remitteeSearcher: IRemitteeSearcher = NoOpRemitteeSearcher(),
protected val bankIconFinder: IBankIconFinder = NoOpBankIconFinder(),
protected val textExtractorRegistry: ITextExtractorRegistry = NoOpTextExtractorRegistry(),
@@ -56,25 +59,25 @@ open class BankingPresenter(
}
- protected val bankingClientsForAccounts = mutableMapOf()
+ protected val bankingClientsForAccounts = mutableMapOf()
- protected var selectedBankAccountsField = mutableListOf()
+ protected var selectedBankAccountsField = mutableListOf()
protected var selectedAccountType = SelectedAccountType.AllAccounts
protected var saveAccountOnNextEnterTanInvocation = false
- protected val accountsChangedListeners = mutableListOf<(List) -> Unit>()
+ protected val accountsChangedListeners = mutableListOf<(List) -> Unit>()
protected val retrievedAccountTransactionsResponseListeners = mutableListOf<(GetTransactionsResponse) -> Unit>()
- protected val selectedBankAccountsChangedListeners = mutableListOf<(List) -> Unit>()
+ protected val selectedBankAccountsChangedListeners = mutableListOf<(List) -> Unit>()
protected val callback: BankingClientCallback = object : BankingClientCallback {
- override fun enterTan(customer: Customer, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit) {
+ override fun enterTan(customer: TypedCustomer, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit) {
if (saveAccountOnNextEnterTanInvocation) {
persistAccount(customer)
saveAccountOnNextEnterTanInvocation = false
@@ -131,14 +134,14 @@ open class BankingPresenter(
}
}
- protected open fun addClientForAccount(customer: Customer, client: IBankingClient) {
+ protected open fun addClientForAccount(customer: TypedCustomer, client: IBankingClient) {
bankingClientsForAccounts.put(customer, client)
}
// TODO: move BankInfo out of fints4k
- open fun addAccountAsync(bankInfo: BankInfo, customerId: String, pin: String, callback: (AddAccountResponse) -> Unit) {
- val customer = Customer(bankInfo.bankCode, customerId, pin, bankInfo.pinTanAddress ?: "", bankInfo.name, bankInfo.bic, "")
+ open fun addAccountAsync(bankInfo: BankInfo, customerId: String, password: String, callback: (AddAccountResponse) -> Unit) {
+ val customer = modelCreator.createCustomer(bankInfo.bankCode, customerId, password, bankInfo.pinTanAddress ?: "", bankInfo.name, bankInfo.bic, "")
val newClient = bankingClientCreator.createClient(customer, dataFolder, asyncRunner, this.callback)
@@ -180,7 +183,7 @@ open class BankingPresenter(
}
}
- protected open fun findIconForBankAsync(customer: Customer) {
+ protected open fun findIconForBankAsync(customer: TypedCustomer) {
bankIconFinder.findIconForBankAsync(customer.bankName) { bankIconUrl ->
bankIconUrl?.let {
try {
@@ -192,7 +195,7 @@ open class BankingPresenter(
}
}
- protected open fun handleFindIconForBankResult(customer: Customer, bankIconUrl: String) {
+ protected open fun handleFindIconForBankResult(customer: TypedCustomer, bankIconUrl: String) {
val bankIconFile = saveBankIconToDisk(customer, bankIconUrl)
var iconFilePath = bankIconFile.getAbsolutePath()
@@ -208,7 +211,7 @@ open class BankingPresenter(
callAccountsChangedListeners()
}
- protected open fun saveBankIconToDisk(customer: Customer, bankIconUrl: String): File {
+ protected open fun saveBankIconToDisk(customer: TypedCustomer, bankIconUrl: String): File {
val bankIconsDir = File(dataFolder, "bank_icons")
bankIconsDir.mkdirs()
@@ -239,7 +242,7 @@ open class BankingPresenter(
}
- open fun deleteAccount(customer: Customer) {
+ open fun deleteAccount(customer: TypedCustomer) {
val wasSelected = isSingleSelectedAccount(customer) or // either account or one of its bank accounts is currently selected
(customer.accounts.firstOrNull { isSingleSelectedBankAccount(it) } != null)
@@ -264,7 +267,7 @@ open class BankingPresenter(
}
- open fun fetchAllAccountTransactionsAsync(customer: Customer,
+ open fun fetchAllAccountTransactionsAsync(customer: TypedCustomer,
callback: (GetTransactionsResponse) -> Unit) {
customer.accounts.forEach { bankAccount ->
@@ -274,13 +277,13 @@ open class BankingPresenter(
}
}
- open fun fetchAllAccountTransactionsAsync(bankAccount: BankAccount,
+ open fun fetchAllAccountTransactionsAsync(bankAccount: TypedBankAccount,
callback: (GetTransactionsResponse) -> Unit) {
fetchAccountTransactionsAsync(bankAccount, null, false, callback)
}
- open fun fetchAccountTransactionsAsync(bankAccount: BankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false,
+ open fun fetchAccountTransactionsAsync(bankAccount: TypedBankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false,
callback: (GetTransactionsResponse) -> Unit) {
getBankingClientForAccount(bankAccount.customer)?.let { client ->
@@ -319,7 +322,7 @@ open class BankingPresenter(
}
}
- protected open fun updateBanksAccountsTransactionsAsync(accounts: List, abortIfTanIsRequired: Boolean = false, callback: (GetTransactionsResponse) -> Unit) {
+ protected open fun updateBanksAccountsTransactionsAsync(accounts: List, abortIfTanIsRequired: Boolean = false, callback: (GetTransactionsResponse) -> Unit) {
accounts.forEach { bankAccount ->
if (bankAccount.supportsRetrievingAccountTransactions) {
updateBankAccountTransactionsAsync(bankAccount, abortIfTanIsRequired, callback)
@@ -327,7 +330,7 @@ open class BankingPresenter(
}
}
- protected open fun updateBankAccountTransactionsAsync(bankAccount: BankAccount, abortIfTanIsRequired: Boolean, callback: (GetTransactionsResponse) -> Unit) {
+ protected open fun updateBankAccountTransactionsAsync(bankAccount: TypedBankAccount, abortIfTanIsRequired: Boolean, callback: (GetTransactionsResponse) -> Unit) {
val fromDate = bankAccount.lastRetrievedTransactionsTimestamp?.let { Date(it.millisSinceEpoch - OneDayMillis) } // one day before last received transactions
fetchAccountTransactionsAsync(bankAccount, fromDate, abortIfTanIsRequired, callback)
@@ -347,7 +350,7 @@ open class BankingPresenter(
callRetrievedAccountTransactionsResponseListener(response)
}
- protected open fun receivedAccountsTransactionChunk(bankAccount: BankAccount, accountTransactionsChunk: List) {
+ protected open fun receivedAccountsTransactionChunk(bankAccount: TypedBankAccount, accountTransactionsChunk: List) {
if (accountTransactionsChunk.isNotEmpty()) {
bankAccount.addBookedTransactions(accountTransactionsChunk)
@@ -370,7 +373,7 @@ open class BankingPresenter(
persistAccountTransactions(bankAccount, response.bookedTransactions, response.unbookedTransactions)
}
- protected open fun updateBalance(bankAccount: BankAccount, balance: BigDecimal) {
+ protected open fun updateBalance(bankAccount: TypedBankAccount, balance: BigDecimal) {
bankAccount.balance = balance
persistAccount(bankAccount.customer)
@@ -388,25 +391,25 @@ open class BankingPresenter(
}
}
- open fun accountDisplayIndexUpdated(account: Customer) {
+ open fun accountDisplayIndexUpdated(account: TypedCustomer) {
persistAccount(account)
}
- open fun accountUpdated(bank: Customer) {
+ open fun accountUpdated(bank: TypedCustomer) {
persistAccount(bank)
getBankingClientForAccount(bank)?.dataChanged(bank)
}
- open fun accountUpdated(account: BankAccount) {
+ open fun accountUpdated(account: TypedBankAccount) {
persistAccount(account.customer)
}
- protected open fun persistAccount(customer: Customer) {
- persister.saveOrUpdateAccount(customer, customers)
+ protected open fun persistAccount(customer: ICustomer<*, *>) {
+ persister.saveOrUpdateAccount(customer as TypedCustomer, customers)
}
- protected open fun persistAccountTransactions(bankAccount: BankAccount, bookedTransactions: List, unbookedTransactions: List) {
+ protected open fun persistAccountTransactions(bankAccount: TypedBankAccount, bookedTransactions: List, unbookedTransactions: List) {
persister.saveOrUpdateAccountTransactions(bankAccount, bookedTransactions)
// TODO: someday also persist unbooked transactions
@@ -513,11 +516,11 @@ open class BankingPresenter(
}
- open fun searchSelectedAccountTransactions(query: String): List {
+ open fun searchSelectedAccountTransactions(query: String): List {
return searchAccountTransactions(query, selectedBankAccountsAccountTransactions)
}
- open fun searchAccountTransactions(query: String, transactions: List): List {
+ open fun searchAccountTransactions(query: String, transactions: List): List {
val queryLowercase = query.trim().toLowerCase()
if (queryLowercase.isEmpty()) {
@@ -532,7 +535,7 @@ open class BankingPresenter(
}
- open fun getMessageLogForAccounts(customers: List): List {
+ open fun getMessageLogForAccounts(customers: List): List {
val logEntries = customers.flatMap {
getBankingClientForAccount(it)?.messageLogWithoutSensitiveData ?: listOf()
}
@@ -556,15 +559,15 @@ open class BankingPresenter(
}
- protected open fun getBankingClientForAccount(customer: Customer): IBankingClient? {
- return bankingClientsForAccounts.get(customer)
+ protected open fun getBankingClientForAccount(customer: ICustomer<*, *>): IBankingClient? {
+ return bankingClientsForAccounts.get(customer as TypedCustomer)
}
- open val selectedBankAccounts: List
+ open val selectedBankAccounts: List
get() = ArrayList(selectedBankAccountsField)
- open val selectedBankAccountsAccountTransactions: List
+ open val selectedBankAccountsAccountTransactions: List
get() = getAccountTransactionsForBankAccounts(selectedBankAccounts)
open val balanceOfSelectedBankAccounts: BigDecimal
@@ -574,12 +577,12 @@ open class BankingPresenter(
open val areAllAccountSelected: Boolean
get() = selectedAccountType == SelectedAccountType.AllAccounts
- open fun isSingleSelectedAccount(customer: Customer): Boolean {
+ open fun isSingleSelectedAccount(customer: TypedCustomer): Boolean {
return selectedAccountType == SelectedAccountType.SingleAccount
&& selectedBankAccountsField.map { it.customer }.toSet().containsExactly(customer)
}
- open fun isSingleSelectedBankAccount(bankAccount: BankAccount): Boolean {
+ open fun isSingleSelectedBankAccount(bankAccount: TypedBankAccount): Boolean {
return selectedAccountType == SelectedAccountType.SingleBankAccount
&& selectedBankAccountsField.containsExactly(bankAccount)
}
@@ -590,39 +593,39 @@ open class BankingPresenter(
setSelectedBankAccounts(bankAccounts)
}
- open fun selectedAccount(customer: Customer) {
+ open fun selectedAccount(customer: TypedCustomer) {
selectedAccountType = SelectedAccountType.SingleAccount
setSelectedBankAccounts(customer.accounts)
}
- open fun selectedBankAccount(bankAccount: BankAccount) {
+ open fun selectedBankAccount(bankAccount: TypedBankAccount) {
selectedAccountType = SelectedAccountType.SingleBankAccount
setSelectedBankAccounts(listOf(bankAccount))
}
- protected open fun setSelectedBankAccounts(bankAccounts: List) {
+ protected open fun setSelectedBankAccounts(bankAccounts: List) {
this.selectedBankAccountsField = ArrayList(bankAccounts) // make a copy
callSelectedBankAccountsChangedListeners(selectedBankAccountsField)
}
- open val customers: List
+ open val customers: List
get() = bankingClientsForAccounts.keys.toList()
- open val bankAccounts: List
+ open val bankAccounts: List
get() = customers.flatMap { it.accounts }
- open val allTransactions: List
+ open val allTransactions: List
get() = getAccountTransactionsForBankAccounts(bankAccounts)
open val balanceOfAllAccounts: BigDecimal
get() = getBalanceForAccounts(customers)
- open val bankAccountsSupportingRetrievingAccountTransactions: List
+ open val bankAccountsSupportingRetrievingAccountTransactions: List
get() = bankAccounts.filter { it.supportsRetrievingAccountTransactions }
open val hasBankAccountsSupportingRetrievingAccountTransactions: Boolean
@@ -631,12 +634,12 @@ open class BankingPresenter(
open val doSelectedBankAccountsSupportRetrievingAccountTransactions: Boolean
get() = doBankAccountsSupportRetrievingAccountTransactions(selectedBankAccounts)
- open fun doBankAccountsSupportRetrievingAccountTransactions(bankAccounts: List): Boolean {
+ open fun doBankAccountsSupportRetrievingAccountTransactions(bankAccounts: List): Boolean {
return bankAccounts.firstOrNull { it.supportsRetrievingAccountTransactions } != null
}
- open val bankAccountsSupportingRetrievingBalance: List
+ open val bankAccountsSupportingRetrievingBalance: List
get() = bankAccounts.filter { it.supportsRetrievingBalance }
open val hasBankAccountsSupportingRetrievingBalance: Boolean
@@ -645,12 +648,12 @@ open class BankingPresenter(
open val doSelectedBankAccountsSupportRetrievingBalance: Boolean
get() = doBankAccountsSupportRetrievingBalance(selectedBankAccounts)
- open fun doBankAccountsSupportRetrievingBalance(bankAccounts: List): Boolean {
+ open fun doBankAccountsSupportRetrievingBalance(bankAccounts: List): Boolean {
return bankAccounts.firstOrNull { it.supportsRetrievingBalance } != null
}
- open val bankAccountsSupportingTransferringMoney: List
+ open val bankAccountsSupportingTransferringMoney: List
get() = bankAccounts.filter { it.supportsTransferringMoney }
open val hasBankAccountsSupportTransferringMoney: Boolean
@@ -659,16 +662,16 @@ open class BankingPresenter(
open val doSelectedBankAccountsSupportTransferringMoney: Boolean
get() = doBankAccountsSupportTransferringMoney(selectedBankAccounts)
- open fun doBankAccountsSupportTransferringMoney(bankAccounts: List): Boolean {
+ open fun doBankAccountsSupportTransferringMoney(bankAccounts: List): Boolean {
return bankAccounts.firstOrNull { it.supportsTransferringMoney } != null
}
- protected open fun getAccountTransactionsForBankAccounts(bankAccounts: Collection): List {
+ protected open fun getAccountTransactionsForBankAccounts(bankAccounts: Collection): List {
return bankAccounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate.millisSinceEpoch } // TODO: someday add unbooked transactions
}
- protected open fun getBalanceForAccounts(customers: Collection): BigDecimal {
+ protected open fun getBalanceForAccounts(customers: Collection): BigDecimal {
return customers.map { it.balance }.sum()
}
@@ -677,7 +680,7 @@ open class BankingPresenter(
}
- open fun getTanMediaForTanProcedure(bank: Customer, tanProcedure: TanProcedure): List {
+ open fun getTanMediaForTanProcedure(bank: TypedCustomer, tanProcedure: TanProcedure): List {
if (ChipTanTanProcedures.contains(tanProcedure.type)) {
return bank.tanMediaSorted.filterIsInstance()
}
@@ -719,11 +722,11 @@ open class BankingPresenter(
}
- open fun addAccountsChangedListener(listener: (List) -> Unit): Boolean {
+ open fun addAccountsChangedListener(listener: (List) -> Unit): Boolean {
return accountsChangedListeners.add(listener)
}
- open fun removeAccountsChangedListener(listener: (List) -> Unit): Boolean {
+ open fun removeAccountsChangedListener(listener: (List) -> Unit): Boolean {
return accountsChangedListeners.add(listener)
}
@@ -751,15 +754,15 @@ open class BankingPresenter(
}
- open fun addSelectedBankAccountsChangedListener(listener: (List) -> Unit): Boolean {
+ open fun addSelectedBankAccountsChangedListener(listener: (List) -> Unit): Boolean {
return selectedBankAccountsChangedListeners.add(listener)
}
- open fun removeSelectedBankAccountsChangedListener(listener: (List) -> Unit): Boolean {
+ open fun removeSelectedBankAccountsChangedListener(listener: (List) -> Unit): Boolean {
return selectedBankAccountsChangedListeners.add(listener)
}
- protected open fun callSelectedBankAccountsChangedListeners(selectedBankAccounts: List) {
+ protected open fun callSelectedBankAccountsChangedListeners(selectedBankAccounts: List) {
val selectedBankAccounts = this.selectedBankAccounts
ArrayList(selectedBankAccountsChangedListeners).forEach {
diff --git a/ui/BankingUiNativeIntegration/src/iosMain/kotlin/net/dankito/banking/BankingPresenterSwift.kt b/ui/BankingUiNativeIntegration/src/iosMain/kotlin/net/dankito/banking/BankingPresenterSwift.kt
index b3fb395d..add17df7 100644
--- a/ui/BankingUiNativeIntegration/src/iosMain/kotlin/net/dankito/banking/BankingPresenterSwift.kt
+++ b/ui/BankingUiNativeIntegration/src/iosMain/kotlin/net/dankito/banking/BankingPresenterSwift.kt
@@ -5,6 +5,7 @@ import net.dankito.banking.fints.webclient.IWebClient
import net.dankito.banking.persistence.IBankingPersistence
import net.dankito.banking.search.IRemitteeSearcher
import net.dankito.banking.ui.IRouter
+import net.dankito.banking.ui.model.mapper.DefaultModelCreator
import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.util.*
import net.dankito.banking.util.extraction.NoOpInvoiceDataExtractor
@@ -14,7 +15,7 @@ import net.dankito.utils.multiplatform.File
class BankingPresenterSwift(dataFolder: File, router: IRouter, webClient: IWebClient, persistence: IBankingPersistence,
remitteeSearcher: IRemitteeSearcher, bankIconFinder: IBankIconFinder, serializer: ISerializer, asyncRunner: IAsyncRunner)
- : BankingPresenter(fints4kBankingClientCreator(serializer, webClient), InMemoryBankFinder(), dataFolder, persistence, router,
+ : BankingPresenter(fints4kBankingClientCreator(DefaultModelCreator(), serializer, webClient), InMemoryBankFinder(), dataFolder, persistence, router, DefaultModelCreator(),
remitteeSearcher, bankIconFinder, NoOpTextExtractorRegistry(), NoOpInvoiceDataExtractor(), serializer, asyncRunner) {
}
\ No newline at end of file
diff --git a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj
index 53512726..557be7ec 100644
--- a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj
+++ b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj
@@ -35,6 +35,8 @@
366FA4E224C4ED6C0094F009 /* EnterTanDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366FA4E124C4ED6C0094F009 /* EnterTanDialog.swift */; };
366FA4E624C6EBF40094F009 /* EnterTanState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366FA4E524C6EBF40094F009 /* EnterTanState.swift */; };
3684EB8B2508F6F00001139E /* SearchBarWithLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3684EB8A2508F6F00001139E /* SearchBarWithLabel.swift */; };
+ 3684EB8F250B7F3C0001139E /* BankingUiCommon.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3684EB8E250B7F3C0001139E /* BankingUiCommon.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 3684EB90250B7F560001139E /* BankingUiCommon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3684EB8E250B7F3C0001139E /* BankingUiCommon.framework */; };
36B8A4482503D12100C15359 /* ProtectAppSettingsDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A4472503D12100C15359 /* ProtectAppSettingsDialog.swift */; };
36B8A44B2503D1E800C15359 /* BiometricAuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A44A2503D1E800C15359 /* BiometricAuthenticationService.swift */; };
36B8A44D2503D96D00C15359 /* AuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A44C2503D96D00C15359 /* AuthenticationService.swift */; };
@@ -44,8 +46,6 @@
36B8A4562503E9B200C15359 /* UIAlertBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A4552503E9B200C15359 /* UIAlertBase.swift */; };
36B8A4582503EEB600C15359 /* ActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A4572503EEB600C15359 /* ActionSheet.swift */; };
36BCF85424BA0C54005BEC29 /* BankList.json in Resources */ = {isa = PBXBuildFile; fileRef = 36BCF85324BA0C54005BEC29 /* BankList.json */; };
- 36BCF85824BA4274005BEC29 /* BankingUiCommon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36BCF85524BA41EE005BEC29 /* BankingUiCommon.framework */; };
- 36BCF85924BA4274005BEC29 /* BankingUiCommon.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 36BCF85524BA41EE005BEC29 /* BankingUiCommon.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
36BCF85E24BA4DA8005BEC29 /* MultiplatformUtils.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36BCF85D24BA4DA8005BEC29 /* MultiplatformUtils.framework */; };
36BCF85F24BA4DA8005BEC29 /* MultiplatformUtils.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 36BCF85D24BA4DA8005BEC29 /* MultiplatformUtils.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
36BCF86324BA5097005BEC29 /* SwiftUiRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF86224BA5097005BEC29 /* SwiftUiRouter.swift */; };
@@ -138,8 +138,8 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
+ 3684EB8F250B7F3C0001139E /* BankingUiCommon.framework in Embed Frameworks */,
36BCF86A24BA550D005BEC29 /* BankFinder.framework in Embed Frameworks */,
- 36BCF85924BA4274005BEC29 /* BankingUiCommon.framework in Embed Frameworks */,
36BCF85F24BA4DA8005BEC29 /* MultiplatformUtils.framework in Embed Frameworks */,
36FC92D124B39C47002B12E9 /* fints4k.framework in Embed Frameworks */,
36BCF87124BB0F8A005BEC29 /* fints4kBankingClient.framework in Embed Frameworks */,
@@ -179,6 +179,8 @@
366FA4E124C4ED6C0094F009 /* EnterTanDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterTanDialog.swift; sourceTree = ""; };
366FA4E524C6EBF40094F009 /* EnterTanState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterTanState.swift; sourceTree = ""; };
3684EB8A2508F6F00001139E /* SearchBarWithLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarWithLabel.swift; sourceTree = ""; };
+ 3684EB8C250B7F2B0001139E /* BankingUiCommon.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = BankingUiCommon.framework.dSYM; path = "../BankingUiCommon/build/xcode-frameworks/BankingUiCommon.framework.dSYM"; sourceTree = ""; };
+ 3684EB8E250B7F3C0001139E /* BankingUiCommon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BankingUiCommon.framework; path = "../BankingUiCommon/build/xcode-frameworks/BankingUiCommon.framework"; sourceTree = ""; };
36B8A4472503D12100C15359 /* ProtectAppSettingsDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtectAppSettingsDialog.swift; sourceTree = ""; };
36B8A44A2503D1E800C15359 /* BiometricAuthenticationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricAuthenticationService.swift; sourceTree = ""; };
36B8A44C2503D96D00C15359 /* AuthenticationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationService.swift; sourceTree = ""; };
@@ -264,8 +266,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 3684EB90250B7F560001139E /* BankingUiCommon.framework in Frameworks */,
36BCF86924BA550D005BEC29 /* BankFinder.framework in Frameworks */,
- 36BCF85824BA4274005BEC29 /* BankingUiCommon.framework in Frameworks */,
36BCF85E24BA4DA8005BEC29 /* MultiplatformUtils.framework in Frameworks */,
36FC92D024B39C47002B12E9 /* fints4k.framework in Frameworks */,
36BCF87024BB0F8A005BEC29 /* fints4kBankingClient.framework in Frameworks */,
@@ -419,6 +421,8 @@
36FC928F24B39A05002B12E9 = {
isa = PBXGroup;
children = (
+ 3684EB8E250B7F3C0001139E /* BankingUiCommon.framework */,
+ 3684EB8C250B7F2B0001139E /* BankingUiCommon.framework.dSYM */,
36FC929A24B39A05002B12E9 /* BankingiOSApp */,
36FC92B424B39A08002B12E9 /* BankingiOSAppTests */,
36FC92BF24B39A08002B12E9 /* BankingiOSAppUITests */,
diff --git a/ui/BankingiOSApp/BankingiOSApp/Preview Content/PreviewData.swift b/ui/BankingiOSApp/BankingiOSApp/Preview Content/PreviewData.swift
index cdd65dd4..4346273f 100644
--- a/ui/BankingiOSApp/BankingiOSApp/Preview Content/PreviewData.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/Preview Content/PreviewData.swift
@@ -15,7 +15,7 @@ let previewImageTanChallenge = ImageTanChallenge(image: TanImage(mimeType: "imag
let previewFlickerCodeTanChallenge = FlickerCodeTanChallenge(flickerCode: FlickerCode(challengeHHD_UC: "", parsedDataSet: "", decodingError: nil), messageToShowToUser: "", tanProcedure: previewTanProcedures[0])
-func createPreviewBanks() -> [Customer] {
+func createPreviewBanks() -> [ICustomer] {
let bank1 = Customer(bankCode: "", customerId: "", password: "", finTsServerAddress: "", bankName: "Abzockbank", bic: "", customerName: "Marieke Musterfrau", userId: "", iconUrl: "", accounts: [])
bank1.accounts = [
diff --git a/ui/BankingiOSApp/BankingiOSApp/extensions/Extensions.swift b/ui/BankingiOSApp/BankingiOSApp/extensions/Extensions.swift
index 690b7147..a0d1c90e 100644
--- a/ui/BankingiOSApp/BankingiOSApp/extensions/Extensions.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/extensions/Extensions.swift
@@ -89,7 +89,32 @@ extension AccountTransaction : Identifiable {
}
-extension Array where Element == Customer {
+func ==(lhs: ICustomer, rhs: ICustomer) -> Bool {
+ return lhs.technicalId == rhs.technicalId
+}
+
+func !=(lhs: ICustomer, rhs: ICustomer) -> Bool {
+ return lhs.technicalId != rhs.technicalId
+}
+
+func ==(lhs: IBankAccount, rhs: IBankAccount) -> Bool {
+ return lhs.technicalId == rhs.technicalId
+}
+
+func !=(lhs: IBankAccount, rhs: IBankAccount) -> Bool {
+ return lhs.technicalId != rhs.technicalId
+}
+
+func ==(lhs: IAccountTransaction, rhs: IAccountTransaction) -> Bool {
+ return lhs.technicalId == rhs.technicalId
+}
+
+func !=(lhs: IAccountTransaction, rhs: IAccountTransaction) -> Bool {
+ return lhs.technicalId != rhs.technicalId
+}
+
+
+extension Array where Element == ICustomer {
func sumBalances() -> CommonBigDecimal {
return CommonBigDecimal(decimal_: self.map { $0.balance.decimal }.sum())
@@ -97,7 +122,7 @@ extension Array where Element == Customer {
}
-extension Array where Element == AccountTransaction {
+extension Array where Element == IAccountTransaction {
func sumAmounts() -> CommonBigDecimal {
return CommonBigDecimal(decimal_: self.map { $0.amount.decimal }.sum())
diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/AppData.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/AppData.swift
index f4d568f5..98fb3c7d 100644
--- a/ui/BankingiOSApp/BankingiOSApp/persistence/AppData.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/persistence/AppData.swift
@@ -6,8 +6,8 @@ class AppData : ObservableObject {
@Inject private var presenter: BankingPresenterSwift
- @Published var banks: [Customer] = []
- @Published var banksSorted: [Customer] = []
+ @Published var banks: [ICustomer] = []
+ @Published var banksSorted: [ICustomer] = []
@Published var hasAtLeastOneAccountBeenAdded: Bool = false
@@ -23,7 +23,7 @@ class AppData : ObservableObject {
}
- private func setFieldsForBanks(_ banks: [Customer]) {
+ private func setFieldsForBanks(_ banks: [ICustomer]) {
self.banks = presenter.customers
self.banksSorted = banks.sortedByDisplayIndex()
diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift
index 5450aa7c..707798a2 100644
--- a/ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift
@@ -19,7 +19,7 @@ class CoreDataBankingPersistence: IBankingPersistence, IRemitteeSearcher {
}
- func saveOrUpdateAccount(customer: Customer, allCustomers: [Customer]) {
+ func saveOrUpdateAccount(customer: ICustomer, allCustomers: [ICustomer]) {
do {
let mapped = mapper.map(customer, context)
@@ -35,7 +35,7 @@ class CoreDataBankingPersistence: IBankingPersistence, IRemitteeSearcher {
}
}
- private func setIds(_ customer: Customer, _ mappedCustomer: PersistedCustomer) {
+ private func setIds(_ customer: ICustomer, _ mappedCustomer: PersistedCustomer) {
customer.technicalId = mappedCustomer.objectIDAsString
for account in customer.accounts {
@@ -58,7 +58,7 @@ class CoreDataBankingPersistence: IBankingPersistence, IRemitteeSearcher {
}
- func readPersistedAccounts_() -> [Customer] {
+ func readPersistedAccounts_() -> [ICustomer] {
var customers: [PersistedCustomer] = []
do {
@@ -73,7 +73,7 @@ class CoreDataBankingPersistence: IBankingPersistence, IRemitteeSearcher {
return customers.map( { mapper.map($0) } )
}
- func deleteAccount(customer: Customer, allCustomers: [Customer]) {
+ func deleteAccount(customer: ICustomer, allCustomers: [ICustomer]) {
do {
let mapped = mapper.map(customer, context)
@@ -85,7 +85,7 @@ class CoreDataBankingPersistence: IBankingPersistence, IRemitteeSearcher {
}
}
- func saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: [AccountTransaction]) {
+ func saveOrUpdateAccountTransactions(bankAccount: IBankAccount, transactions: [IAccountTransaction]) {
if let persistedAccount = context.objectByID(bankAccount.technicalId) as? PersistedBankAccount {
for transaction in transactions {
if transaction.technicalId.isCoreDataId == false { // TODO: or also update already persisted transactions?
@@ -96,7 +96,7 @@ class CoreDataBankingPersistence: IBankingPersistence, IRemitteeSearcher {
transaction.technicalId = mappedTransaction.objectIDAsString
} catch {
- NSLog("Could not save transaction \(transaction.transactionIdentifier) of account \(bankAccount.displayName): \(error)")
+ NSLog("Could not save transaction \(transaction.buildTransactionIdentifier()) of account \(bankAccount.displayName): \(error)")
}
}
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/EnterTanState.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/EnterTanState.swift
index ce00f270..db576d11 100644
--- a/ui/BankingiOSApp/BankingiOSApp/persistence/EnterTanState.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/persistence/EnterTanState.swift
@@ -6,14 +6,14 @@ class EnterTanState : Identifiable {
let id: Foundation.UUID = UUID()
- let customer: Customer
+ let customer: ICustomer
let tanChallenge: TanChallenge
let callback: (EnterTanResult) -> Void
- init(_ customer: Customer, _ tanChallenge: TanChallenge, _ callback: @escaping (EnterTanResult) -> Void) {
+ init(_ customer: ICustomer, _ tanChallenge: TanChallenge, _ callback: @escaping (EnterTanResult) -> Void) {
self.customer = customer
self.tanChallenge = tanChallenge
self.callback = callback
diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift
index dc3454ce..c5c8cfec 100644
--- a/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift
@@ -5,7 +5,7 @@ import BankingUiSwift
class Mapper {
- func map(_ customer: PersistedCustomer) -> Customer {
+ func map(_ customer: PersistedCustomer) -> ICustomer {
let mapped = Customer(bankCode: map(customer.bankCode), customerId: map(customer.customerId), password: map(customer.password), finTsServerAddress: map(customer.finTsServerAddress), bankName: map(customer.bankName), bic: map(customer.bic), customerName: map(customer.customerName), userId: map(customer.userId), iconUrl: customer.iconUrl, accounts: [])
mapped.userSetDisplayName = customer.userSetDisplayName
@@ -23,7 +23,7 @@ class Mapper {
return mapped
}
- func map(_ customer: Customer, _ context: NSManagedObjectContext) -> PersistedCustomer {
+ func map(_ customer: ICustomer, _ context: NSManagedObjectContext) -> PersistedCustomer {
let mapped = context.objectByID(customer.technicalId) ?? PersistedCustomer(context: context)
mapped.bankCode = customer.bankCode
@@ -50,11 +50,11 @@ class Mapper {
}
- func map(_ customer: Customer, _ accounts: [PersistedBankAccount]?) -> [BankAccount] {
+ func map(_ customer: ICustomer, _ accounts: [PersistedBankAccount]?) -> [IBankAccount] {
return accounts?.map( { map(customer, $0) } ) ?? []
}
- func map(_ customer: Customer, _ account: PersistedBankAccount) -> BankAccount {
+ func map(_ customer: ICustomer, _ account: PersistedBankAccount) -> IBankAccount {
let mapped = BankAccount(customer: customer, identifier: map(account.identifier), accountHolderName: map(account.accountHolderName), iban: account.iban, subAccountNumber: account.subAccountNumber, customerId: map(account.customerId), balance: map(account.balance), currency: map(account.currency), type: map(account.type), productName: account.productName, accountLimit: account.accountLimit, lastRetrievedTransactionsTimestamp: map(account.lastRetrievedTransactionsTimestamp), supportsRetrievingAccountTransactions: account.supportsRetrievingAccountTransactions, supportsRetrievingBalance: account.supportsRetrievingBalance, supportsTransferringMoney: account.supportsTransferringMoney, supportsInstantPaymentMoneyTransfer: account.supportsInstantPaymentMoneyTransfer, bookedTransactions: [], unbookedTransactions: [])
mapped.haveAllTransactionsBeenFetched = account.haveAllTransactionsBeenFetched
@@ -69,11 +69,11 @@ class Mapper {
return mapped
}
- func map(_ customer: PersistedCustomer, _ accounts: [BankAccount], _ context: NSManagedObjectContext) -> [PersistedBankAccount] {
+ func map(_ customer: PersistedCustomer, _ accounts: [IBankAccount], _ context: NSManagedObjectContext) -> [PersistedBankAccount] {
return accounts.map( { map(customer, $0, context) } )
}
- func map(_ customer: PersistedCustomer, _ account: BankAccount, _ context: NSManagedObjectContext) -> PersistedBankAccount {
+ func map(_ customer: PersistedCustomer, _ account: IBankAccount, _ context: NSManagedObjectContext) -> PersistedBankAccount {
let mapped = context.objectByID(account.technicalId) ?? PersistedBankAccount(context: context)
mapped.customer = customer
@@ -136,11 +136,11 @@ class Mapper {
}
- func map(_ account: BankAccount, _ transactions: Set?) -> [AccountTransaction] {
+ func map(_ account: IBankAccount, _ transactions: Set?) -> [IAccountTransaction] {
return transactions?.map( {map(account, $0) } ) ?? []
}
- func map(_ account: BankAccount, _ transaction: PersistedAccountTransaction) -> AccountTransaction {
+ func map(_ account: IBankAccount, _ transaction: PersistedAccountTransaction) -> IAccountTransaction {
let mapped = AccountTransaction(bankAccount: account, amount: map(transaction.amount), currency: map(transaction.currency), unparsedUsage: map(transaction.unparsedUsage), bookingDate: map(transaction.bookingDate), otherPartyName: transaction.otherPartyName, otherPartyBankCode: transaction.otherPartyBankCode, otherPartyAccountId: transaction.otherPartyAccountId, bookingText: transaction.bookingText, valueDate: map(transaction.valueDate), statementNumber: Int32(transaction.statementNumber), sequenceNumber: map(transaction.sequenceNumber), openingBalance: map(transaction.openingBalance), closingBalance: map(transaction.closingBalance), endToEndReference: transaction.endToEndReference, customerReference: transaction.customerReference, mandateReference: transaction.mandateReference, creditorIdentifier: transaction.creditorIdentifier, originatorsIdentificationCode: transaction.originatorsIdentificationCode, compensationAmount: transaction.compensationAmount, originalAmount: transaction.originalAmount, sepaUsage: transaction.sepaUsage, deviantOriginator: transaction.deviantOriginator, deviantRecipient: transaction.deviantRecipient, usageWithNoSpecialType: transaction.usageWithNoSpecialType, primaNotaNumber: transaction.primaNotaNumber, textKeySupplement: transaction.textKeySupplement, currencyType: transaction.currencyType, bookingKey: map(transaction.bookingKey), referenceForTheAccountOwner: map(transaction.referenceForTheAccountOwner), referenceOfTheAccountServicingInstitution: transaction.referenceOfTheAccountServicingInstitution, supplementaryDetails: transaction.supplementaryDetails, transactionReferenceNumber: map(transaction.transactionReferenceNumber), relatedReferenceNumber: transaction.relatedReferenceNumber)
mapped.technicalId = transaction.objectIDAsString
@@ -149,11 +149,11 @@ class Mapper {
}
- func map(_ account: PersistedBankAccount, _ transactions: [AccountTransaction], _ context: NSManagedObjectContext) -> [PersistedAccountTransaction] {
+ func map(_ account: PersistedBankAccount, _ transactions: [IAccountTransaction], _ context: NSManagedObjectContext) -> [PersistedAccountTransaction] {
return transactions.map( {map(account, $0, context) } )
}
- func map(_ account: PersistedBankAccount, _ transaction: AccountTransaction, _ context: NSManagedObjectContext) -> PersistedAccountTransaction {
+ func map(_ account: PersistedBankAccount, _ transaction: IAccountTransaction, _ context: NSManagedObjectContext) -> PersistedAccountTransaction {
let mapped = context.objectByID(transaction.technicalId) ?? PersistedAccountTransaction(context: context)
mapped.account = account
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/Messages.swift b/ui/BankingiOSApp/BankingiOSApp/ui/Messages.swift
index dc077755..59918658 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/Messages.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/Messages.swift
@@ -11,7 +11,7 @@ extension Message {
secondaryButton: .cancel())
}
- static func createAskUserToDeleteAccountMessage(_ bank: Customer, _ deleteAccount: @escaping (Customer) -> Void) -> Message {
+ static func createAskUserToDeleteAccountMessage(_ bank: ICustomer, _ deleteAccount: @escaping (ICustomer) -> Void) -> Message {
return Message(title: Text("Really delete account '\(bank.displayName)'?"),
message: Text("All data for this account will be permanently deleted locally."),
primaryButton: .destructive(Text("Delete"), action: { deleteAccount(bank) } ),
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/SwiftUiRouter.swift b/ui/BankingiOSApp/BankingiOSApp/ui/SwiftUiRouter.swift
index 0c16df94..842e8aa3 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/SwiftUiRouter.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/SwiftUiRouter.swift
@@ -9,7 +9,7 @@ class SwiftUiRouter : IRouter {
}
- func getTanFromUserFromNonUiThread(customer: Customer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: @escaping (EnterTanResult) -> Void) {
+ func getTanFromUserFromNonUiThread(customer: ICustomer, tanChallenge: TanChallenge, presenter: BankingPresenter, callback: @escaping (EnterTanResult) -> Void) {
let enterTanState = EnterTanState(customer, tanChallenge, callback)
SceneDelegate.navigateToView(EnterTanDialog(enterTanState))
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountTransactionsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountTransactionsDialog.swift
index 4b079fd9..c31f15af 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountTransactionsDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountTransactionsDialog.swift
@@ -9,7 +9,7 @@ struct AccountTransactionsDialog: View {
private let title: String
- private let allTransactions: [AccountTransaction]
+ private let allTransactions: [IAccountTransaction]
private let balanceOfAllTransactions: CommonBigDecimal
@@ -20,10 +20,10 @@ struct AccountTransactionsDialog: View {
@State private var showFetchAllTransactionsOverlay: Bool
- @State private var accountsForWhichNotAllTransactionsHaveBeenFetched: [BankAccount]
+ @State private var accountsForWhichNotAllTransactionsHaveBeenFetched: [IBankAccount]
- @State private var filteredTransactions: [AccountTransaction]
+ @State private var filteredTransactions: [IAccountTransaction]
@State private var balanceOfFilteredTransactions: CommonBigDecimal
@@ -45,7 +45,7 @@ struct AccountTransactionsDialog: View {
@Inject private var presenter: BankingPresenterSwift
- init(allBanks: [Customer]) {
+ init(allBanks: [ICustomer]) {
let allAccounts = allBanks.flatMap { $0.accounts }
self.init("All accounts", allAccounts.flatMap { $0.bookedTransactions }, allBanks.sumBalances(), allAccounts.filter { $0.haveAllTransactionsBeenFetched == false })
@@ -53,19 +53,19 @@ struct AccountTransactionsDialog: View {
presenter.selectedAllBankAccounts()
}
- init(bank: Customer) {
+ init(bank: ICustomer) {
self.init(bank.displayName, bank.accounts.flatMap { $0.bookedTransactions }, bank.balance, bank.accounts.filter { $0.haveAllTransactionsBeenFetched == false })
presenter.selectedAccount(customer: bank)
}
- init(account: BankAccount) {
+ init(account: IBankAccount) {
self.init(account.displayName, account.bookedTransactions, account.balance, account.haveAllTransactionsBeenFetched ? [] : [account])
presenter.selectedBankAccount(bankAccount: account)
}
- fileprivate init(_ title: String, _ transactions: [AccountTransaction], _ balance: CommonBigDecimal, _ accountsForWhichNotAllTransactionsHaveBeenFetched: [BankAccount] = []) {
+ fileprivate init(_ title: String, _ transactions: [IAccountTransaction], _ balance: CommonBigDecimal, _ accountsForWhichNotAllTransactionsHaveBeenFetched: [IBankAccount] = []) {
self.title = title
self.allTransactions = transactions
@@ -74,7 +74,7 @@ struct AccountTransactionsDialog: View {
self.balanceOfAllTransactions = balance
self._balanceOfFilteredTransactions = State(initialValue: balance)
- self.areMoreThanOneBanksTransactionsDisplayed = Set(allTransactions.compactMap { $0.bankAccount }.compactMap { $0.customer }).count > 1
+ self.areMoreThanOneBanksTransactionsDisplayed = Set(allTransactions.compactMap { $0.bankAccount }.compactMap { $0.customer as! Customer }).count > 1
_accountsForWhichNotAllTransactionsHaveBeenFetched = State(initialValue: accountsForWhichNotAllTransactionsHaveBeenFetched)
_haveAllTransactionsBeenFetched = State(initialValue: accountsForWhichNotAllTransactionsHaveBeenFetched.isEmpty)
@@ -173,7 +173,7 @@ struct AccountTransactionsDialog: View {
}
}
- private func fetchAllTransactions(_ accounts: [BankAccount]) {
+ private func fetchAllTransactions(_ accounts: [IBankAccount]) {
accounts.forEach { account in
presenter.fetchAllAccountTransactionsAsync(bankAccount: account, callback: self.handleGetAllTransactionsResult)
}
@@ -224,7 +224,7 @@ struct AccountTransactionsDialog: View {
struct AccountTransactionsDialog_Previews: PreviewProvider {
static var previews: some View {
AccountTransactionsDialog(previewBanks[0].displayName, [
- AccountTransaction(bankAccount: previewBanks[0].accounts[0], amount: CommonBigDecimal(double: 1234.56), currency: "€", unparsedUsage: "Usage", bookingDate: CommonDate(year: 2020, month: 5, day: 7), otherPartyName: "Marieke Musterfrau", otherPartyBankCode: nil, otherPartyAccountId: nil, bookingText: "SEPA Ueberweisung", valueDate: CommonDate(year: 2020, month: 5, day: 7))
+ AccountTransaction(bankAccount: previewBanks[0].accounts[0] as! BankAccount, amount: CommonBigDecimal(double: 1234.56), currency: "€", unparsedUsage: "Usage", bookingDate: CommonDate(year: 2020, month: 5, day: 7), otherPartyName: "Marieke Musterfrau", otherPartyBankCode: nil, otherPartyAccountId: nil, bookingText: "SEPA Ueberweisung", valueDate: CommonDate(year: 2020, month: 5, day: 7))
],
CommonBigDecimal(double: 84.12))
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountsDialog.swift
index 49a89d2f..97ea8122 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountsDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AccountsDialog.swift
@@ -22,7 +22,7 @@ struct AccountsDialog: View {
Form {
AllBanksListItem(banks: data.banks)
- ForEach(data.banks.sortedByDisplayIndex()) { bank in
+ ForEach(data.banks.sortedByDisplayIndex(), id: \.technicalId) { bank in
BankListItem(bank: bank)
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AddAccountDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AddAccountDialog.swift
index abb71bdf..336f396d 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AddAccountDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/AddAccountDialog.swift
@@ -85,7 +85,7 @@ struct AddAccountDialog: View {
isTryingToAddAccount = true
UIApplication.hideKeyboard()
- presenter.addAccountAsync(bankInfo: bank, customerId: customerId, pin: password) { (response) in
+ presenter.addAccountAsync(bankInfo: bank, customerId: customerId, password: password) { (response) in
self.handleAddAccountResponse(response)
}
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankAccountSettingsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankAccountSettingsDialog.swift
index d78aaf5a..8d269cd6 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankAccountSettingsDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankAccountSettingsDialog.swift
@@ -9,7 +9,7 @@ struct BankAccountSettingsDialog: View {
@Inject private var presenter: BankingPresenterSwift
- private let account: BankAccount
+ private let account: IBankAccount
@State private var displayName: String
@@ -21,7 +21,7 @@ struct BankAccountSettingsDialog: View {
}
- init(_ account: BankAccount) {
+ init(_ account: IBankAccount) {
self.account = account
_displayName = State(initialValue: account.displayName)
@@ -79,8 +79,8 @@ struct BankAccountSettingsDialog: View {
private func donePressed() {
if hasUnsavedData {
account.userSetDisplayName = displayName
-
- presenter.accountUpdated(account: account.customer)
+
+ presenter.accountUpdated(account: account)
}
closeDialog()
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift
index e19a1046..95ab0195 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift
@@ -10,7 +10,7 @@ struct BankSettingsDialog: View {
@Inject private var presenter: BankingPresenterSwift
- private let bank: Customer
+ private let bank: ICustomer
@State private var displayName: String
@@ -19,7 +19,7 @@ struct BankSettingsDialog: View {
@State private var selectedTanProcedure: TanProcedure?
- @State private var accountsSorted: [BankAccount]
+ @State private var accountsSorted: [IBankAccount]
@State private var askUserToDeleteAccountOrSaveChangesMessage: Message? = nil
@@ -32,7 +32,7 @@ struct BankSettingsDialog: View {
}
- init(_ bank: Customer) {
+ init(_ bank: ICustomer) {
self.bank = bank
_displayName = State(initialValue: bank.displayName)
@@ -75,7 +75,7 @@ struct BankSettingsDialog: View {
}
Section(header: SectionHeaderWithRightAlignedEditButton("Accounts")) {
- ForEach(accountsSorted) { account in
+ ForEach(accountsSorted, id: \.technicalId) { account in
NavigationLink(destination: LazyView(BankAccountSettingsDialog(account))) {
Text(account.displayName)
}
@@ -102,7 +102,7 @@ struct BankSettingsDialog: View {
func reorderAccounts(from source: IndexSet, to destination: Int) {
accountsSorted = accountsSorted.reorder(from: source, to: destination)
- presenter.accountUpdated(account: bank)
+ presenter.accountDisplayIndexUpdated(account: bank)
}
@@ -110,7 +110,7 @@ struct BankSettingsDialog: View {
self.askUserToDeleteAccountOrSaveChangesMessage = Message.createAskUserToDeleteAccountMessage(bank, self.deleteAccount)
}
- func deleteAccount(bank: Customer) {
+ func deleteAccount(bank: ICustomer) {
presenter.deleteAccount(customer: bank)
closeDialog()
@@ -135,7 +135,7 @@ struct BankSettingsDialog: View {
bank.selectedTanProcedure = selectedTanProcedure
- presenter.accountUpdated(account: bank)
+ presenter.accountUpdated(bank: bank)
}
closeDialog()
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/EnterTanDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/EnterTanDialog.swift
index a464e6ee..5d276e14 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/EnterTanDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/EnterTanDialog.swift
@@ -11,7 +11,7 @@ struct EnterTanDialog: View {
private var tanChallenge: TanChallenge
- private var customer: Customer
+ private var customer: ICustomer
private var customersTanMedia: [TanMedium] = []
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/SettingsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/SettingsDialog.swift
index 2efbf256..b94cd013 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/SettingsDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/SettingsDialog.swift
@@ -18,7 +18,7 @@ struct SettingsDialog: View {
Form {
Section(header: SectionHeaderWithRightAlignedEditButton("Bank Credentials", isEditButtonEnabled: data.hasAtLeastOneAccountBeenAdded),
footer: footer) {
- ForEach(data.banksSorted) { bank in
+ ForEach(data.banksSorted, id: \.technicalId) { bank in
NavigationLink(destination: LazyView(BankSettingsDialog(bank))) {
IconedTitleView(bank)
}
@@ -68,11 +68,11 @@ struct SettingsDialog: View {
}
}
- func askUserToDeleteAccount(_ bankToDelete: Customer) {
+ func askUserToDeleteAccount(_ bankToDelete: ICustomer) {
self.askToDeleteAccountMessage = Message.createAskUserToDeleteAccountMessage(bankToDelete, self.deleteAccountWithSecurityChecks)
}
- func deleteAccountWithSecurityChecks(_ bankToDelete: Customer) {
+ func deleteAccountWithSecurityChecks(_ bankToDelete: ICustomer) {
// don't know why but when deleting last bank application crashes if we don't delete bank async
DispatchQueue.main.async {
if self.presenter.customers.count == 1 {
@@ -88,7 +88,7 @@ struct SettingsDialog: View {
}
}
- private func deleteAccount(_ bankToDelete: Customer) {
+ private func deleteAccount(_ bankToDelete: ICustomer) {
self.presenter.deleteAccount(customer: bankToDelete)
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/TransferMoneyDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/TransferMoneyDialog.swift
index 383dc60a..35e2eb07 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/TransferMoneyDialog.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/TransferMoneyDialog.swift
@@ -10,7 +10,7 @@ struct TransferMoneyDialog: View {
private var showAccounts = false
- private var accountsSupportingTransferringMoney: [BankAccount] = []
+ private var accountsSupportingTransferringMoney: [IBankAccount] = []
@State private var selectedAccountIndex = 0
@@ -52,7 +52,7 @@ struct TransferMoneyDialog: View {
@State private var didJustCorrectEnteredValue = false
- private var account: BankAccount? {
+ private var account: IBankAccount? {
if (self.selectedAccountIndex < self.accountsSupportingTransferringMoney.count) {
return self.accountsSupportingTransferringMoney[selectedAccountIndex]
}
@@ -411,6 +411,7 @@ struct TransferMoneyDialog: View {
self.transferMoneyResponseMessage = Message(message: Text("Could not transfer \(data.amount) \("€") to \(data.creditorName). Error: \(response.errorToShowToUser ?? "")."))
}
}
+
}
struct TransferMoneyDialog_Previews: PreviewProvider {
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/IconedTitleView.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/IconedTitleView.swift
index 071144a7..d69f0751 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/views/IconedTitleView.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/IconedTitleView.swift
@@ -13,11 +13,11 @@ struct IconedTitleView: View {
private var titleFont: Font?
- init(_ bank: Customer, titleFont: Font? = nil) {
+ init(_ bank: ICustomer, titleFont: Font? = nil) {
self.init(accountTitle: bank.displayName, iconUrl: bank.iconUrl, defaultIconName: Styles.AccountFallbackIcon, titleFont: titleFont)
}
- init(_ account: BankAccount, titleFont: Font? = nil) {
+ init(_ account: IBankAccount, titleFont: Font? = nil) {
self.init(accountTitle: account.displayName, iconUrl: account.customer.iconUrl, defaultIconName: Styles.AccountFallbackIcon, titleFont: titleFont)
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AccountTransactionListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AccountTransactionListItem.swift
index 4249945f..6d34145c 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AccountTransactionListItem.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AccountTransactionListItem.swift
@@ -13,7 +13,7 @@ struct AccountTransactionListItem: View {
}()
- private let transaction: AccountTransaction
+ private let transaction: IAccountTransaction
private let areMoreThanOneBanksTransactionsDisplayed: Bool
@@ -21,7 +21,7 @@ struct AccountTransactionListItem: View {
@Inject private var presenter: BankingPresenterSwift
- init(_ transaction: AccountTransaction, _ areMoreThanOneBanksTransactionsDisplayed: Bool) {
+ init(_ transaction: IAccountTransaction, _ areMoreThanOneBanksTransactionsDisplayed: Bool) {
self.transaction = transaction
self.areMoreThanOneBanksTransactionsDisplayed = areMoreThanOneBanksTransactionsDisplayed
@@ -82,7 +82,7 @@ struct AccountTransactionListItem: View {
}
- private func getTransactionLabel(_ transaction: AccountTransaction) -> String {
+ private func getTransactionLabel(_ transaction: IAccountTransaction) -> String {
if transaction.bookingText?.localizedCaseInsensitiveCompare("Bargeldauszahlung") == ComparisonResult.orderedSame {
return transaction.bookingText ?? ""
}
@@ -98,6 +98,6 @@ struct AccountTransactionListItem: View {
struct AccountTransactionListItem_Previews: PreviewProvider {
static var previews: some View {
- AccountTransactionListItem(AccountTransaction(bankAccount: previewBanks[0].accounts[0], otherPartyName: "Marieke Musterfrau", unparsedUsage: "Vielen Dank für Ihre Mühen", amount: CommonBigDecimal(double: 1234.56), valueDate: CommonDate(year: 2020, month: .march, day_: 27), bookingText: "SEPA Überweisung"), false)
+ AccountTransactionListItem(AccountTransaction(bankAccount: previewBanks[0].accounts[0] as! BankAccount, otherPartyName: "Marieke Musterfrau", unparsedUsage: "Vielen Dank für Ihre Mühen", amount: CommonBigDecimal(double: 1234.56), valueDate: CommonDate(year: 2020, month: .march, day_: 27), bookingText: "SEPA Überweisung"), false)
}
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AllBanksListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AllBanksListItem.swift
index 6b535ef0..da258eba 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AllBanksListItem.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/AllBanksListItem.swift
@@ -4,7 +4,7 @@ import BankingUiSwift
struct AllBanksListItem: View {
- let banks: [Customer]
+ let banks: [ICustomer]
@State private var navigateToAccountTransactionsDialog = false
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankAccountListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankAccountListItem.swift
index 036c636f..38db6028 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankAccountListItem.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankAccountListItem.swift
@@ -4,7 +4,7 @@ import BankingUiSwift
struct BankAccountListItem : View {
- let account: BankAccount
+ let account: IBankAccount
@State private var navigateToAccountTransactionsDialog = false
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankListItem.swift
index d0943af0..1451d9a6 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankListItem.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/listitems/BankListItem.swift
@@ -4,7 +4,7 @@ import BankingUiSwift
struct BankListItem : View {
- let bank: Customer
+ let bank: ICustomer
@State private var navigateToAccountTransactionsDialog = false
@@ -47,7 +47,7 @@ struct BankListItem : View {
}
- ForEach(bank.accountsSorted) { account in
+ ForEach(bank.accountsSorted, id: \.technicalId) { account in
BankAccountListItem(account: account)
}
.padding(.leading, Styles.AccountsIconWidth + Styles.DefaultSpaceBetweenIconAndText)
@@ -70,7 +70,7 @@ struct BankListItem : View {
).show()
}
- private func deleteAccount(_ bank: Customer) {
+ private func deleteAccount(_ bank: ICustomer) {
presenter.deleteAccount(customer: bank)
}
diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/tan/TanProcedurePicker.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/tan/TanProcedurePicker.swift
index c88b91bf..d9adcf06 100644
--- a/ui/BankingiOSApp/BankingiOSApp/ui/views/tan/TanProcedurePicker.swift
+++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/tan/TanProcedurePicker.swift
@@ -4,7 +4,7 @@ import BankingUiSwift
struct TanProcedurePicker: View {
- private let bank: Customer
+ private let bank: ICustomer
private let selectedTanProcedureChanged: (TanProcedure) -> Void
@@ -27,7 +27,7 @@ struct TanProcedurePicker: View {
}
- init(_ bank: Customer, _ initiallySelectedTanProcedure: TanProcedure? = nil, selectedTanProcedureChanged: @escaping (TanProcedure) -> Void) {
+ init(_ bank: ICustomer, _ initiallySelectedTanProcedure: TanProcedure? = nil, selectedTanProcedureChanged: @escaping (TanProcedure) -> Void) {
self.bank = bank
self.selectedTanProcedureChanged = selectedTanProcedureChanged
diff --git a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt
index 96d6e63b..2e99f5d7 100644
--- a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt
+++ b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt
@@ -2,9 +2,6 @@ package net.dankito.banking
import net.dankito.banking.ui.BankingClientCallback
import net.dankito.banking.ui.IBankingClient
-import net.dankito.banking.ui.model.Customer
-import net.dankito.banking.ui.model.BankAccount
-import net.dankito.banking.ui.model.MessageLogEntry
import net.dankito.banking.ui.model.parameters.GetTransactionsParameter
import net.dankito.banking.ui.model.parameters.TransferMoneyData
import net.dankito.banking.ui.model.responses.AddAccountResponse
@@ -20,13 +17,17 @@ import net.dankito.banking.fints.webclient.IWebClient
import net.dankito.banking.fints.webclient.KtorWebClient
import net.dankito.banking.extensions.toMoney
import net.dankito.banking.fints.response.client.FinTsClientResponse
+import net.dankito.banking.ui.model.*
+import net.dankito.banking.ui.model.MessageLogEntry
+import net.dankito.banking.ui.model.mapper.IModelCreator
import net.dankito.banking.util.ISerializer
import net.dankito.utils.multiplatform.File
import net.dankito.utils.multiplatform.log.LoggerFactory
open class fints4kBankingClient(
- protected val customer: Customer,
+ protected val customer: TypedCustomer,
+ protected val modelCreator: IModelCreator,
protected val dataFolder: File,
protected val serializer: ISerializer,
webClient: IWebClient = KtorWebClient(),
@@ -42,7 +43,7 @@ open class fints4kBankingClient(
}
- protected val mapper = net.dankito.banking.mapper.fints4kModelMapper()
+ protected val mapper = net.dankito.banking.mapper.fints4kModelMapper(modelCreator)
protected var didTryToGetAccountDataFromBank = false
@@ -74,7 +75,7 @@ open class fints4kBankingClient(
}
- override fun getTransactionsAsync(bankAccount: BankAccount, parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
+ override fun getTransactionsAsync(bankAccount: TypedBankAccount, parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
findAccountForBankAccount(bankAccount) { account, errorMessage ->
if (account == null) {
callback(GetTransactionsResponse(bankAccount, false, errorMessage))
@@ -90,13 +91,13 @@ open class fints4kBankingClient(
}
protected open fun doGetTransactionsAsync(parameter: net.dankito.banking.fints.model.GetTransactionsParameter,
- account: AccountData, bankAccount: BankAccount, callback: (GetTransactionsResponse) -> Unit) {
+ account: AccountData, bankAccount: TypedBankAccount, callback: (GetTransactionsResponse) -> Unit) {
client.getTransactionsAsync(parameter, account) { response ->
handleGetTransactionsResponse(bankAccount, response, callback)
}
}
- protected open fun handleGetTransactionsResponse(bankAccount: BankAccount, response: net.dankito.banking.fints.response.client.GetTransactionsResponse,
+ protected open fun handleGetTransactionsResponse(bankAccount: TypedBankAccount, response: net.dankito.banking.fints.response.client.GetTransactionsResponse,
callback: (GetTransactionsResponse) -> Unit) {
val mappedResponse = mapper.mapResponse(bankAccount, response)
@@ -132,12 +133,12 @@ open class fints4kBankingClient(
}
- override fun dataChanged(customer: Customer) {
+ override fun dataChanged(customer: TypedCustomer) {
mapper.mapChangesFromUiToClientModel(customer, bank)
}
- protected open fun findAccountForBankAccount(bankAccount: BankAccount, findAccountResult: (AccountData?, error: String?) -> Unit) {
+ protected open fun findAccountForBankAccount(bankAccount: TypedBankAccount, findAccountResult: (AccountData?, error: String?) -> Unit) {
val mappedAccount = mapper.findAccountForBankAccount(bank, bankAccount)
if (mappedAccount != null) {
@@ -157,12 +158,12 @@ open class fints4kBankingClient(
}
- protected open fun restoreDataOrMapFromUiModel(customer: Customer): BankData {
+ protected open fun restoreDataOrMapFromUiModel(customer: TypedCustomer): BankData {
return restoreData(customer) ?:
BankData(customer.bankCode, customer.customerId, customer.password, customer.finTsServerAddress, customer.bic, customer.bankName)
}
- protected open fun restoreData(customer: Customer): BankData? {
+ protected open fun restoreData(customer: TypedCustomer): BankData? {
try {
return serializer.deserializeObject(getFints4kClientDataFile(customer.bankCode, customer.customerId), BankData::class)
} catch (e: Exception) {
diff --git a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClientCreator.kt b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClientCreator.kt
index 1fa31c0b..87f061e0 100644
--- a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClientCreator.kt
+++ b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClientCreator.kt
@@ -5,25 +5,27 @@ import net.dankito.banking.ui.IBankingClient
import net.dankito.banking.ui.IBankingClientCreator
import net.dankito.banking.fints.webclient.IWebClient
import net.dankito.banking.fints.webclient.KtorWebClient
-import net.dankito.banking.ui.model.Customer
+import net.dankito.banking.ui.model.TypedCustomer
+import net.dankito.banking.ui.model.mapper.IModelCreator
import net.dankito.banking.util.IAsyncRunner
import net.dankito.banking.util.ISerializer
import net.dankito.utils.multiplatform.File
open class fints4kBankingClientCreator(
+ protected val modelCreator: IModelCreator,
protected val serializer: ISerializer,
protected val webClient: IWebClient = KtorWebClient()
) : IBankingClientCreator {
override fun createClient(
- customer: Customer,
+ customer: TypedCustomer,
dataFolder: File,
asyncRunner: IAsyncRunner,
callback: BankingClientCallback
): IBankingClient {
- return fints4kBankingClient(customer, dataFolder, serializer, webClient, callback = callback)
+ return fints4kBankingClient(customer, modelCreator, dataFolder, serializer, webClient, callback = callback)
}
}
\ No newline at end of file
diff --git a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt
index 157bf45b..75cec669 100644
--- a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt
+++ b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt
@@ -11,24 +11,24 @@ import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.
import net.dankito.banking.fints.model.AccountData
import net.dankito.banking.fints.model.AccountFeature
import net.dankito.banking.fints.model.BankData
-import net.dankito.banking.fints.model.Money
import net.dankito.banking.fints.response.client.FinTsClientResponse
import net.dankito.banking.fints.response.segments.AccountType
+import net.dankito.banking.ui.model.mapper.IModelCreator
-open class fints4kModelMapper {
+open class fints4kModelMapper(protected val modelCreator: IModelCreator) {
open fun mapResponse(response: FinTsClientResponse): BankingClientResponse {
return BankingClientResponse(response.isSuccessful, mapErrorToShowToUser(response), response.userCancelledAction)
}
- open fun mapResponse(customer: Customer, response: net.dankito.banking.fints.response.client.AddAccountResponse): AddAccountResponse {
+ open fun mapResponse(customer: TypedCustomer, response: net.dankito.banking.fints.response.client.AddAccountResponse): AddAccountResponse {
val balances = response.balances.mapKeys { findMatchingBankAccount(customer, it.key) }.filter { it.key != null }
- .mapValues { (it.value as Money).toBigDecimal() } as Map
+ .mapValues { it.value.toBigDecimal() } as Map
val bookedTransactions = response.bookedTransactions.associateBy { it.account }
- val mappedBookedTransactions = mutableMapOf>()
+ val mappedBookedTransactions = mutableMapOf