master: change repo
This commit is contained in:
276
src/views/transactions/TransactionItem.vue
Normal file
276
src/views/transactions/TransactionItem.vue
Normal file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<div v-if="transaction">
|
||||
<h4 class="subtitle is-4">{{ transaction.date | fulldate }}</h4>
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs" v-if="account">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link
|
||||
:to="{ name: 'account', params: { id: account._id }, hash: `#${transaction._id}` }"
|
||||
>{{ account.name }}</router-link>
|
||||
</li>
|
||||
<li class="is-active" v-if="transaction.tag && transaction.tag !== noTag">
|
||||
<a href="#" @click.prevent>{{ transactionTagLabel[transaction.tag].label }}</a>
|
||||
</li>
|
||||
<li class="is-active">
|
||||
<a href="#" @click.prevent>{{ transaction.name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="resume">
|
||||
Dépense payée par
|
||||
<span class="pay-by">{{ transaction.payBy }}</span>
|
||||
pour
|
||||
<span v-if="payForLabel.length > 1">{{ payForLabel.join(', ') }}</span>
|
||||
<span v-else>{{ payForLabel[0] }}</span>
|
||||
d'une somme de
|
||||
<span
|
||||
class="numeric"
|
||||
>{{ transaction.amount | money(transaction.mainCurrency) }}</span>.
|
||||
</div>
|
||||
<div v-if="transaction.exchange" class="exchange">
|
||||
<div v-if="currencies.length">
|
||||
<hr />
|
||||
<h2 class="subtitle is-2">Taux d'échange à date</h2>
|
||||
<div class="columns is-centered">
|
||||
<div class="column">
|
||||
<table class="table is-fullwidth is-striped is-bordered">
|
||||
<caption>
|
||||
<span class="numeric">{{ transaction.amount | money(transaction.mainCurrency) }}</span>
|
||||
</caption>
|
||||
<tbody>
|
||||
<tr v-for="(currency, k) in currencies" :key="k">
|
||||
<td
|
||||
class="numeric"
|
||||
>{{ (transaction.amount * transaction.exchange.rates[currency.code]) | moneypad(currency) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="column">
|
||||
<table class="table is-fullwidth is-striped is-bordered">
|
||||
<caption>
|
||||
<span class="numeric">{{ 1 | money(transaction.mainCurrency) }}</span>
|
||||
</caption>
|
||||
<tbody>
|
||||
<tr v-for="(currency, k) in currencies" :key="k">
|
||||
<td
|
||||
class="numeric"
|
||||
>{{ ( transaction.exchange.rates[currency.code]) | moneypad(currency) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="column">
|
||||
<table class="table is-hoverable is-fullwidth is-striped is-bordered">
|
||||
<caption>{{ $tc('transaction.money', currencies.length) }}</caption>
|
||||
<tbody>
|
||||
<tr v-for="(currency, k) in currencies" :key="k">
|
||||
<td>{{ 1 | money(currency) }}</td>
|
||||
<td
|
||||
class="numeric"
|
||||
>{{ (1 / transaction.exchange.rates[currency.code]) | moneypad(transaction.mainCurrency) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<online-view @online="retrieveExchange" />Le taux d'échange n'a pas pu être récupéré.
|
||||
</div>
|
||||
<div class="buttons is-centered">
|
||||
<router-link
|
||||
v-if="canModify"
|
||||
tag="button"
|
||||
class="button"
|
||||
:to="{ name: 'transaction-update', params: { id } }"
|
||||
>modifier</router-link>
|
||||
<confirm-button class="is-danger" @confirm="removeTransaction">supprimer</confirm-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator'
|
||||
import { Getter } from 'vuex-class'
|
||||
import TransactionType from '@/enums/TransactionType'
|
||||
import bus, { SYNC } from '@/utils/bus-event'
|
||||
import notif from '@/utils/notif'
|
||||
import TransactionTag, { TransactionTagLabel } from '@/enums/TransactionTag'
|
||||
import accountService from '@/services/AccountService'
|
||||
import exchangeService from '@/services/ExchangeService'
|
||||
import transactionService from '@/services/TransactionService'
|
||||
import IAccount from '@/models/IAccount'
|
||||
import ICurrency from '@/models/ICurrency'
|
||||
import ITransaction from '@/models/ITransaction'
|
||||
import IUser from '@/models/IUser'
|
||||
import ISplit from '@/models/ISplit'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
'online-view': () => import('@/components/OnlineView.vue'),
|
||||
'confirm-button': () => import('@/components/ConfirmButton.vue')
|
||||
}
|
||||
})
|
||||
export default class TransactionItem extends Vue {
|
||||
@Getter
|
||||
public user!: IUser | null
|
||||
@Prop({ type: String, required: true })
|
||||
public id!: string
|
||||
public transaction: ITransaction | null = null
|
||||
public account: IAccount | null = null
|
||||
public noTag: string = TransactionTag.None
|
||||
public transactionTagLabel: typeof TransactionTagLabel = TransactionTagLabel
|
||||
public removing: boolean = false
|
||||
|
||||
public created(): void {
|
||||
this.getData()
|
||||
bus.$on(SYNC, this.getData)
|
||||
}
|
||||
|
||||
public beforeDestroy(): void {
|
||||
bus.$off(SYNC, this.getData)
|
||||
}
|
||||
|
||||
public async getData(docIds?: string[]): Promise<void> {
|
||||
if (docIds && !docIds.find((i: string) => i === this.id)) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
if (this.removing) {
|
||||
return
|
||||
}
|
||||
this.transaction = await transactionService.get(this.id)
|
||||
if (this.transaction) {
|
||||
this.account = await accountService.get(this.accountId)
|
||||
} else {
|
||||
if (this.accountId) {
|
||||
this.$router.push({ name: 'account', params: { id: this.accountId } })
|
||||
notif.alert('Transaction supprimée.')
|
||||
} else {
|
||||
this.$router.push({ name: 'home' })
|
||||
notif.alert('Compte inexistant.')
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// tslint:disable-next-line
|
||||
console.warn({ error })
|
||||
this.$router.push({ name: 'home' })
|
||||
}
|
||||
}
|
||||
|
||||
public async removeTransaction(): Promise<void> {
|
||||
if (!this.transaction) {
|
||||
return
|
||||
}
|
||||
this.removing = true
|
||||
const ok: boolean = await transactionService.remove(this.id)
|
||||
if (ok) {
|
||||
if (this.accountId) {
|
||||
this.$router.push({
|
||||
name: 'account',
|
||||
params: {
|
||||
id: this.accountId
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$router.push({ name: 'home' })
|
||||
}
|
||||
}
|
||||
this.removing = false
|
||||
}
|
||||
|
||||
public async retrieveExchange(): Promise<void> {
|
||||
if (this.transaction && !this.transaction.exchange) {
|
||||
this.transaction.exchange = await exchangeService.get(
|
||||
this.transaction.mainCurrency.code,
|
||||
this.transaction.date
|
||||
)
|
||||
await transactionService.save(this.transaction)
|
||||
}
|
||||
}
|
||||
|
||||
public get accountId(): string {
|
||||
return (this.transaction && this.transaction.accountId) || ''
|
||||
}
|
||||
|
||||
public get canModify(): boolean {
|
||||
if (!this.transaction) {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
(this.transaction.transactionType === TransactionType.normal &&
|
||||
this.isAdmin) ||
|
||||
this.transaction.payBy === this.userAlias
|
||||
)
|
||||
}
|
||||
|
||||
public get userAlias(): string | undefined {
|
||||
if (!this.account || !this.user) {
|
||||
return ''
|
||||
}
|
||||
const user = this.user
|
||||
return this.account.users
|
||||
.map((u: IUser) => u.slugEmail)
|
||||
.find((email: string | undefined) => email === user.slugEmail)
|
||||
}
|
||||
|
||||
public get isAdmin(): boolean {
|
||||
if (!this.account || !this.user) {
|
||||
return true
|
||||
}
|
||||
return (
|
||||
!this.account.admin ||
|
||||
this.account.admin.slugEmail === this.user.slugEmail
|
||||
)
|
||||
}
|
||||
|
||||
public get payForLabel(): string[] {
|
||||
if (!this.transaction) {
|
||||
return []
|
||||
}
|
||||
return this.transaction.payFor.map((p: ISplit) => {
|
||||
const part =
|
||||
p.weight > 1
|
||||
? `(${p.weight} ${this.$tc('transaction.weight', p.weight)})`
|
||||
: ''
|
||||
return `${p.alias} ${part}`.trim()
|
||||
})
|
||||
}
|
||||
|
||||
public get currencies(): ICurrency[] {
|
||||
if (!this.transaction || !this.transaction.exchange) {
|
||||
return []
|
||||
}
|
||||
const transaction = this.transaction
|
||||
const exchange = transaction.exchange
|
||||
return transaction.currencies.filter(
|
||||
(currency: ICurrency) => exchange && currency.code !== exchange.base
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
p.resume {
|
||||
font-size: 18pt;
|
||||
margin: 15px 0;
|
||||
}
|
||||
table.table {
|
||||
margin: 15px auto 0;
|
||||
max-width: 350px;
|
||||
}
|
||||
.main-cell {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.buttons {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.pay-by {
|
||||
font-weight: bold;
|
||||
}
|
||||
.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user