@actual-app/sync-server 25.4.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/.dockerignore +12 -0
  2. package/README.md +19 -0
  3. package/app.js +11 -0
  4. package/babel.config.json +3 -0
  5. package/bin/@actual-app/sync-server +55 -0
  6. package/docker/alpine.Dockerfile +62 -0
  7. package/docker/ubuntu.Dockerfile +63 -0
  8. package/docker-compose.yml +29 -0
  9. package/jest.config.json +19 -0
  10. package/jest.global-setup.js +101 -0
  11. package/jest.global-teardown.js +6 -0
  12. package/migrations/1694360000000-create-folders.js +25 -0
  13. package/migrations/1694360479680-create-account-db.js +30 -0
  14. package/migrations/1694362247011-create-secret-table.js +16 -0
  15. package/migrations/1702667624000-rename-nordigen-secrets.js +19 -0
  16. package/migrations/1718889148000-openid.js +41 -0
  17. package/migrations/1719409568000-multiuser.js +116 -0
  18. package/package.json +64 -0
  19. package/src/account-db.js +239 -0
  20. package/src/accounts/openid.js +361 -0
  21. package/src/accounts/password.js +149 -0
  22. package/src/app-account.js +155 -0
  23. package/src/app-admin.js +410 -0
  24. package/src/app-admin.test.js +381 -0
  25. package/src/app-gocardless/README.md +198 -0
  26. package/src/app-gocardless/app-gocardless.js +274 -0
  27. package/src/app-gocardless/bank-factory.js +91 -0
  28. package/src/app-gocardless/banks/abanca_caglesmm.js +22 -0
  29. package/src/app-gocardless/banks/abnamro_abnanl2a.js +57 -0
  30. package/src/app-gocardless/banks/american_express_aesudef1.js +40 -0
  31. package/src/app-gocardless/banks/bancsabadell_bsabesbbb.js +31 -0
  32. package/src/app-gocardless/banks/bank.interface.ts +51 -0
  33. package/src/app-gocardless/banks/bank_of_ireland_b365_bofiie2d.js +39 -0
  34. package/src/app-gocardless/banks/bankinter_bkbkesmm.js +24 -0
  35. package/src/app-gocardless/banks/belfius_gkccbebb.js +17 -0
  36. package/src/app-gocardless/banks/berliner_sparkasse_beladebexxx.js +61 -0
  37. package/src/app-gocardless/banks/bnp_be_gebabebb.js +73 -0
  38. package/src/app-gocardless/banks/cbc_cregbebb.js +34 -0
  39. package/src/app-gocardless/banks/commerzbank_cobadeff.js +51 -0
  40. package/src/app-gocardless/banks/danskebank_dabno22.js +39 -0
  41. package/src/app-gocardless/banks/direkt_heladef1822.js +18 -0
  42. package/src/app-gocardless/banks/easybank_bawaatww.js +50 -0
  43. package/src/app-gocardless/banks/entercard_swednokk.js +40 -0
  44. package/src/app-gocardless/banks/fortuneo_ftnofrp1xxx.js +46 -0
  45. package/src/app-gocardless/banks/hype_hyeeit22.js +74 -0
  46. package/src/app-gocardless/banks/ing_ingbrobu.js +70 -0
  47. package/src/app-gocardless/banks/ing_ingddeff.js +47 -0
  48. package/src/app-gocardless/banks/ing_pl_ingbplpw.js +46 -0
  49. package/src/app-gocardless/banks/integration-bank.js +115 -0
  50. package/src/app-gocardless/banks/isybank_itbbitmm.js +18 -0
  51. package/src/app-gocardless/banks/kbc_kredbebb.js +33 -0
  52. package/src/app-gocardless/banks/lhv-lhvbee22.js +36 -0
  53. package/src/app-gocardless/banks/mbank_retail_brexplpw.js +56 -0
  54. package/src/app-gocardless/banks/nationwide_naiagb21.js +46 -0
  55. package/src/app-gocardless/banks/nbg_ethngraaxxx.js +51 -0
  56. package/src/app-gocardless/banks/norwegian_xx_norwnok1.js +74 -0
  57. package/src/app-gocardless/banks/revolut_revolt21.js +37 -0
  58. package/src/app-gocardless/banks/sandboxfinance_sfin0000.js +28 -0
  59. package/src/app-gocardless/banks/seb_kort_bank_ab.js +58 -0
  60. package/src/app-gocardless/banks/seb_privat.js +29 -0
  61. package/src/app-gocardless/banks/sparnord_spnodk22.js +24 -0
  62. package/src/app-gocardless/banks/spk_karlsruhe_karsde66.js +61 -0
  63. package/src/app-gocardless/banks/spk_marburg_biedenkopf_heladef1mar.js +30 -0
  64. package/src/app-gocardless/banks/spk_worms_alzey_ried_malade51wor.js +19 -0
  65. package/src/app-gocardless/banks/ssk_dusseldorf_dussdeddxxx.js +50 -0
  66. package/src/app-gocardless/banks/swedbank_habalv22.js +47 -0
  67. package/src/app-gocardless/banks/tests/abanca_caglesmm.spec.js +21 -0
  68. package/src/app-gocardless/banks/tests/abnamro_abnanl2a.spec.js +61 -0
  69. package/src/app-gocardless/banks/tests/bancsabadell_bsabesbbb.spec.js +53 -0
  70. package/src/app-gocardless/banks/tests/belfius_gkccbebb.spec.js +22 -0
  71. package/src/app-gocardless/banks/tests/cbc_cregbebb.spec.js +34 -0
  72. package/src/app-gocardless/banks/tests/commerzbank_cobadeff.spec.js +110 -0
  73. package/src/app-gocardless/banks/tests/easybank_bawaatww.spec.js +54 -0
  74. package/src/app-gocardless/banks/tests/fortuneo_ftnofrp1xxx.spec.js +206 -0
  75. package/src/app-gocardless/banks/tests/ing_ingddeff.spec.js +302 -0
  76. package/src/app-gocardless/banks/tests/ing_pl_ingbplpw.spec.js +202 -0
  77. package/src/app-gocardless/banks/tests/integration_bank.spec.js +158 -0
  78. package/src/app-gocardless/banks/tests/kbc_kredbebb.spec.js +38 -0
  79. package/src/app-gocardless/banks/tests/lhv-lhvbee22.spec.js +68 -0
  80. package/src/app-gocardless/banks/tests/mbank_retail_brexplpw.spec.js +171 -0
  81. package/src/app-gocardless/banks/tests/nationwide_naiagb21.spec.js +105 -0
  82. package/src/app-gocardless/banks/tests/nbg_ethngraaxxx.spec.js +48 -0
  83. package/src/app-gocardless/banks/tests/revolut_revolt21.spec.js +42 -0
  84. package/src/app-gocardless/banks/tests/sandboxfinance_sfin0000.spec.js +133 -0
  85. package/src/app-gocardless/banks/tests/spk_marburg_biedenkopf_heladef1mar.spec.js +256 -0
  86. package/src/app-gocardless/banks/tests/ssk_dusseldorf_dussdeddxxx.spec.js +102 -0
  87. package/src/app-gocardless/banks/tests/swedbank_habalv22.spec.js +57 -0
  88. package/src/app-gocardless/banks/tests/virgin_nrnbgb22.spec.js +54 -0
  89. package/src/app-gocardless/banks/util/extract-payeeName-from-remittanceInfo.js +36 -0
  90. package/src/app-gocardless/banks/virgin_nrnbgb22.js +39 -0
  91. package/src/app-gocardless/errors.js +84 -0
  92. package/src/app-gocardless/gocardless-node.types.ts +497 -0
  93. package/src/app-gocardless/gocardless.types.ts +93 -0
  94. package/src/app-gocardless/link.html +18 -0
  95. package/src/app-gocardless/services/gocardless-service.js +620 -0
  96. package/src/app-gocardless/services/tests/fixtures.js +181 -0
  97. package/src/app-gocardless/services/tests/gocardless-service.spec.js +537 -0
  98. package/src/app-gocardless/tests/bank-factory.spec.js +20 -0
  99. package/src/app-gocardless/tests/utils.spec.js +162 -0
  100. package/src/app-gocardless/util/handle-error.js +16 -0
  101. package/src/app-gocardless/utils.js +45 -0
  102. package/src/app-openid.js +108 -0
  103. package/src/app-pluggyai/app-pluggyai.js +215 -0
  104. package/src/app-pluggyai/pluggyai-service.js +120 -0
  105. package/src/app-secrets.js +61 -0
  106. package/src/app-simplefin/app-simplefin.js +418 -0
  107. package/src/app-sync/errors.js +13 -0
  108. package/src/app-sync/services/files-service.js +243 -0
  109. package/src/app-sync/tests/services/files-service.test.js +250 -0
  110. package/src/app-sync/validation.js +77 -0
  111. package/src/app-sync.js +391 -0
  112. package/src/app-sync.test.js +877 -0
  113. package/src/app.js +145 -0
  114. package/src/config-types.ts +44 -0
  115. package/src/db.js +58 -0
  116. package/src/load-config.js +307 -0
  117. package/src/migrations.js +36 -0
  118. package/src/run-migrations.js +8 -0
  119. package/src/scripts/disable-openid.js +44 -0
  120. package/src/scripts/enable-openid.js +53 -0
  121. package/src/scripts/health-check.js +23 -0
  122. package/src/scripts/reset-password.js +51 -0
  123. package/src/secrets.test.js +83 -0
  124. package/src/services/secrets-service.js +94 -0
  125. package/src/services/user-service.js +272 -0
  126. package/src/sql/messages.sql +9 -0
  127. package/src/sync-simple.js +95 -0
  128. package/src/util/hash.js +5 -0
  129. package/src/util/middlewares.js +62 -0
  130. package/src/util/paths.js +13 -0
  131. package/src/util/payee-name.js +45 -0
  132. package/src/util/prompt.js +88 -0
  133. package/src/util/title/index.js +59 -0
  134. package/src/util/title/lower-case.js +93 -0
  135. package/src/util/title/specials.js +21 -0
  136. package/src/util/validate-user.js +68 -0
  137. package/tsconfig.json +21 -0
