Skip to content

Commit 48d1e7e

Browse files
doublefaceCrash--
doubleface
authored andcommittedDec 6, 2022
fix: Also update disabled bank accounts with new cozy account id

File tree

2 files changed

+192
-21
lines changed

2 files changed

+192
-21
lines changed
 

‎packages/cozy-doctypes/src/banking/BankAccount.js

+80-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const groupBy = require('lodash/groupBy')
22
const get = require('lodash/get')
3+
const keyBy = require('lodash/keyBy')
34
const merge = require('lodash/merge')
45
const Document = require('../Document')
56
const matching = require('./matching-accounts')
@@ -11,14 +12,22 @@ class BankAccount extends Document {
1112
* Adds _id of existing accounts to fetched accounts
1213
*/
1314
static reconciliate(fetchedAccounts, localAccounts) {
14-
const matchings = matching.matchAccounts(fetchedAccounts, localAccounts)
15+
let matchings = matching.matchAccounts(fetchedAccounts, localAccounts)
16+
matchings = BankAccount.addForcedReplaceMatchings(matchings, localAccounts)
1517
return matchings.map(matching => {
1618
log(
1719
'info',
1820
matching.match
1921
? `${matching.account.label} matched with ${matching.match.label} via ${matching.method}`
2022
: `${matching.account.label} did not match with an existing account`
2123
)
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
2231
return {
2332
// eslint-disable-next-line node/no-unsupported-features/es-syntax
2433
...matching.account,
@@ -27,11 +36,80 @@ class BankAccount extends Document {
2736
matching.match ? matching.match.relationships : null,
2837
matching.account.relationships
2938
),
30-
_id: matching.match ? matching.match._id : undefined
39+
_id: forcedReplaceId || matchingMatchId
3140
}
3241
})
3342
}
3443

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+
35113
static findDuplicateAccountsWithNoOperations(accounts, operations) {
36114
const opsByAccountId = groupBy(operations, op => op.account)
37115

‎packages/cozy-doctypes/src/banking/BankAccount.spec.js

+112-19
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,122 @@
11
const BankAccount = require('./BankAccount')
22

33
describe('account reconciliation', () => {
4-
const newAccounts = [
5-
{
6-
number: '1',
7-
balance: 100,
8-
relationships: {
9-
aRelationship: { _id: 'fake-id', _type: 'fake-type' },
10-
anotherRelationship: { _id: 'fake-id2', _type: 'fake-type2' }
4+
it('should update relationship of disabled accounts associated to the same relationship as updated anabled accounts', () => {
5+
const newAccounts = [
6+
{
7+
number: '1',
8+
balance: 100,
9+
relationships: {
10+
connection: {
11+
data: {
12+
_id: 'cozyaccountnew',
13+
_type: 'io.cozy.accounts'
14+
}
15+
}
16+
},
17+
metadata: {
18+
updatedAt: '2020-11-30'
19+
}
1120
}
12-
},
13-
{ number: '2', balance: 200 }
14-
]
15-
const currentAccounts = [
16-
{
17-
_id: 'a1',
18-
number: '1',
19-
balance: 50,
20-
relationships: {
21-
aRelationship: { _id: 'old-fake-id', _type: 'old-fake-type' }
21+
]
22+
const currentAccounts = [
23+
{
24+
_id: 'a1',
25+
number: '1',
26+
balance: 50,
27+
relationships: {
28+
connection: {
29+
data: {
30+
_id: 'cozyaccountold',
31+
_type: 'io.cozy.accounts'
32+
}
33+
}
34+
},
35+
metadata: {
36+
updatedAt: '2020-11-30'
37+
}
38+
},
39+
{
40+
_id: 'a2',
41+
number: '2',
42+
balance: 300,
43+
relationships: {
44+
connection: {
45+
data: {
46+
_id: 'cozyaccountold',
47+
_type: 'io.cozy.accounts'
48+
}
49+
}
50+
},
51+
metadata: {
52+
updatedAt: '2020-11-30'
53+
}
2254
}
23-
}
24-
]
55+
]
56+
const matchedAccounts = BankAccount.reconciliate(
57+
newAccounts,
58+
currentAccounts
59+
)
2560

61+
expect(matchedAccounts).toEqual([
62+
{
63+
_id: 'a1',
64+
number: '1',
65+
rawNumber: '1',
66+
balance: 100,
67+
relationships: {
68+
connection: {
69+
data: {
70+
_id: 'cozyaccountnew',
71+
_type: 'io.cozy.accounts'
72+
}
73+
}
74+
},
75+
metadata: {
76+
updatedAt: '2020-11-30'
77+
}
78+
},
79+
{
80+
_id: 'a2',
81+
number: '2',
82+
balance: 300,
83+
relationships: {
84+
connection: {
85+
data: {
86+
_id: 'cozyaccountnew',
87+
_type: 'io.cozy.accounts'
88+
}
89+
}
90+
},
91+
metadata: {
92+
disabledAt: '2020-11-30',
93+
updatedAt: '2020-11-30'
94+
}
95+
}
96+
])
97+
})
2698
it('should correctly match linxo accounts to cozy accounts through number', () => {
99+
const newAccounts = [
100+
{
101+
number: '1',
102+
balance: 100,
103+
relationships: {
104+
aRelationship: { _id: 'fake-id', _type: 'fake-type' },
105+
anotherRelationship: { _id: 'fake-id2', _type: 'fake-type2' }
106+
}
107+
},
108+
{ number: '2', balance: 200 }
109+
]
110+
const currentAccounts = [
111+
{
112+
_id: 'a1',
113+
number: '1',
114+
balance: 50,
115+
relationships: {
116+
aRelationship: { _id: 'old-fake-id', _type: 'old-fake-type' }
117+
}
118+
}
119+
]
27120
const matchedAccounts = BankAccount.reconciliate(
28121
newAccounts,
29122
currentAccounts

0 commit comments

Comments
 (0)
Please sign in to comment.