1
1
const groupBy = require ( 'lodash/groupBy' )
2
2
const get = require ( 'lodash/get' )
3
+ const keyBy = require ( 'lodash/keyBy' )
3
4
const merge = require ( 'lodash/merge' )
4
5
const Document = require ( '../Document' )
5
6
const matching = require ( './matching-accounts' )
@@ -11,14 +12,22 @@ class BankAccount extends Document {
11
12
* Adds _id of existing accounts to fetched accounts
12
13
*/
13
14
static reconciliate ( fetchedAccounts , localAccounts ) {
14
- const matchings = matching . matchAccounts ( fetchedAccounts , localAccounts )
15
+ let matchings = matching . matchAccounts ( fetchedAccounts , localAccounts )
16
+ matchings = BankAccount . addForcedReplaceMatchings ( matchings , localAccounts )
15
17
return matchings . map ( matching => {
16
18
log (
17
19
'info' ,
18
20
matching . match
19
21
? `${ matching . account . label } matched with ${ matching . match . label } via ${ matching . method } `
20
22
: `${ matching . account . label } did not match with an existing account`
21
23
)
24
+ if ( matching . forcedReplace ) {
25
+ log ( 'info' , `${ matching . account . label } forced disabled state` )
26
+ }
27
+ const matchingMatchId = matching . match ? matching . match . _id : undefined
28
+ const forcedReplaceId = matching . forcedReplace
29
+ ? matching . account . _id
30
+ : undefined
22
31
return {
23
32
// eslint-disable-next-line node/no-unsupported-features/es-syntax
24
33
...matching . account ,
@@ -27,11 +36,80 @@ class BankAccount extends Document {
27
36
matching . match ? matching . match . relationships : null ,
28
37
matching . account . relationships
29
38
) ,
30
- _id : matching . match ? matching . match . _id : undefined
39
+ _id : forcedReplaceId || matchingMatchId
31
40
}
32
41
} )
33
42
}
34
43
44
+ /**
45
+ * Finds existing local bank accounts which are disabled and force their association to the new cozy account id
46
+ * which can be found in the other updated bank accounts
47
+ *
48
+ * @param {Array } previousMatchings
49
+ * @param {Array } localAccounts
50
+ * @returns {Array } matchings array with added disabled bank accounts to update with new cozy account id
51
+ */
52
+ static addForcedReplaceMatchings ( previousMatchings , localAccounts ) {
53
+ const replacedCozyAccountIds =
54
+ BankAccount . findReplacedCozyAccountIdsMatchings ( previousMatchings )
55
+
56
+ if ( ! Object . keys ( replacedCozyAccountIds ) . length > 0 ) {
57
+ return previousMatchings
58
+ }
59
+
60
+ const matchings = [ ...previousMatchings ]
61
+ const matchedAccountIds = keyBy ( matchings , 'match._id' )
62
+ for ( const localAccount of localAccounts ) {
63
+ const foundInMatchedAccounts = Boolean (
64
+ matchedAccountIds [ localAccount . _id ]
65
+ )
66
+ const newAccountId =
67
+ replacedCozyAccountIds [ localAccount . relationships . connection . data . _id ]
68
+ if ( foundInMatchedAccounts || ! newAccountId ) {
69
+ continue
70
+ }
71
+ matchings . push ( {
72
+ forcedReplace : true ,
73
+ account : {
74
+ // eslint-disable-next-line node/no-unsupported-features/es-syntax
75
+ ...localAccount ,
76
+ metadata : merge ( { } , localAccount . metadata , {
77
+ disabledAt : localAccount . metadata ?. updatedAt
78
+ } ) ,
79
+ relationships : merge ( { } , localAccount . relationships , {
80
+ connection : {
81
+ data : {
82
+ _id : newAccountId
83
+ }
84
+ }
85
+ } )
86
+ }
87
+ } )
88
+ }
89
+ return matchings
90
+ }
91
+
92
+ /**
93
+ * Find any bank account which cozy account id has been changed
94
+ *
95
+ * @param {Array } matchings
96
+ * @returns {Object } mapping from old cozy account id to new cozy account id
97
+ */
98
+ static findReplacedCozyAccountIdsMatchings ( matchings ) {
99
+ const result = { }
100
+ for ( const matching of matchings ) {
101
+ if (
102
+ matching . match &&
103
+ matching ?. account ?. relationships ?. connection ?. data ?. _id !==
104
+ matching ?. match ?. relationships ?. connection ?. data ?. _id
105
+ ) {
106
+ result [ matching ?. match ?. relationships ?. connection ?. data ?. _id ] =
107
+ matching ?. account ?. relationships ?. connection ?. data ?. _id
108
+ }
109
+ }
110
+ return result
111
+ }
112
+
35
113
static findDuplicateAccountsWithNoOperations ( accounts , operations ) {
36
114
const opsByAccountId = groupBy ( operations , op => op . account )
37
115
0 commit comments