From fb3f659831c1e164a315d01d7982890f2693ea2e Mon Sep 17 00:00:00 2001 From: Minz Date: Tue, 3 Feb 2026 12:16:29 +0100 Subject: [PATCH] Receipts: Historical stats command --- commands/receipts/receiptCommands.js | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/commands/receipts/receiptCommands.js b/commands/receipts/receiptCommands.js index 4b41581..5fd986d 100644 --- a/commands/receipts/receiptCommands.js +++ b/commands/receipts/receiptCommands.js @@ -29,6 +29,11 @@ module.exports = { .setDescription('Show spendings from the previous budget cycle instead of the current one') .setRequired(false) ) + ) + .addSubcommand(subcommand => + subcommand + .setName('stats') + .setDescription('View detailed spending and savings statistics') ), async execute(interaction) { console.log('budget command entrypoint'); @@ -100,6 +105,47 @@ module.exports = { await interaction.reply({ embeds: [budgetEmbed] }); break + case 'stats': + const allBudgets = db.prepare(` + SELECT id, budget_amount, exchange_rate, start_date, end_date + FROM weekly_budgets + ORDER BY start_date DESC + LIMIT 4 + `).all(); + + let statsDescription = ""; + let cumulativeSavingsEur = 0; + + for (const budgetPeriod of allBudgets) { + const periodSpendings = db.prepare(` + SELECT amount + FROM grocery_spendings + WHERE budget_id = ? AND discord_id = ? + `).all(budgetPeriod.id, interaction.member.id); + + const totalSpentInPeriodEur = periodSpendings.reduce((acc, s) => acc + s.amount, 0); + const savedInPeriodEur = budgetPeriod.budget_amount - totalSpentInPeriodEur; + cumulativeSavingsEur += savedInPeriodEur; + + statsDescription += `**Period: ${budgetPeriod.start_date} - ${budgetPeriod.end_date}**\n`; + statsDescription += `Budget: ${budgetPeriod.budget_amount.toFixed(2)}€\n`; + statsDescription += `Spent: ${totalSpentInPeriodEur.toFixed(2)}€ (${(totalSpentInPeriodEur * budgetPeriod.exchange_rate).toFixed(2)} kr)\n`; + statsDescription += `Saved: ${savedInPeriodEur.toFixed(2)}€ (${(savedInPeriodEur * budgetPeriod.exchange_rate).toFixed(2)} kr)\n`; + statsDescription += `Cumulative: ${cumulativeSavingsEur.toFixed(2)}€\n\n`; + } + + if (allBudgets.length === 0) { + statsDescription = "No budget periods on record."; + } + + const statsEmbed = new EmbedBuilder() + .setColor(0x0099ff) + .setTitle(`${interaction.member.displayName}'s Budget Statistics`) + .setDescription(statsDescription) + .setTimestamp(); + + await interaction.reply({ embeds: [statsEmbed] }); + break; default: await interaction.reply(`Sub mismatch. Switching on ${interaction.options.getSubcommand()}`); break;