Add transfers
This commit is contained in:
parent
5779e9e8a9
commit
cfc9a677af
2 changed files with 208 additions and 48 deletions
|
@ -3,7 +3,6 @@
|
|||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<!-- TODO: Add time-selector -->
|
||||
<range-selector
|
||||
v-model="timeRange"
|
||||
/>
|
||||
|
@ -15,7 +14,7 @@
|
|||
<div class="btn-group btn-group-sm">
|
||||
<button
|
||||
class="btn"
|
||||
@click="showAddTransaction = true"
|
||||
@click="showAddTransaction = !showAddTransaction"
|
||||
>
|
||||
<i class="fas fa-fw fa-plus-circle mr-1" />
|
||||
Add Transaction
|
||||
|
|
|
@ -1,60 +1,175 @@
|
|||
<template>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col d-flex align-items-center">
|
||||
<range-selector
|
||||
v-model="timeRange"
|
||||
:multi-month="false"
|
||||
/>
|
||||
<div>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col d-flex align-items-center">
|
||||
<range-selector
|
||||
v-model="timeRange"
|
||||
:multi-month="false"
|
||||
/>
|
||||
</div>
|
||||
<div class="col d-flex align-items-center justify-content-center">
|
||||
<div :class="unallocatedMoneyClass">
|
||||
<span class="fs-4">{{ formatNumber(unallocatedMoney) }} €</span>
|
||||
<span class="small">Unallocated</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col d-flex align-items-center justify-content-end">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button
|
||||
class="btn"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#transferMoneyModal"
|
||||
>
|
||||
<i class="fas fa-fw fa-arrow-right-arrow-left mr-1" />
|
||||
Add Transfer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col d-flex align-items-center justify-content-end">
|
||||
<div :class="unallocatedMoneyClass">
|
||||
<span class="fs-4">{{ formatNumber(unallocatedMoney) }} €</span>
|
||||
<span class="small">Unallocated</span>
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
<table class="table table-striped small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th class="text-end">
|
||||
Allocated
|
||||
</th>
|
||||
<th class="text-end">
|
||||
Activity
|
||||
</th>
|
||||
<th class="text-end">
|
||||
Available
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="cat in categories"
|
||||
:key="cat.id"
|
||||
>
|
||||
<td>{{ cat.name }}</td>
|
||||
<td :class="{'text-end': true, 'text-danger': (allocatedByCategory[cat.id] || 0) < 0}">
|
||||
{{ formatNumber(allocatedByCategory[cat.id] || 0) }} €
|
||||
</td>
|
||||
<td :class="{'text-end': true, 'text-danger': (activityByCategory[cat.id] || 0) < 0}">
|
||||
{{ formatNumber(activityByCategory[cat.id] || 0) }} €
|
||||
</td>
|
||||
<td :class="{'text-end': true, 'text-danger': cat.balance < 0}">
|
||||
{{ formatNumber(cat.balance) }} €
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
<table class="table table-striped small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th class="text-end">
|
||||
Allocated
|
||||
</th>
|
||||
<th class="text-end">
|
||||
Activity
|
||||
</th>
|
||||
<th class="text-end">
|
||||
Available
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="cat in categories"
|
||||
:key="cat.id"
|
||||
|
||||
<div
|
||||
id="transferMoneyModal"
|
||||
ref="transferMoneyModal"
|
||||
class="modal fade"
|
||||
tabindex="-1"
|
||||
aria-labelledby="transferMoneyModalLabel"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1
|
||||
id="transferMoneyModalLabel"
|
||||
class="modal-title fs-5"
|
||||
>
|
||||
<td>{{ cat.name }}</td>
|
||||
<td :class="{'text-end': true, 'text-danger': (allocatedByCategory[cat.id] || 0) < 0}">
|
||||
{{ formatNumber(allocatedByCategory[cat.id] || 0) }} €
|
||||
</td>
|
||||
<td :class="{'text-end': true, 'text-danger': (activityByCategory[cat.id] || 0) < 0}">
|
||||
{{ formatNumber(activityByCategory[cat.id] || 0) }} €
|
||||
</td>
|
||||
<td :class="{'text-end': true, 'text-danger': cat.balance < 0}">
|
||||
{{ formatNumber(cat.balance) }} €
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
Transfer Money
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
/>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label
|
||||
for="transferMoneyModalFrom"
|
||||
class="form-label"
|
||||
>From</label>
|
||||
<select
|
||||
id="transferMoneyModalFrom"
|
||||
v-model="modals.createTransfer.from"
|
||||
class="form-select"
|
||||
>
|
||||
<option
|
||||
v-for="cat in transferableCategories"
|
||||
:key="cat.id"
|
||||
:value="cat.id"
|
||||
>
|
||||
{{ cat.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label
|
||||
for="transferMoneyModalTo"
|
||||
class="form-label"
|
||||
>To</label>
|
||||
<select
|
||||
id="transferMoneyModalTo"
|
||||
v-model="modals.createTransfer.to"
|
||||
class="form-select"
|
||||
>
|
||||
<option
|
||||
v-for="cat in transferableCategories"
|
||||
:key="cat.id"
|
||||
:value="cat.id"
|
||||
>
|
||||
{{ cat.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label
|
||||
for="transferMoneyModalAmount"
|
||||
class="form-label"
|
||||
>Amount</label>
|
||||
<div class="input-group">
|
||||
<input
|
||||
id="transferMoneyModalAmount"
|
||||
v-model.number="modals.createTransfer.amount"
|
||||
type="number"
|
||||
min="0.01"
|
||||
step="0.01"
|
||||
class="form-control text-end"
|
||||
>
|
||||
<span class="input-group-text">€</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
:disabled="!transferModalValid"
|
||||
@click="transferMoney"
|
||||
>
|
||||
<i class="fas fa-fw fa-arrow-right-arrow-left mr-1" />
|
||||
Transfer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint-disable sort-imports */
|
||||
import { Modal } from 'bootstrap'
|
||||
|
||||
import { formatNumber } from '../helpers'
|
||||
import rangeSelector from './rangeSelector.vue'
|
||||
import { unallocatedMoneyAcc } from '../constants'
|
||||
|
@ -89,6 +204,25 @@ export default {
|
|||
return accounts
|
||||
},
|
||||
|
||||
transferModalValid() {
|
||||
if (!this.modals.createTransfer.from || !this.modals.createTransfer.to) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.modals.createTransfer.from === this.modals.createTransfer.to) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
|
||||
transferableCategories() {
|
||||
const accounts = this.accounts
|
||||
.filter(acc => acc.type === 'category')
|
||||
accounts.sort((a, b) => a.name.localeCompare(b.name))
|
||||
return accounts
|
||||
},
|
||||
|
||||
unallocatedMoney() {
|
||||
const acc = this.accounts.filter(acc => acc.id === unallocatedMoneyAcc)[0] || null
|
||||
if (acc === null) {
|
||||
|
@ -98,7 +232,7 @@ export default {
|
|||
},
|
||||
|
||||
unallocatedMoneyClass() {
|
||||
const classes = ['d-inline-flex', 'flex-column', 'text-center', 'ms-auto', 'p-2', 'rounded']
|
||||
const classes = ['d-inline-flex', 'flex-column', 'text-center', 'p-2', 'rounded']
|
||||
if (this.unallocatedMoney < 0) {
|
||||
classes.push('bg-danger')
|
||||
} else if (this.unallocatedMoney === 0) {
|
||||
|
@ -113,6 +247,14 @@ export default {
|
|||
|
||||
data() {
|
||||
return {
|
||||
modals: {
|
||||
createTransfer: {
|
||||
amount: 0,
|
||||
from: unallocatedMoneyAcc,
|
||||
to: '',
|
||||
},
|
||||
},
|
||||
|
||||
timeRange: {},
|
||||
transactions: [],
|
||||
}
|
||||
|
@ -131,6 +273,25 @@ export default {
|
|||
},
|
||||
|
||||
formatNumber,
|
||||
|
||||
transferMoney() {
|
||||
const params = new URLSearchParams()
|
||||
params.set('amount', this.modals.createTransfer.amount.toFixed(2))
|
||||
|
||||
return fetch(`/api/accounts/${this.modals.createTransfer.from}/transfer/${this.modals.createTransfer.to}?${params.toString()}`, {
|
||||
method: 'PUT',
|
||||
})
|
||||
.then(() => {
|
||||
this.$emit('update-accounts')
|
||||
Modal.getInstance(this.$refs.transferMoneyModal).toggle()
|
||||
|
||||
this.modals.createTransfer = {
|
||||
amount: 0,
|
||||
from: unallocatedMoneyAcc,
|
||||
to: '',
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
name: 'AccountingAppBudgetDashboard',
|
||||
|
|
Loading…
Reference in a new issue