Skip to content

Commit

Permalink
fix: Also update disabled bank accounts with new cozy account id
Browse files Browse the repository at this point in the history
  • Loading branch information
doubleface authored and Crash-- committed Dec 6, 2022
1 parent 1aed214 commit 48d1e7e
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 21 deletions.
82 changes: 80 additions & 2 deletions packages/cozy-doctypes/src/banking/BankAccount.js
@@ -1,5 +1,6 @@
const groupBy = require('lodash/groupBy')
const get = require('lodash/get')
const keyBy = require('lodash/keyBy')
const merge = require('lodash/merge')
const Document = require('../Document')
const matching = require('./matching-accounts')
Expand All @@ -11,14 +12,22 @@ class BankAccount extends Document {
* Adds _id of existing accounts to fetched accounts
*/
static reconciliate(fetchedAccounts, localAccounts) {
const matchings = matching.matchAccounts(fetchedAccounts, localAccounts)
let matchings = matching.matchAccounts(fetchedAccounts, localAccounts)
matchings = BankAccount.addForcedReplaceMatchings(matchings, localAccounts)
return matchings.map(matching => {
log(
'info',
matching.match
? `${matching.account.label} matched with ${matching.match.label} via ${matching.method}`
: `${matching.account.label} did not match with an existing account`
)
if (matching.forcedReplace) {
log('info', `${matching.account.label} forced disabled state`)
}
const matchingMatchId = matching.match ? matching.match._id : undefined
const forcedReplaceId = matching.forcedReplace
? matching.account._id
: undefined
return {
// eslint-disable-next-line node/no-unsupported-features/es-syntax
...matching.account,
Expand All @@ -27,11 +36,80 @@ class BankAccount extends Document {
matching.match ? matching.match.relationships : null,
matching.account.relationships
),
_id: matching.match ? matching.match._id : undefined
_id: forcedReplaceId || matchingMatchId
}
})
}

/**
* Finds existing local bank accounts which are disabled and force their association to the new cozy account id
* which can be found in the other updated bank accounts
*
* @param {Array} previousMatchings
* @param {Array} localAccounts
* @returns {Array} matchings array with added disabled bank accounts to update with new cozy account id
*/
static addForcedReplaceMatchings(previousMatchings, localAccounts) {
const replacedCozyAccountIds =
BankAccount.findReplacedCozyAccountIdsMatchings(previousMatchings)

if (!Object.keys(replacedCozyAccountIds).length > 0) {
return previousMatchings
}

const matchings = [...previousMatchings]
const matchedAccountIds = keyBy(matchings, 'match._id')
for (const localAccount of localAccounts) {
const foundInMatchedAccounts = Boolean(
matchedAccountIds[localAccount._id]
)
const newAccountId =
replacedCozyAccountIds[localAccount.relationships.connection.data._id]
if (foundInMatchedAccounts || !newAccountId) {
continue
}
matchings.push({
forcedReplace: true,
account: {
// eslint-disable-next-line node/no-unsupported-features/es-syntax
...localAccount,
metadata: merge({}, localAccount.metadata, {
disabledAt: localAccount.metadata?.updatedAt
}),
relationships: merge({}, localAccount.relationships, {
connection: {
data: {
_id: newAccountId
}
}
})
}
})
}
return matchings
}

/**
* Find any bank account which cozy account id has been changed
*
* @param {Array} matchings
* @returns {Object} mapping from old cozy account id to new cozy account id
*/
static findReplacedCozyAccountIdsMatchings(matchings) {
const result = {}
for (const matching of matchings) {
if (
matching.match &&
matching?.account?.relationships?.connection?.data?._id !==
matching?.match?.relationships?.connection?.data?._id
) {
result[matching?.match?.relationships?.connection?.data?._id] =
matching?.account?.relationships?.connection?.data?._id
}
}
return result
}

static findDuplicateAccountsWithNoOperations(accounts, operations) {
const opsByAccountId = groupBy(operations, op => op.account)

Expand Down
131 changes: 112 additions & 19 deletions packages/cozy-doctypes/src/banking/BankAccount.spec.js
@@ -1,29 +1,122 @@
const BankAccount = require('./BankAccount')

describe('account reconciliation', () => {
const newAccounts = [
{
number: '1',
balance: 100,
relationships: {
aRelationship: { _id: 'fake-id', _type: 'fake-type' },
anotherRelationship: { _id: 'fake-id2', _type: 'fake-type2' }
it('should update relationship of disabled accounts associated to the same relationship as updated anabled accounts', () => {
const newAccounts = [
{
number: '1',
balance: 100,
relationships: {
connection: {
data: {
_id: 'cozyaccountnew',
_type: 'io.cozy.accounts'
}
}
},
metadata: {
updatedAt: '2020-11-30'
}
}
},
{ number: '2', balance: 200 }
]
const currentAccounts = [
{
_id: 'a1',
number: '1',
balance: 50,
relationships: {
aRelationship: { _id: 'old-fake-id', _type: 'old-fake-type' }
]
const currentAccounts = [
{
_id: 'a1',
number: '1',
balance: 50,
relationships: {
connection: {
data: {
_id: 'cozyaccountold',
_type: 'io.cozy.accounts'
}
}
},
metadata: {
updatedAt: '2020-11-30'
}
},
{
_id: 'a2',
number: '2',
balance: 300,
relationships: {
connection: {
data: {
_id: 'cozyaccountold',
_type: 'io.cozy.accounts'
}
}
},
metadata: {
updatedAt: '2020-11-30'
}
}
}
]
]
const matchedAccounts = BankAccount.reconciliate(
newAccounts,
currentAccounts
)

expect(matchedAccounts).toEqual([
{
_id: 'a1',
number: '1',
rawNumber: '1',
balance: 100,
relationships: {
connection: {
data: {
_id: 'cozyaccountnew',
_type: 'io.cozy.accounts'
}
}
},
metadata: {
updatedAt: '2020-11-30'
}
},
{
_id: 'a2',
number: '2',
balance: 300,
relationships: {
connection: {
data: {
_id: 'cozyaccountnew',
_type: 'io.cozy.accounts'
}
}
},
metadata: {
disabledAt: '2020-11-30',
updatedAt: '2020-11-30'
}
}
])
})
it('should correctly match linxo accounts to cozy accounts through number', () => {
const newAccounts = [
{
number: '1',
balance: 100,
relationships: {
aRelationship: { _id: 'fake-id', _type: 'fake-type' },
anotherRelationship: { _id: 'fake-id2', _type: 'fake-type2' }
}
},
{ number: '2', balance: 200 }
]
const currentAccounts = [
{
_id: 'a1',
number: '1',
balance: 50,
relationships: {
aRelationship: { _id: 'old-fake-id', _type: 'old-fake-type' }
}
}
]
const matchedAccounts = BankAccount.reconciliate(
newAccounts,
currentAccounts
Expand Down

0 comments on commit 48d1e7e

Please sign in to comment.