@@ -0,0 +1,30 @@
1
+ import Fallback from './integration-bank.js';
2
+
3
+ /** @type {import('./bank.interface.js').IBank} */
4
+ export default {
5
+ ...Fallback,
6
+
7
+ institutionIds: ['SPK_MARBURG_BIEDENKOPF_HELADEF1MAR'],
8
+
9
+ normalizeTransaction(transaction, booked) {
10
+ const editedTrans = { ...transaction };
11
+
12
+ let remittanceInformationUnstructured;
13
+
14
+ if (transaction.remittanceInformationUnstructured) {
15
+ remittanceInformationUnstructured =
16
+ transaction.remittanceInformationUnstructured;
17
+ } else if (transaction.remittanceInformationStructured) {
18
+ remittanceInformationUnstructured =
19
+ transaction.remittanceInformationStructured;
20
+ } else if (transaction.remittanceInformationStructuredArray?.length > 0) {
21
+ remittanceInformationUnstructured =
22
+ transaction.remittanceInformationStructuredArray?.join(' ');
23
+ }
24
+
25
+ editedTrans.remittanceInformationUnstructured =
26
+ remittanceInformationUnstructured;
27
+
28
+ return Fallback.normalizeTransaction(transaction, booked, editedTrans);
29
+ },
30
+ };
@@ -0,0 +1,19 @@
1
+ import Fallback from './integration-bank.js';
2
+
3
+ /** @type {import('./bank.interface.js').IBank} */
4
+ export default {
5
+ ...Fallback,
6
+
7
+ institutionIds: ['SPK_WORMS_ALZEY_RIED_MALADE51WOR'],
8
+
9
+ normalizeTransaction(transaction, booked) {
10
+ const editedTrans = { ...transaction };
11
+
12
+ editedTrans.remittanceInformationUnstructured =
13
+ transaction.remittanceInformationUnstructured ??
14
+ transaction.remittanceInformationStructured ??
15
+ transaction.remittanceInformationStructuredArray?.join(' ');
16
+
17
+ return Fallback.normalizeTransaction(transaction, booked, editedTrans);
18
+ },
19
+ };
@@ -0,0 +1,50 @@
1
+ import Fallback from './integration-bank.js';
2
+
3
+ /** @type {import('./bank.interface.js').IBank} */
4
+ export default {
5
+ ...Fallback,
6
+
7
+ institutionIds: ['SSK_DUSSELDORF_DUSSDEDDXXX'],
8
+
9
+ normalizeTransaction(transaction, booked) {
10
+ const editedTrans = { ...transaction };
11
+
12
+ // If the transaction is not booked yet by the bank, don't import it.
13
+ // Reason being that the transaction doesn't have the information yet
14
+ // to make the payee and notes field be of any use. It's filled with
15
+ // a placeholder text and wouldn't be corrected on the next sync.
16
+ if (!booked) {
17
+ console.debug(
18
+ 'Skipping unbooked transaction:',
19
+ transaction.transactionId,
20
+ );
21
+ return null;
22
+ }
23
+
24
+ // Prioritize unstructured information, falling back to structured formats
25
+ let remittanceInformationUnstructured =
26
+ transaction.remittanceInformationUnstructured ??
27
+ transaction.remittanceInformationStructured ??
28
+ transaction.remittanceInformationStructuredArray?.join(' ');
29
+
30
+ if (transaction.additionalInformation) {
31
+ remittanceInformationUnstructured = [
32
+ remittanceInformationUnstructured,
33
+ transaction.additionalInformation,
34
+ ]
35
+ .filter(Boolean)
36
+ .join(' ');
37
+ }
38
+
39
+ const usefulCreditorName =
40
+ transaction.ultimateCreditor ||
41
+ transaction.creditorName ||
42
+ transaction.debtorName;
43
+
44
+ editedTrans.creditorName = usefulCreditorName;
45
+ editedTrans.remittanceInformationUnstructured =
46
+ remittanceInformationUnstructured;
47
+
48
+ return Fallback.normalizeTransaction(transaction, booked, editedTrans);
49
+ },
50
+ };
@@ -0,0 +1,47 @@
1
+ import d from 'date-fns';
2
+
3
+ import Fallback from './integration-bank.js';
4
+
5
+ /** @type {import('./bank.interface.js').IBank} */
6
+ export default {
7
+ ...Fallback,
8
+
9
+ institutionIds: ['SWEDBANK_HABALV22'],
10
+
11
+ /**
12
+ * The actual transaction date for card transactions is only available in the remittanceInformationUnstructured field when the transaction is booked.
13
+ */
14
+ normalizeTransaction(transaction, booked) {
15
+ const editedTrans = { ...transaction };
16
+
17
+ const isCardTransaction =
18
+ transaction.remittanceInformationUnstructured?.startsWith('PIRKUMS');
19
+
20
+ if (isCardTransaction) {
21
+ if (!booked && !transaction.creditorName) {
22
+ const creditorNameMatch =
23
+ transaction.remittanceInformationUnstructured?.match(
24
+ /PIRKUMS [\d*]+ \d{2}\.\d{2}\.\d{2} \d{2}:\d{2} [\d.]+ \w{3} \(\d+\) (.+)/,
25
+ );
26
+
27
+ if (creditorNameMatch) {
28
+ editedTrans.creditorName = creditorNameMatch[1];
29
+ }
30
+ }
31
+
32
+ const dateMatch = transaction.remittanceInformationUnstructured?.match(
33
+ /PIRKUMS [\d*]+ (\d{2}\.\d{2}\.\d{4})/,
34
+ );
35
+
36
+ if (dateMatch) {
37
+ const extractedDate = d
38
+ .parse(dateMatch[1], 'dd.MM.yyyy', new Date())
39
+ .toISOString();
40
+
41
+ editedTrans.date = extractedDate;
42
+ }
43
+ }
44
+
45
+ return Fallback.normalizeTransaction(transaction, booked, editedTrans);
46
+ },
47
+ };
@@ -0,0 +1,21 @@
1
+ import { mockTransactionAmount } from '../../services/tests/fixtures.js';
2
+ import Abanca from '../abanca_caglesmm.js';
3
+
4
+ describe('Abanca', () => {
5
+ describe('#normalizeTransaction', () => {
6
+ it('returns the creditorName and debtorName as remittanceInformationStructured', () => {
7
+ const transaction = {
8
+ transactionId: 'non-unique-id',
9
+ internalTransactionId: 'D202301180000003',
10
+ transactionAmount: mockTransactionAmount,
11
+ remittanceInformationStructured: 'some-creditor-name',
12
+ date: new Date().toISOString(),
13
+ };
14
+ const normalizedTransaction = Abanca.normalizeTransaction(
15
+ transaction,
16
+ true,
17
+ );
18
+ expect(normalizedTransaction.payeeName).toEqual('Some-Creditor-Name');
19
+ });
20
+ });
21
+ });
@@ -0,0 +1,61 @@
1
+ import AbnamroAbnanl2a from '../abnamro_abnanl2a.js';
2
+
3
+ describe('AbnamroAbnanl2a', () => {
4
+ describe('#normalizeTransaction', () => {
5
+ it('correctly extracts the payee and when not provided', () => {
6
+ const transaction = {
7
+ transactionId: '0123456789012345',
8
+ bookingDate: '2023-12-11',
9
+ valueDateTime: '2023-12-09T15:43:37.950',
10
+ transactionAmount: {
11
+ amount: '-10.00',
12
+ currency: 'EUR',
13
+ },
14
+ remittanceInformationUnstructuredArray: [
15
+ 'BEA, Betaalpas',
16
+ 'My Payee Name,PAS123',
17
+ 'NR:123A4B, 09.12.23/15:43',
18
+ 'CITY',
19
+ ],
20
+ };
21
+
22
+ const normalizedTransaction = AbnamroAbnanl2a.normalizeTransaction(
23
+ transaction,
24
+ false,
25
+ );
26
+
27
+ expect(normalizedTransaction.notes).toEqual(
28
+ 'BEA, Betaalpas, My Payee Name,PAS123, NR:123A4B, 09.12.23/15:43, CITY',
29
+ );
30
+ expect(normalizedTransaction.payeeName).toEqual('My Payee Name');
31
+ });
32
+
33
+ it('correctly extracts the payee for google pay', () => {
34
+ const transaction = {
35
+ transactionId: '0123456789012345',
36
+ bookingDate: '2023-12-11',
37
+ valueDateTime: '2023-12-09T15:43:37.950',
38
+ transactionAmount: {
39
+ amount: '-10.00',
40
+ currency: 'EUR',
41
+ },
42
+ remittanceInformationUnstructuredArray: [
43
+ 'BEA, Google Pay',
44
+ 'CCV*Other payee name,PAS123',
45
+ 'NR:123A4B, 09.12.23/15:43',
46
+ 'CITY',
47
+ ],
48
+ };
49
+
50
+ const normalizedTransaction = AbnamroAbnanl2a.normalizeTransaction(
51
+ transaction,
52
+ false,
53
+ );
54
+
55
+ expect(normalizedTransaction.notes).toEqual(
56
+ 'BEA, Google Pay, CCV*Other payee name,PAS123, NR:123A4B, 09.12.23/15:43, CITY',
57
+ );
58
+ expect(normalizedTransaction.payeeName).toEqual('Other Payee Name');
59
+ });
60
+ });
61
+ });
@@ -0,0 +1,53 @@
1
+ import Sabadell from '../bancsabadell_bsabesbbb.js';
2
+
3
+ describe('BancSabadell', () => {
4
+ describe('#normalizeTransaction', () => {
5
+ describe('returns the creditorName and debtorName from remittanceInformationUnstructuredArray', () => {
6
+ it('debtor role - amount < 0', () => {
7
+ const transaction = {
8
+ transactionAmount: { amount: '-100', currency: 'EUR' },
9
+ remittanceInformationUnstructuredArray: ['some-creditor-name'],
10
+ internalTransactionId: 'd7dca139cf31d9',
11
+ transactionId: '04704109322',
12
+ bookingDate: '2022-05-01',
13
+ };
14
+ const normalizedTransaction = Sabadell.normalizeTransaction(
15
+ transaction,
16
+ true,
17
+ );
18
+ expect(normalizedTransaction.payeeName).toEqual('Some-Creditor-Name');
19
+ });
20
+
21
+ it('creditor role - amount > 0', () => {
22
+ const transaction = {
23
+ transactionAmount: { amount: '100', currency: 'EUR' },
24
+ remittanceInformationUnstructuredArray: ['some-debtor-name'],
25
+ internalTransactionId: 'd7dca139cf31d9',
26
+ transactionId: '04704109322',
27
+ bookingDate: '2022-05-01',
28
+ };
29
+ const normalizedTransaction = Sabadell.normalizeTransaction(
30
+ transaction,
31
+ true,
32
+ );
33
+ expect(normalizedTransaction.payeeName).toEqual('Some-Debtor-Name');
34
+ });
35
+ });
36
+
37
+ it('extract date', () => {
38
+ const transaction = {
39
+ transactionAmount: { amount: '-100', currency: 'EUR' },
40
+ remittanceInformationUnstructuredArray: ['some-creditor-name'],
41
+ internalTransactionId: 'd7dca139cf31d9',
42
+ transactionId: '04704109322',
43
+ bookingDate: '2024-10-02',
44
+ valueDate: '2024-10-05',
45
+ };
46
+ const normalizedTransaction = Sabadell.normalizeTransaction(
47
+ transaction,
48
+ true,
49
+ );
50
+ expect(normalizedTransaction.date).toEqual('2024-10-02');
51
+ });
52
+ });
53
+ });
@@ -0,0 +1,22 @@
1
+ import { mockTransactionAmount } from '../../services/tests/fixtures.js';
2
+ import Belfius from '../belfius_gkccbebb.js';
3
+
4
+ describe('Belfius', () => {
5
+ describe('#normalizeTransaction', () => {
6
+ it('returns the internalTransactionId as transactionId', () => {
7
+ const transaction = {
8
+ transactionId: 'non-unique-id',
9
+ internalTransactionId: 'D202301180000003',
10
+ transactionAmount: mockTransactionAmount,
11
+ date: new Date().toISOString(),
12
+ };
13
+ const normalizedTransaction = Belfius.normalizeTransaction(
14
+ transaction,
15
+ true,
16
+ );
17
+ expect(normalizedTransaction.transactionId).toEqual(
18
+ transaction.internalTransactionId,
19
+ );
20
+ });
21
+ });
22
+ });
@@ -0,0 +1,34 @@
1
+ import CBCcregbebb from '../cbc_cregbebb.js';
2
+
3
+ describe('cbc_cregbebb', () => {
4
+ describe('#normalizeTransaction', () => {
5
+ it('returns the remittanceInformationUnstructured as payeeName when the amount is negative', () => {
6
+ const transaction = {
7
+ remittanceInformationUnstructured:
8
+ 'ONKART FR Viry Paiement Maestro par Carte de débit CBC 05-09-2024 à 15.43 heures 6703 19XX XXXX X201 5 JOHN DOE',
9
+ transactionAmount: { amount: '-45.00', currency: 'EUR' },
10
+ date: new Date().toISOString(),
11
+ };
12
+ const normalizedTransaction = CBCcregbebb.normalizeTransaction(
13
+ transaction,
14
+ true,
15
+ );
16
+ expect(normalizedTransaction.payeeName).toEqual('ONKART FR Viry');
17
+ });
18
+
19
+ it('returns the debtorName as payeeName when the amount is positive', () => {
20
+ const transaction = {
21
+ debtorName: 'ONKART FR Viry',
22
+ remittanceInformationUnstructured:
23
+ 'ONKART FR Viry Paiement Maestro par Carte de débit CBC 05-09-2024 à 15.43 heures 6703 19XX XXXX X201 5 JOHN DOE',
24
+ transactionAmount: { amount: '10.99', currency: 'EUR' },
25
+ date: new Date().toISOString(),
26
+ };
27
+ const normalizedTransaction = CBCcregbebb.normalizeTransaction(
28
+ transaction,
29
+ true,
30
+ );
31
+ expect(normalizedTransaction.payeeName).toEqual('ONKART FR Viry');
32
+ });
33
+ });
34
+ });
@@ -0,0 +1,110 @@
1
+ import CommerzbankCobadeff from '../commerzbank_cobadeff.js';
2
+
3
+ describe('CommerzbankCobadeff', () => {
4
+ describe('#normalizeTransaction', () => {
5
+ it('correctly formats remittanceInformationUnstructured', () => {
6
+ const transaction = {
7
+ endToEndId: '1234567890',
8
+ mandateId: '321654',
9
+ bookingDate: '2024-12-20',
10
+ valueDate: '2024-12-20',
11
+ transactionAmount: {
12
+ amount: '-12.34',
13
+ currency: 'EUR',
14
+ },
15
+ creditorName: 'SHOP NAME CITY DE',
16
+ remittanceInformationUnstructured:
17
+ 'SHOP NAME//CITY/DE\n2024-12-19T15:34:31 KFN 1 AB 1234\nKartenzahlung',
18
+ remittanceInformationUnstructuredArray: [
19
+ 'SHOP NAME//CITY/DE',
20
+ '2024-12-19T15:34:31 KFN 1 AB 1234',
21
+ 'Kartenzahlung',
22
+ ],
23
+ remittanceInformationStructured:
24
+ 'SHOP NAME//CITY/DE 2024-12-19T15:34:31 KFN 1 AB 1234 Kartenzahlung',
25
+ internalTransactionId: '3815213adb654baeadfb231c853',
26
+ };
27
+ const normalizedTransaction = CommerzbankCobadeff.normalizeTransaction(
28
+ transaction,
29
+ false,
30
+ );
31
+ expect(normalizedTransaction.notes).toEqual(
32
+ '2024-12-19T15:34:31 KFN 1 AB 1234, Kartenzahlung',
33
+ );
34
+ });
35
+
36
+ it('correctly formats remittanceInformationUnstructured; repair split keyword', () => {
37
+ const transaction = {
38
+ endToEndId: '901234567890',
39
+ mandateId: 'ABC123DEF456',
40
+ bookingDate: '2024-10-11',
41
+ valueDate: '2024-10-11',
42
+ transactionAmount: {
43
+ amount: '-56.78',
44
+ currency: 'EUR',
45
+ },
46
+ creditorName: 'Long payee name that is eaxtly 35ch',
47
+ remittanceInformationUnstructured:
48
+ 'Long payee name that is eaxtly 35ch\n901234567890/. Long description tha\nt gets cut and is very long, did I\nmention it is long\nEnd-to-En',
49
+ remittanceInformationUnstructuredArray: [
50
+ 'Long payee name that is eaxtly 35ch',
51
+ '901234567890/. Long description tha',
52
+ 't gets cut and is very long, did I',
53
+ 'mention it is long',
54
+ 'End-to-En',
55
+ 'd-Ref.: 901234567890',
56
+ 'Mandatsref: ABC123DEF456',
57
+ 'Gläubiger-ID:',
58
+ 'AB12CDE0000000000000000012',
59
+ 'SEPA-BASISLASTSCHRIFT wiederholend',
60
+ ],
61
+ remittanceInformationStructured:
62
+ 'Long payee name that is eaxtly 35ch 901234567890/. Long description tha t gets cut and is very long, did I mention it is long End-to-En',
63
+ internalTransactionId: '812354cfdea36465asdfe',
64
+ };
65
+ const normalizedTransaction = CommerzbankCobadeff.normalizeTransaction(
66
+ transaction,
67
+ false,
68
+ );
69
+ expect(normalizedTransaction.notes).toEqual(
70
+ '901234567890/. Long description tha t gets cut and is very long, did I mention it is long, End-to-End-Ref.: 901234567890, Mandatsref: ABC123DEF456, Gläubiger-ID: AB12CDE0000000000000000012, SEPA-BASISLASTSCHRIFT wiederholend',
71
+ );
72
+ });
73
+
74
+ it('correctly formats remittanceInformationUnstructured; removing NOTPROVIDED', () => {
75
+ const transaction = {
76
+ endToEndId: 'NOTPROVIDED',
77
+ bookingDate: '2024-12-02',
78
+ valueDate: '2024-12-02',
79
+ transactionAmount: {
80
+ amount: '-9',
81
+ currency: 'EUR',
82
+ },
83
+ creditorName: 'CREDITOR NAME',
84
+ creditorAccount: {
85
+ iban: 'CREDITOR000IBAN',
86
+ },
87
+ remittanceInformationUnstructured:
88
+ 'CREDITOR NAME\nCREDITOR00BIC\nCREDITOR000IBAN\nDESCRIPTION\nEnd-to-End-Ref.: NOTPROVIDED\nDauerauftrag',
89
+ remittanceInformationUnstructuredArray: [
90
+ 'CREDITOR NAME',
91
+ 'CREDITOR00BIC',
92
+ 'CREDITOR000IBAN',
93
+ 'DESCRIPTION',
94
+ 'End-to-End-Ref.: NOTPROVIDED',
95
+ 'Dauerauftrag',
96
+ ],
97
+ remittanceInformationStructured:
98
+ 'CREDITOR NAME CREDITOR00BIC CREDITOR000IBAN DESCRIPTION End-to-End-Ref.: NOTPROVIDED Dauerauftrag',
99
+ internalTransactionId: 'f617dc31ab77622bf13d6c95d6dd8b4a',
100
+ };
101
+ const normalizedTransaction = CommerzbankCobadeff.normalizeTransaction(
102
+ transaction,
103
+ false,
104
+ );
105
+ expect(normalizedTransaction.notes).toEqual(
106
+ 'CREDITOR00BIC CREDITOR000IBAN DESCRIPTION, Dauerauftrag',
107
+ );
108
+ });
109
+ });
110
+ });
@@ -0,0 +1,54 @@
1
+ import { mockTransactionAmount } from '../../services/tests/fixtures.js';
2
+ import EasybankBawaatww from '../easybank_bawaatww.js';
3
+
4
+ describe('easybank', () => {
5
+ describe('#normalizeTransaction', () => {
6
+ it('returns the expected payeeName from a transaction with a set creditorName', () => {
7
+ const transaction = {
8
+ creditorName: 'Some Payee Name',
9
+ transactionAmount: mockTransactionAmount,
10
+ bookingDate: '2024-01-01',
11
+ creditorAccount: 'AT611904300234573201',
12
+ };
13
+
14
+ const normalizedTransaction = EasybankBawaatww.normalizeTransaction(
15
+ transaction,
16
+ true,
17
+ );
18
+
19
+ expect(normalizedTransaction.payeeName).toEqual('Some Payee Name');
20
+ });
21
+
22
+ it('returns the expected payeeName from a transaction with payee name inside structuredInformation', () => {
23
+ const transaction = {
24
+ payeeName: '',
25
+ transactionAmount: mockTransactionAmount,
26
+ remittanceInformationStructured:
27
+ 'Bezahlung Karte MC/000001234POS 1234 K001 12.12. 23:59SOME PAYEE NAME\\\\LOCATION\\1',
28
+ bookingDate: '2023-12-31',
29
+ };
30
+ const normalizedTransaction = EasybankBawaatww.normalizeTransaction(
31
+ transaction,
32
+ true,
33
+ );
34
+ expect(normalizedTransaction.payeeName).toEqual('Some Payee Name');
35
+ });
36
+
37
+ it('returns the full structured information as payeeName from a transaction with no payee name', () => {
38
+ const transaction = {
39
+ payeeName: '',
40
+ transactionAmount: mockTransactionAmount,
41
+ remittanceInformationStructured:
42
+ 'Auszahlung Karte MC/000001234AUTOMAT 00012345 K001 31.12. 23:59',
43
+ bookingDate: '2023-12-31',
44
+ };
45
+ const normalizedTransaction = EasybankBawaatww.normalizeTransaction(
46
+ transaction,
47
+ true,
48
+ );
49
+ expect(normalizedTransaction.payeeName).toEqual(
50
+ 'Auszahlung Karte MC/000001234AUTOMAT 00012345 K001 31.12. 23:59',
51
+ );
52
+ });
53
+ });
54
+ });