170a551169
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
138 lines
3.2 KiB
Svelte
138 lines
3.2 KiB
Svelte
<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} <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)} {account.currency}
|
||
</th>
|
||
{/each}
|
||
<td class="amount">
|
||
<br/>
|
||
{sums[0].toFixed(2)} {account.currency}
|
||
</td>
|
||
<td colspan="2"></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</fieldset>
|
||
|
||
<EntryForm {account} {onSave} />
|
||
{/if} |