Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -0,0 +1,86 @@
|
||||
// Generated, do not edit. sha256:ebad02dba29ae50bcbaf9c21bb59936cf43f6be868e86ac00d0e6055f404b26f
|
||||
import * as db from '../db.js';
|
||||
import { ACCOUNT_SOURCE_KINDS } from '../../shared/config.js';
|
||||
import { fail } from '../../shared/app-error.js';
|
||||
import { eventsNetByAccount } from './events.js';
|
||||
import { trackUpdate, trackUpdateWhere, trackDelete, trackDeleteWhere, withOrigin } from './change-log.js';
|
||||
|
||||
function mergeCompatibility(survivor, victim) {
|
||||
const S = ACCOUNT_SOURCE_KINDS[survivor.kind] || [];
|
||||
const V = ACCOUNT_SOURCE_KINDS[victim.kind] || [];
|
||||
if ((S.length === 0) !== (V.length === 0)) {
|
||||
return { ok: false, reason: 'sourceMismatch' };
|
||||
}
|
||||
if (V.some(k => !S.includes(k))) {
|
||||
return { ok: false, reason: 'kindCannotCarry' };
|
||||
}
|
||||
return { ok: true, reason: null };
|
||||
}
|
||||
|
||||
export function mergeCheck(survivorId, victimId) {
|
||||
if (!survivorId || !victimId) return { ok: false, reason: 'pickTwo', counts: null };
|
||||
if (Number(survivorId) === Number(victimId)) return { ok: false, reason: 'sameAccount', counts: null };
|
||||
const survivor = db.one(`SELECT * FROM Account WHERE id=?`, [survivorId]);
|
||||
const victim = db.one(`SELECT * FROM Account WHERE id=?`, [victimId]);
|
||||
if (!survivor || !victim) return { ok: false, reason: 'notFound', counts: null };
|
||||
const compat = mergeCompatibility(survivor, victim);
|
||||
const counts = {
|
||||
sources: db.one(`SELECT COUNT(*) AS n FROM WalletSource WHERE accountId=?`, [victimId]).n,
|
||||
events: db.one(`SELECT COUNT(*) AS n FROM Event WHERE fromAccountId=?1 OR toAccountId=?1`, [victimId]).n,
|
||||
schedules: db.one(`SELECT COUNT(*) AS n FROM InterestSchedule WHERE accountId=?`, [victimId]).n,
|
||||
valuations: db.one(`SELECT COUNT(*) AS n FROM Valuation WHERE accountId =?`, [victimId]).n,
|
||||
};
|
||||
return { ok: compat.ok, reason: compat.reason, counts, survivorName: survivor.name, victimName: victim.name };
|
||||
}
|
||||
|
||||
export async function mergeAccounts(survivorId, victimId) {
|
||||
survivorId = Number(survivorId); victimId = Number(victimId);
|
||||
const chk = mergeCheck(survivorId, victimId);
|
||||
if (!chk.ok) fail(`accounts.mergeReason_${chk.reason}`, null, `Merge not possible (${chk.reason}).`);
|
||||
return withOrigin('merge', victimId, () => voerSamenvoegingUit(survivorId, victimId, chk));
|
||||
}
|
||||
|
||||
async function voerSamenvoegingUit(survivorId, victimId, chk) {
|
||||
|
||||
const preDiff = new Map();
|
||||
for (const v of db.all(`SELECT id, accountId, assetId, rateAt, balance FROM Valuation WHERE accountId = ?1 OR accountId = ?2`, [survivorId, victimId])) {
|
||||
preDiff.set(v.id, v.balance - eventsNetByAccount(v.accountId, v.assetId, v.rateAt));
|
||||
}
|
||||
|
||||
trackUpdateWhere('Event', `fromAccountId = ?`, [victimId], () =>
|
||||
db.run(`UPDATE Event SET fromAccountId=?1 WHERE fromAccountId=?2`, [survivorId, victimId]));
|
||||
trackUpdateWhere('Event', `toAccountId = ?`, [victimId], () =>
|
||||
db.run(`UPDATE Event SET toAccountId=?1 WHERE toAccountId=?2`, [survivorId, victimId]));
|
||||
trackUpdateWhere('WalletSource', `accountId = ?`, [victimId], () =>
|
||||
db.run(`UPDATE WalletSource SET accountId=?1 WHERE accountId=?2`, [survivorId, victimId]));
|
||||
db.run(`UPDATE WalletAddress SET accountId=?1 WHERE accountId=?2`, [survivorId, victimId]);
|
||||
db.run(`UPDATE WalletTransaction SET accountId=?1 WHERE accountId=?2`, [survivorId, victimId]);
|
||||
db.run(`UPDATE ScanLog SET accountId=?1 WHERE accountId=?2`, [survivorId, victimId]);
|
||||
db.run(`UPDATE ReconcileProposal SET accountId=?1 WHERE accountId=?2`, [survivorId, victimId]);
|
||||
db.run(`UPDATE ImportBatch SET accountId=?1 WHERE accountId=?2`, [survivorId, victimId]);
|
||||
trackUpdateWhere('InterestSchedule', `accountId = ?`, [victimId], () =>
|
||||
db.run(`UPDATE InterestSchedule SET accountId=?1 WHERE accountId=?2`, [survivorId, victimId]));
|
||||
|
||||
trackDeleteWhere('Valuation', `accountId = ?2
|
||||
AND EXISTS (SELECT 1 FROM Valuation v2 WHERE v2.accountId = ?1
|
||||
AND v2.assetId=Valuation.assetId AND v2.valuedOn=Valuation.valuedOn)`,
|
||||
[survivorId, victimId], () =>
|
||||
db.run(`DELETE FROM Valuation WHERE accountId =?2
|
||||
AND EXISTS (SELECT 1 FROM Valuation v2 WHERE v2.accountId =?1
|
||||
AND v2.assetId=Valuation.assetId AND v2.valuedOn=Valuation.valuedOn)`,
|
||||
[survivorId, victimId]));
|
||||
trackUpdateWhere('Valuation', `accountId = ?`, [victimId], () =>
|
||||
db.run(`UPDATE Valuation SET accountId =?1 WHERE accountId = ?2`, [survivorId, victimId]));
|
||||
|
||||
for (const [id, diff] of preDiff) {
|
||||
const v = db.one(`SELECT id, assetId, rateAt FROM Valuation WHERE id=?`, [id]);
|
||||
if (!v) continue;
|
||||
const newNet = eventsNetByAccount(survivorId, v.assetId, v.rateAt);
|
||||
trackUpdate('Valuation', id, () =>
|
||||
db.run(`UPDATE Valuation SET balance=? WHERE id=?`, [newNet + diff, id]));
|
||||
}
|
||||
|
||||
trackDelete('Account', victimId, () => db.run(`DELETE FROM Account WHERE id=?`, [victimId]));
|
||||
await db.persist();
|
||||
return chk.counts;
|
||||
}
|
||||
Reference in new issue
Block a user