Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117907954
D4809.1775392627.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None
D4809.1775392627.diff
View Options
diff --git a/src/app/Http/Controllers/API/V4/WalletsController.php b/src/app/Http/Controllers/API/V4/WalletsController.php
--- a/src/app/Http/Controllers/API/V4/WalletsController.php
+++ b/src/app/Http/Controllers/API/V4/WalletsController.php
@@ -115,21 +115,42 @@
return $this->errorResponse(403);
}
+ $pageSize = 10;
+ $page = intval(request()->input('page')) ?: 1;
+ $hasMore = false;
+
$result = $wallet->payments()
- ->selectRaw('distinct date_format(updated_at, "%Y-%m") as ident')
+ ->selectRaw('date_format(updated_at, "%Y-%m") as ident, sum(amount) as total')
->where('status', Payment::STATUS_PAID)
->where('amount', '<>', 0)
->orderBy('ident', 'desc')
+ ->groupBy('ident')
+ ->limit($pageSize + 1)
+ ->offset($pageSize * ($page - 1))
->get()
- ->whereNotIn('ident', [date('Y-m')]) // exclude current month
- ->pluck('ident');
+ ->whereNotIn('ident', [date('Y-m')]); // exclude current month
+
+
+ if (count($result) > $pageSize) {
+ $result->pop();
+ $hasMore = true;
+ }
+
+ $result = $result->map(function ($item) use ($wallet) {
+ $entry = [
+ 'period' => $item->ident,
+ 'amount' => $item->total,
+ 'currency' => $wallet->currency
+ ];
+ return $entry;
+ });
return response()->json([
'status' => 'success',
'list' => $result,
'count' => count($result),
- 'hasMore' => false,
- 'page' => 1,
+ 'hasMore' => $hasMore,
+ 'page' => $page,
]);
}
diff --git a/src/resources/vue/Wallet.vue b/src/resources/vue/Wallet.vue
--- a/src/resources/vue/Wallet.vue
+++ b/src/resources/vue/Wallet.vue
@@ -46,20 +46,7 @@
<div class="tab-content">
<div class="tab-pane active" id="receipts" role="tabpanel" aria-labelledby="tab-receipts">
<div class="card-body">
- <div class="card-text">
- <p v-if="receipts.length">
- {{ $t('wallet.receipts-hint') }}
- </p>
- <div v-if="receipts.length" class="input-group">
- <select id="receipt-id" class="form-control">
- <option v-for="(receipt, index) in receipts" :key="index" :value="receipt">{{ receipt }}</option>
- </select>
- <btn class="btn-secondary" @click="receiptDownload" icon="download">{{ $t('btn.download') }}</btn>
- </div>
- <p v-if="!receipts.length">
- {{ $t('wallet.receipts-none') }}
- </p>
- </div>
+ <receipt-list v-if="walletId && loadReceipts" class="card-text" :wallet-id="walletId"></receipt-list>
</div>
</div>
<div class="tab-pane" id="history" role="tabpanel" aria-labelledby="tab-history">
@@ -154,7 +141,8 @@
import ModalDialog from './Widgets/ModalDialog'
import TransactionLog from './Widgets/TransactionLog'
import PaymentLog from './Widgets/PaymentLog'
- import { downloadFile, paymentCheckout } from '../js/utils'
+ import ReceiptList from './Widgets/ReceiptList'
+ import { paymentCheckout } from '../js/utils'
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -170,7 +158,8 @@
components: {
ModalDialog,
TransactionLog,
- PaymentLog
+ PaymentLog,
+ ReceiptList
},
data() {
return {
@@ -182,6 +171,7 @@
receipts: [],
loadTransactions: false,
loadPayments: false,
+ loadReceipts: true,
showPendingPayments: false,
wallet: {},
walletId: null,
@@ -242,6 +232,7 @@
this.$refs.tabs.clickHandler('history', () => { this.loadTransactions = true })
this.$refs.tabs.clickHandler('payments', () => { this.loadPayments = true })
+ this.$refs.tabs.clickHandler('receipts', () => { this.loadReceipts = true })
},
methods: {
loadMandate() {
@@ -375,10 +366,6 @@
this.$refs.paymentDialog.show()
},
- receiptDownload() {
- const receipt = $('#receipt-id').val()
- downloadFile('/api/v4/wallets/' + this.walletId + '/receipts/' + receipt)
- }
}
}
</script>
diff --git a/src/resources/vue/Widgets/ReceiptList.vue b/src/resources/vue/Widgets/ReceiptList.vue
new file mode 100644
--- /dev/null
+++ b/src/resources/vue/Widgets/ReceiptList.vue
@@ -0,0 +1,61 @@
+<template>
+ <div>
+ <table class="table table-sm m-0 receipts">
+ <thead>
+ <tr>
+ <th scope="col">{{ $t('form.date') }}</th>
+ <th scope="col" class="price">{{ $t('form.amount') }}</th>
+ <th scope="col"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="receipt in receipts" :id="'log' + receipt.id" :key="receipt.id">
+ <td class="datetime">{{ receipt.period }}</td>
+ <td :class="'price ' + className(receipt)">{{ amount(receipt) }}</td>
+ <td class="selection">
+ <btn class="btn-secondary float-end" @click="receiptDownload(receipt.period)" icon="download">{{ $t('btn.download') }}</btn>
+ </td>
+ </tr>
+ </tbody>
+ <list-foot :text="$t('wallet.receipts-none')" :colspan="3"></list-foot>
+ </table>
+ <list-more v-if="hasMore" :on-click="loadMore"></list-more>
+ </div>
+</template>
+
+
+<script>
+ import ListTools from './ListTools'
+ import { downloadFile } from '../../js/utils'
+
+ export default {
+ mixins: [ ListTools ],
+ props: {
+ walletId: { type: String, default: null }
+ },
+ data() {
+ return {
+ receipts: []
+ }
+ },
+ mounted() {
+ this.loadMore({ reset: true })
+ },
+ methods: {
+ loadMore(params) {
+ if (this.walletId) {
+ this.listSearch('receipts', '/api/v4/wallets/' + this.walletId + '/receipts', params)
+ }
+ },
+ amount(receipt) {
+ return this.$root.price(receipt.amount, receipt.currency)
+ },
+ className(receipt) {
+ return receipt.amount < 0 ? 'text-danger' : 'text-success';
+ },
+ receiptDownload(period) {
+ downloadFile('/api/v4/wallets/' + this.walletId + '/receipts/' + period)
+ }
+ }
+ }
+</script>
diff --git a/src/tests/Browser/WalletTest.php b/src/tests/Browser/WalletTest.php
--- a/src/tests/Browser/WalletTest.php
+++ b/src/tests/Browser/WalletTest.php
@@ -112,9 +112,7 @@
->assertSeeIn('@nav #tab-receipts', 'Receipts')
->with('@receipts-tab', function (Browser $browser) {
$browser->waitUntilMissing('.app-loader')
- ->assertSeeIn('p', 'There are no receipts for payments')
- ->assertDontSeeIn('p', 'Here you can download')
- ->assertMissing('select')
+ ->assertSeeIn('td', 'There are no receipts for payments')
->assertMissing('button');
});
});
@@ -162,16 +160,14 @@
->assertSeeIn('@nav #tab-receipts', 'Receipts')
->with('@receipts-tab', function (Browser $browser) use ($receipts) {
$browser->waitUntilMissing('.app-loader')
- ->assertDontSeeIn('p', 'There are no receipts for payments')
- ->assertSeeIn('p', 'Here you can download')
- ->assertSeeIn('button', 'Download')
- ->assertElementsCount('select > option', 2)
- ->assertSeeIn('select > option:nth-child(1)', $receipts[1])
- ->assertSeeIn('select > option:nth-child(2)', $receipts[0]);
+ ->assertElementsCount('table tbody tr', 2)
+ ->assertMissing('.more-loader button', 'Load more')
+ ->assertSeeIn('table tbody tr:nth-child(1) td.datetime', $receipts[1])
+ ->assertSeeIn('table tbody tr:nth-child(2) td.datetime', $receipts[0]);
// Download a receipt file
- $browser->select('select', $receipts[0])
- ->click('button')
+ $browser->click('table tbody tr:nth-child(2) td.selection button')
+ ->waitUntilMissing('.app-loader')
->pause(2000);
$files = glob(__DIR__ . '/downloads/*.pdf');
diff --git a/src/tests/Feature/Controller/WalletsTest.php b/src/tests/Feature/Controller/WalletsTest.php
--- a/src/tests/Feature/Controller/WalletsTest.php
+++ b/src/tests/Feature/Controller/WalletsTest.php
@@ -193,7 +193,7 @@
$this->assertCount(5, $json);
$this->assertSame('success', $json['status']);
- $this->assertSame([$date->format('Y-m')], $json['list']);
+ $this->assertSame(['period' => $date->format('Y-m'), 'amount' => '1111', 'currency' => 'CHF'], $json['list'][0]);
$this->assertSame(1, $json['page']);
$this->assertSame(1, $json['count']);
$this->assertSame(false, $json['hasMore']);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 5, 12:37 PM (8 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18833460
Default Alt Text
D4809.1775392627.diff (9 KB)
Attached To
Mode
D4809: Turn the Receipt download into a ReceiptList
Attached
Detach File
Event Timeline