Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -0,0 +1,84 @@
|
||||
// Generated, do not edit. sha256:ae0d48181a52fd75f129b890a9ec73664ed0e72770dbab20484d6647df3ef532
|
||||
import * as db from '../db.js';
|
||||
import { toSearchName } from '../../shared/search-name.js';
|
||||
import { CONFIG, ENUMS } from '../../shared/config.js';
|
||||
import { assertEnum, assertTaxCategory, assertTaxScope, RATE_ONLY_ASSET } from './_shared.js';
|
||||
import { capacityReachedFor } from './_limits.js';
|
||||
import { allowedAssets } from '../license.mjs';
|
||||
import { fail } from '../../shared/app-error.js';
|
||||
import { trackDelete, trackUpdate } from './change-log.js';
|
||||
|
||||
export function listAssets() { return db.all(`SELECT * FROM Asset ORDER BY symbol`); }
|
||||
|
||||
export function listBookableAssets() {
|
||||
return db.all(`SELECT * FROM Asset WHERE NOT ${RATE_ONLY_ASSET} ORDER BY symbol`);
|
||||
}
|
||||
|
||||
function assertDecimals(decimals) {
|
||||
const leesbaar = typeof decimals === 'number'
|
||||
|| (typeof decimals === 'string' && decimals.trim() !== '');
|
||||
const n = leesbaar ? Number(decimals) : NaN;
|
||||
if (!Number.isInteger(n) || n < 0 || n > CONFIG.MAX_ASSET_DECIMALS) {
|
||||
fail('assets.decimalsRange', { max: CONFIG.MAX_ASSET_DECIMALS, waarde: decimals },
|
||||
`Decimals has to be a whole number from 0 to ${CONFIG.MAX_ASSET_DECIMALS} (got: '${decimals}'); `
|
||||
+ 'above that an amount can no longer be read back.');
|
||||
}
|
||||
}
|
||||
|
||||
function assertBalanceCapture(value) {
|
||||
if (value == null || value === '') return null;
|
||||
const n = Number(value);
|
||||
if (n !== 0 && n !== 1) throw new Error(`Invalid balanceCapture: '${value}'. Allowed: empty, 0, 1.`);
|
||||
return n;
|
||||
}
|
||||
|
||||
export async function createAsset({ symbol, name, kind, unit, subunit, decimals, displayUnit, taxCategory, taxScope, balanceCapture }) {
|
||||
const allowed = allowedAssets();
|
||||
if (allowed && kind !== 'fiat' && !allowed.includes(symbol)) {
|
||||
fail('assets.freeOnly', { list: allowed.join(', ') },
|
||||
`The free version holds ${allowed.join(', ')} and currencies only. A licence lifts that.`);
|
||||
}
|
||||
const max = capacityReachedFor('assets');
|
||||
if (max !== null) {
|
||||
fail('assets.maxFree', { max },
|
||||
`The free version holds ${max} asset(s). A licence lifts that; nothing is removed in the meantime.`);
|
||||
}
|
||||
assertEnum('kind', ENUMS.ASSET_KIND, kind);
|
||||
assertEnum('displayUnit', ENUMS.ASSET_DISPLAY_UNIT, displayUnit);
|
||||
assertDecimals(decimals);
|
||||
const categorie = assertTaxCategory(taxCategory);
|
||||
const capture = assertBalanceCapture(balanceCapture);
|
||||
const scope = assertTaxScope(taxScope);
|
||||
db.run(`INSERT INTO Asset (symbol, name, searchName, kind, unit, subunit, decimals, displayUnit, taxCategory, taxScope, balanceCapture)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?)`,
|
||||
[symbol, name, toSearchName(name), kind, unit, subunit ?? null, decimals, displayUnit, categorie, scope, capture]);
|
||||
const id = db.lastId();
|
||||
db.seedPriceSource(id, 'confirmed');
|
||||
await db.persist();
|
||||
return id;
|
||||
}
|
||||
export async function updateAsset(id, a) {
|
||||
assertEnum('kind', ENUMS.ASSET_KIND, a.kind);
|
||||
assertEnum('displayUnit', ENUMS.ASSET_DISPLAY_UNIT, a.displayUnit);
|
||||
assertDecimals(a.decimals);
|
||||
const categorie = assertTaxCategory(a.taxCategory);
|
||||
const given = Object.hasOwn(a, 'balanceCapture');
|
||||
const capture = given ? assertBalanceCapture(a.balanceCapture) : null;
|
||||
const scopeGiven = Object.hasOwn(a, 'taxScope');
|
||||
const scope = scopeGiven ? assertTaxScope(a.taxScope) : null;
|
||||
trackUpdate('Asset', id, () =>
|
||||
db.run(`UPDATE Asset SET symbol=?, name=?, searchName=?, kind=?, unit=?, subunit=?, decimals=?, displayUnit=?, taxCategory=?,
|
||||
taxScope = CASE WHEN ? THEN ? ELSE taxScope END,
|
||||
balanceCapture = CASE WHEN ? THEN ? ELSE balanceCapture END WHERE id=?`,
|
||||
[a.symbol, a.name, toSearchName(a.name), a.kind, a.unit, a.subunit ?? null, a.decimals, a.displayUnit, categorie,
|
||||
scopeGiven ? 1 : 0, scope, given ? 1 : 0, capture, id]));
|
||||
await db.persist();
|
||||
}
|
||||
export async function deleteAsset(id) {
|
||||
const used = db.one(`SELECT (SELECT COUNT(*) FROM Event WHERE assetId=?1)
|
||||
+ (SELECT COUNT(*) FROM Valuation WHERE assetId=?1)
|
||||
+ (SELECT COUNT(*) FROM ReconcileProposal WHERE assetId=?1) AS n`, [id]).n;
|
||||
if (used > 0) fail('assets.inUse', { n: used }, `The asset is used by ${used} record(s).`);
|
||||
trackDelete('Asset', id, () => db.run(`DELETE FROM Asset WHERE id=?`, [id]));
|
||||
await db.persist();
|
||||
}
|
||||
Reference in new issue
Block a user