From c2bfd8ca7ae128f3738b45cdfe3a92ff2e28d1a6 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Sat, 7 Jun 2025 17:30:37 +1000 Subject: [PATCH] Error when inputting commodity with no cost base --- src/amounts.ts | 15 +++++++++------ src/components/TransactionEditor.vue | 13 +++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/amounts.ts b/src/amounts.ts index e63443c..808f6bc 100644 --- a/src/amounts.ts +++ b/src/amounts.ts @@ -1,6 +1,6 @@ /* DrCr: Web-based double-entry bookkeeping framework - Copyright (C) 2022–2025 Lee Yingtong Li (RunasSudo) + Copyright (C) 2022-2025 Lee Yingtong Li (RunasSudo) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -17,6 +17,7 @@ */ import { db } from './db.ts'; +import { ppWithCommodity } from './display.ts'; export interface Amount { quantity: number; @@ -56,18 +57,20 @@ export function asCost(quantity: number, commodity: string): number { if (commodity === db.metadata.reporting_commodity) { return quantity; } - if (commodity.indexOf('{{') >= 0) { + if (commodity.indexOf(' {{') >= 0) { // Total price - const price = parseFloat(commodity.substring(commodity.indexOf('{{') + 2, commodity.indexOf('}}', commodity.indexOf('{{')))); + const price = parseFloat(commodity.substring(commodity.indexOf(' {{') + 3, commodity.indexOf('}}', commodity.indexOf(' {{')))); // Multiply by Math.sign(quantity) in case the quantity is negative // FIXME: This yields unexpected results when trying to deduct a partial amount from a commodity specified in total price terms return Math.round(Math.sign(quantity) * price * Math.pow(10, db.metadata.dps)); } - if (commodity.indexOf('{') >= 0) { + if (commodity.indexOf(' {') >= 0) { // Unit price - const price = parseFloat(commodity.substring(commodity.indexOf('{') + 1, commodity.indexOf('}', commodity.indexOf('{')))); + const price = parseFloat(commodity.substring(commodity.indexOf(' {') + 2, commodity.indexOf('}', commodity.indexOf(' {')))); return Math.round(quantity * price); } - throw new Error('No cost base specified: ' + quantity + ' ' + commodity); + throw new NoCostBaseError('No cost base specified: ' + ppWithCommodity(quantity, commodity)); } + +export class NoCostBaseError extends Error {} diff --git a/src/components/TransactionEditor.vue b/src/components/TransactionEditor.vue index 333532a..ee60f32 100644 --- a/src/components/TransactionEditor.vue +++ b/src/components/TransactionEditor.vue @@ -109,6 +109,7 @@ import { ref } from 'vue'; + import { asCost, NoCostBaseError } from '../amounts.ts'; import { DT_FORMAT, DeserialiseAmountError, Posting, Transaction, db, deserialiseAmount } from '../db.ts'; import ComboBoxAccounts from './ComboBoxAccounts.vue'; @@ -167,6 +168,18 @@ } } + // If not in reporting commodity, check the amount specifies a cost base + try { + asCost(amount_abs.quantity, amount_abs.commodity); + } catch (err) { + if (err instanceof NoCostBaseError) { + error.value = err.message; + return; + } else { + throw err; + } + } + newTransaction.postings.push({ id: posting.id, description: posting.description,