Files
Umbrella/frontend/src/routes/accounting/account.svelte
T
StephanRichter 170a551169 adding title tag
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
2026-04-25 20:15:05 +02:00

138 lines
3.2 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script>
import { onMount } from 'svelte';
import { api, get } from '../../urls.svelte';
import { error, yikes } from '../../warn.svelte';
import { t } from '../../translations.svelte';
import EntryForm from './add_entry.svelte';
import Transaction from './transaction.svelte';
let { id } = $props();
let account = $state(null);
let filter = $state([]);
let transactions = $state([]);
let filtered = $derived(transactions.filter(t => checker(t.tags,filter)));
let users = {};
let sums = $derived.by(calcSums);
function calcSums(){
let sums = {};
sums[0] = 0;
for (let user of Object.values(users)) sums[user.id] = 0;
for (let transaction of filtered) {
for (let user of Object.values(users)){
if (user.id == transaction.destination.id) sums[user.id] += transaction.amount;
if (user.id == transaction.source.id) sums[user.id] -= transaction.amount;
}
if (!transaction.destination.id) sums[0] += transaction.amount;
if (!transaction.source.id) sums[0] -= transaction.amount;
}
window.setTimeout(scrollToBottom,100);
return sums;
}
function addToFilter(tag){
filter.push(tag.toLowerCase());
}
function checker(taglist, filter){
for (var f of filter){
var included = false;
for (var t of taglist){
if (t.toLowerCase() == f && (included = true)) break;
}
if (!included) return false;
}
return true;
}
function dropTag(tag){
filter = filter.filter(x => x != tag.toLowerCase());
}
async function load(){
let url = api(`accounting/${id}`);
let res = await get(url);
if (res.ok) {
yikes();
let json = await res.json();
transactions = json.transactions;
users = json.user_list;
account = json.account;
} else error(res);
}
function onSave(){
load();
}
function scrollToBottom(){
window.scrollTo(0, document.body.scrollHeight);
}
onMount(load);
</script>
<style>
.amount{ text-align: right }
</style>
<svelte:head>
{#if account}
<title>Umbrella {account.name}</title>
{/if}
</svelte:head>
{#if filter.length > 0}
<fieldset>
<legend>{t('filter by tags')}</legend>
<div class="taglist">
{#each filter as tag,i}
<span class="tag">{tag}&nbsp;<button onclick={() => dropTag(tag)} class="symbol"></button></span>
{/each}
</div>
</fieldset>
{/if}
{#if account}
<fieldset>
<legend>{account.name}</legend>
<table class="account">
<thead>
<tr>
<th>{t('date')}</th>
{#each Object.entries(users) as [id,user]}
<th>{user.name}</th>
{/each}
<th>{t('other party')}</th>
<th>{t('purpose')}</th>
<th>{t('tags')}</th>
</tr>
</thead>
<tbody>
{#each filtered as transaction, i}
<Transaction {account} {addToFilter} {transaction} {users} />
{/each}
<tr class="sums">
<td>
<br/>
{t('sums')}
</td>
{#each Object.entries(users) as [id,user]}
<th class="amount">
{user.name}<br/>
{sums[id].toFixed(2)}&nbsp;{account.currency}
</th>
{/each}
<td class="amount">
<br/>
{sums[0].toFixed(2)}&nbsp;{account.currency}
</td>
<td colspan="2"></td>
</tr>
</tbody>
</table>
</fieldset>
<EntryForm {account} {onSave} />
{/if}