Adds expense approval workflow

Implements expense approval functionality, allowing superusers to review and approve or reject expense entries.

This includes:
- Filtering account balance calculations and user balance calculations to only include cleared journal entries.
- Adding API endpoints to retrieve pending expense entries and approve/reject them.
- Updating the UI to display pending expenses to superusers and provide actions to approve or reject them.

This ensures better control over expenses within the system.
This commit is contained in:
padreug 2025-10-23 00:26:52 +02:00
parent 8221feec20
commit 018a074915
4 changed files with 232 additions and 8 deletions

View file

@ -154,6 +154,60 @@
</q-card-section>
</q-card>
<!-- Pending Expense Entries (Super User Only) -->
<q-card v-if="isSuperUser && pendingExpenses.length > 0">
<q-card-section>
<h6 class="q-my-none q-mb-md">Pending Expense Approvals</h6>
<q-list separator>
<q-item v-for="entry in pendingExpenses" :key="entry.id">
<q-item-section avatar>
<q-icon name="pending" color="orange" size="sm">
<q-tooltip>Pending approval</q-tooltip>
</q-icon>
</q-item-section>
<q-item-section>
<q-item-label>{% raw %}{{ entry.description }}{% endraw %}</q-item-label>
<q-item-label caption>
{% raw %}{{ formatDate(entry.entry_date) }}{% endraw %}
</q-item-label>
<q-item-label caption v-if="entry.meta && entry.meta.user_id">
User: {% raw %}{{ entry.meta.user_id.substring(0, 16) }}...{% endraw %}
</q-item-label>
<q-item-label caption v-if="entry.reference" class="text-grey">
Ref: {% raw %}{{ entry.reference }}{% endraw %}
</q-item-label>
</q-item-section>
<q-item-section side>
<q-item-label>{% raw %}{{ formatSats(getTotalAmount(entry)) }} sats{% endraw %}</q-item-label>
<q-item-label caption v-if="getEntryFiatAmount(entry)">
{% raw %}{{ getEntryFiatAmount(entry) }}{% endraw %}
</q-item-label>
</q-item-section>
<q-item-section side>
<div class="q-gutter-xs">
<q-btn
size="sm"
color="positive"
@click="approveExpense(entry.id)"
:loading="entry.approving"
>
Approve
</q-btn>
<q-btn
size="sm"
color="negative"
@click="rejectExpense(entry.id)"
:loading="entry.rejecting"
>
Reject
</q-btn>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card-section>
</q-card>
<!-- Pending Manual Payment Requests (Super User Only) -->
<q-card v-if="isSuperUser && pendingManualPaymentRequests.length > 0">
<q-card-section>