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 @@ -5,6 +5,7 @@ use App\Transaction; use App\Wallet; use App\Http\Controllers\Controller; +use App\Providers\PaymentProvider; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -94,6 +95,87 @@ return $this->errorResponse(404); } + /** + * Download a receipt in pdf format. + * + * @param string $id Wallet identifier + * @param string $receipt Receipt identifier (YYYY-MM) + * + * @return \Illuminate\Http\Response|void + */ + public function receiptDownload($id, $receipt) + { + $wallet = Wallet::find($id); + + // Only owner (or admin) has access to the wallet + if (!Auth::guard()->user()->canRead($wallet)) { + return abort(403); + } + + list ($year, $month) = explode('-', $receipt); + + if (empty($year) || empty($month) || $year < 2000 || $month < 1 || $month > 12) { + return abort(404); + } + + if ($receipt >= date('Y-m')) { + return abort(404); + } + + $params = [ + 'year' => $year, + 'month' => \trans('documents.month' . intval($month)), + 'site' => \config('app.name') + ]; + + $filename = \trans('documents.receipt-filename', $params); + + $receipt = new \App\Documents\Receipt($wallet, (int) $year, (int) $month); + + $content = $receipt->pdfOutput(); + + return response($content) + ->withHeaders([ + 'Content-Type' => 'application/pdf', + 'Content-Disposition' => 'attachment; filename="' . $filename . '"', + 'Content-Length' => strlen($content), + ]); + } + + /** + * Fetch wallet receipts list. + * + * @param string $id Wallet identifier + * + * @return \Illuminate\Http\JsonResponse + */ + public function receipts($id) + { + $wallet = Wallet::find($id); + + // Only owner (or admin) has access to the wallet + if (!Auth::guard()->user()->canRead($wallet)) { + return $this->errorResponse(403); + } + + $result = $wallet->payments() + ->selectRaw('distinct date_format(updated_at, "%Y-%m") as ident') + ->where('status', PaymentProvider::STATUS_PAID) + ->where('amount', '>', 0) + ->orderBy('ident', 'desc') + ->get() + ->whereNotIn('ident', [date('Y-m')]) // exclude current month + ->pluck('ident'); + + return response()->json([ + 'status' => 'success', + 'list' => $result, + 'count' => count($result), + 'hasMore' => false, + 'page' => 1, + ]); + } + /** * Fetch wallet transactions. * diff --git a/src/resources/js/app.js b/src/resources/js/app.js --- a/src/resources/js/app.js +++ b/src/resources/js/app.js @@ -122,6 +122,29 @@ this.errorPage(error.response.status, error.response.statusText) } }, + downloadFile(url) { + // TODO: This might not be a best way for big files as the content + // will be stored (temporarily) in browser memory + // TODO: This method does not show the download progress in the browser + // but it could be implemented in the UI, axios has 'progress' property + axios.get(url, { responseType: 'blob' }) + .then (response => { + const link = document.createElement('a') + const contentDisposition = response.headers['content-disposition'] + let filename = 'unknown' + + if (contentDisposition) { + const match = contentDisposition.match(/filename="(.+)"/); + if (match.length === 2) { + filename = match[1]; + } + } + + link.href = window.URL.createObjectURL(response.data) + link.download = filename + link.click() + }) + }, price(price) { return (price/100).toLocaleString('de-DE', { style: 'currency', currency: 'CHF' }) }, diff --git a/src/resources/js/fontawesome.js b/src/resources/js/fontawesome.js --- a/src/resources/js/fontawesome.js +++ b/src/resources/js/fontawesome.js @@ -11,6 +11,7 @@ import { faCheck, faCheckCircle, + faDownload, faGlobe, faExclamationCircle, faInfoCircle, @@ -33,6 +34,7 @@ faCheckCircle, faCheckSquare, faCreditCard, + faDownload, faExclamationCircle, faGlobe, faInfoCircle, diff --git a/src/resources/lang/en/documents.php b/src/resources/lang/en/documents.php --- a/src/resources/lang/en/documents.php +++ b/src/resources/lang/en/documents.php @@ -29,6 +29,7 @@ 'month11' => "November", 'month12' => "December", + 'receipt-filename' => ":site Receipt for :month :year", 'receipt-title' => "Receipt for :month :year", 'receipt-item-desc' => ":site Services", diff --git a/src/resources/views/documents/receipt.blade.php b/src/resources/views/documents/receipt.blade.php --- a/src/resources/views/documents/receipt.blade.php +++ b/src/resources/views/documents/receipt.blade.php @@ -3,7 +3,7 @@
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 @@ -14,13 +14,42 @@+ Here you can download receipts (in PDF format) for payments in specified period. + Select the period and press the Download button. +
++ There are no receipts for payments in this account. Please, note that you can download + receipts after the month ends. +
+