2024-01-16 15:13:04 +00:00
|
|
|
<template>
|
|
|
|
<div>
|
|
|
|
<router-link
|
|
|
|
to="/"
|
|
|
|
class="d-flex align-items-center fs-5 mb-3 mb-md-0 me-md-auto text-start text-white text-decoration-none"
|
|
|
|
>
|
|
|
|
<i class="fas fa-fw fa-hand-holding-dollar me-2" />
|
|
|
|
My Budget
|
|
|
|
</router-link>
|
2024-01-20 23:52:45 +00:00
|
|
|
|
2024-01-16 15:13:04 +00:00
|
|
|
<hr>
|
2024-01-20 23:52:45 +00:00
|
|
|
|
2024-01-16 15:13:04 +00:00
|
|
|
<ul class="list-unstyled lh-lg ps-0">
|
2024-01-20 23:51:47 +00:00
|
|
|
<acc-list
|
|
|
|
:accounts="budgetAccounts"
|
|
|
|
header="Budget"
|
|
|
|
/>
|
|
|
|
<acc-list
|
|
|
|
:accounts="trackingAccounts"
|
|
|
|
header="Tracking"
|
|
|
|
/>
|
2024-01-16 15:13:04 +00:00
|
|
|
</ul>
|
2024-01-20 23:52:45 +00:00
|
|
|
|
2024-01-16 15:13:04 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm w-100"
|
|
|
|
data-bs-toggle="modal"
|
|
|
|
data-bs-target="#createAccountModal"
|
|
|
|
>
|
|
|
|
<i class="fas fa-fw fa-circle-plus mr-1" />
|
|
|
|
Add Account
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<div
|
|
|
|
id="createAccountModal"
|
|
|
|
ref="createAccountModal"
|
|
|
|
class="modal fade"
|
|
|
|
tabindex="-1"
|
2024-01-17 22:02:41 +00:00
|
|
|
aria-labelledby="createAccountModalLabel"
|
2024-01-16 15:13:04 +00:00
|
|
|
aria-hidden="true"
|
|
|
|
>
|
|
|
|
<div class="modal-dialog modal-sm">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h1
|
2024-01-17 22:02:41 +00:00
|
|
|
id="createAccountModalLabel"
|
2024-01-16 15:13:04 +00:00
|
|
|
class="modal-title fs-5"
|
|
|
|
>
|
|
|
|
Add Account
|
|
|
|
</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="createAccountModalName"
|
|
|
|
class="form-label"
|
|
|
|
>Account Name</label>
|
|
|
|
<input
|
|
|
|
id="createAccountModalName"
|
|
|
|
v-model.trim="modals.addAccount.name"
|
|
|
|
type="text"
|
|
|
|
class="form-control"
|
|
|
|
required
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label
|
|
|
|
for="createAccountModalType"
|
|
|
|
class="form-label"
|
|
|
|
>Account Type</label>
|
|
|
|
<select
|
|
|
|
v-model="modals.addAccount.type"
|
|
|
|
class="form-select"
|
|
|
|
>
|
|
|
|
<option value="budget">
|
|
|
|
Budget
|
|
|
|
</option>
|
|
|
|
<option value="tracking">
|
|
|
|
Tracking
|
|
|
|
</option>
|
|
|
|
<option value="category">
|
|
|
|
Category
|
|
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label
|
|
|
|
for="createAccountModalBalance"
|
|
|
|
class="form-label"
|
|
|
|
>Starting Balance</label>
|
|
|
|
<div class="input-group">
|
|
|
|
<input
|
|
|
|
id="createAccountModalBalance"
|
|
|
|
v-model.number="modals.addAccount.startingBalance"
|
|
|
|
type="number"
|
|
|
|
step="0.01"
|
|
|
|
class="form-control"
|
|
|
|
>
|
|
|
|
<span class="input-group-text">€</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="btn btn-primary"
|
|
|
|
@click="addAccount"
|
|
|
|
>
|
|
|
|
<i class="fas fa-fw fa-circle-plus mr-1" />
|
|
|
|
Add
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2024-01-17 22:02:41 +00:00
|
|
|
/* eslint-disable sort-imports */
|
2024-01-16 15:13:04 +00:00
|
|
|
import { Modal } from 'bootstrap'
|
|
|
|
|
2024-01-20 23:51:47 +00:00
|
|
|
import accList from './accountsSidebarAccList.vue'
|
|
|
|
|
2024-01-17 22:02:41 +00:00
|
|
|
import { formatNumber } from '../helpers'
|
2024-01-16 16:30:17 +00:00
|
|
|
import { unallocatedMoneyAcc } from '../constants'
|
2024-01-16 15:13:04 +00:00
|
|
|
|
|
|
|
export default {
|
2024-01-20 23:51:47 +00:00
|
|
|
components: { accList },
|
|
|
|
|
2024-01-16 15:13:04 +00:00
|
|
|
computed: {
|
|
|
|
budgetAccounts() {
|
|
|
|
const accs = (this.accounts || []).filter(acc => acc.type === 'budget')
|
|
|
|
accs.sort((a, b) => a.name.localeCompare(b.name))
|
|
|
|
return accs
|
|
|
|
},
|
|
|
|
|
|
|
|
budgetSum() {
|
|
|
|
return this.budgetAccounts.reduce((sum, acc) => sum + acc.balance, 0)
|
|
|
|
},
|
|
|
|
|
|
|
|
trackingAccounts() {
|
|
|
|
const accs = (this.accounts || []).filter(acc => acc.type === 'tracking')
|
|
|
|
accs.sort((a, b) => a.name.localeCompare(b.name))
|
|
|
|
return accs
|
|
|
|
},
|
|
|
|
|
|
|
|
trackingSum() {
|
|
|
|
return this.trackingAccounts.reduce((sum, acc) => sum + acc.balance, 0)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
modals: {
|
|
|
|
addAccount: {
|
|
|
|
name: '',
|
|
|
|
startingBalance: 0,
|
|
|
|
type: 'budget',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
addAccount() {
|
|
|
|
return fetch('/api/accounts', {
|
|
|
|
body: JSON.stringify({
|
|
|
|
name: this.modals.addAccount.name,
|
|
|
|
type: this.modals.addAccount.type,
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
method: 'POST',
|
|
|
|
})
|
|
|
|
.then(resp => resp.json())
|
|
|
|
.then(account => {
|
|
|
|
if (account.type === 'budget') {
|
|
|
|
return fetch('/api/transactions', {
|
|
|
|
body: JSON.stringify({
|
|
|
|
account: account.id,
|
|
|
|
amount: this.modals.addAccount.startingBalance,
|
2024-01-16 16:30:17 +00:00
|
|
|
category: unallocatedMoneyAcc,
|
2024-01-16 15:13:04 +00:00
|
|
|
cleared: true,
|
|
|
|
description: 'Starting Balance',
|
|
|
|
time: new Date(),
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
method: 'POST',
|
|
|
|
})
|
|
|
|
} else if (account.type === 'tracking') {
|
|
|
|
return fetch('/api/transactions', {
|
|
|
|
body: JSON.stringify({
|
|
|
|
account: account.id,
|
|
|
|
amount: this.modals.addAccount.startingBalance,
|
|
|
|
cleared: true,
|
|
|
|
description: 'Starting Balance',
|
|
|
|
time: new Date(),
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
method: 'POST',
|
|
|
|
})
|
|
|
|
} else if (account.type === 'category') {
|
2024-01-16 16:30:17 +00:00
|
|
|
return fetch(`/api/accounts/${unallocatedMoneyAcc}/transfer/${account.id}?amount=${this.modals.addAccount.startingBalance}`, {
|
2024-01-16 15:13:04 +00:00
|
|
|
method: 'PUT',
|
|
|
|
})
|
|
|
|
}
|
|
|
|
throw new Error('invalid account type detected')
|
|
|
|
})
|
|
|
|
.then(() => this.$emit('update-accounts'))
|
|
|
|
.then(() => {
|
|
|
|
Modal.getInstance(this.$refs.createAccountModal).toggle()
|
|
|
|
|
|
|
|
this.modals.addAccount = {
|
|
|
|
name: '',
|
|
|
|
startingBalance: 0,
|
|
|
|
type: 'budget',
|
|
|
|
}
|
|
|
|
})
|
|
|
|
},
|
2024-01-17 22:02:41 +00:00
|
|
|
|
|
|
|
formatNumber,
|
2024-01-16 15:13:04 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
name: 'AccountingAppSidebar',
|
|
|
|
|
|
|
|
props: {
|
|
|
|
accounts: {
|
|
|
|
required: true,
|
|
|
|
type: Array,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
</script>
|