add receipt to payments
parent
6cd67a5280
commit
f2d38aa3c7
|
|
@ -267,6 +267,7 @@ class ContractController extends Controller
|
|||
'date' => $payment->date,
|
||||
'amount' => $payment->amount->format(),
|
||||
'type' => $payment->type,
|
||||
'print_link' => $payment->print_link,
|
||||
'delete_link' => $payment->delete_link,
|
||||
];
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Carbon\Carbon;
|
|||
use Inertia\Inertia;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Contract;
|
||||
use Barryvdh\DomPDF\Facade as PDF;
|
||||
use App\Enums\PaymentType;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
|
@ -41,6 +42,20 @@ class PaymentController extends Controller
|
|||
return Redirect::route('contracts.show', $payment->contract);
|
||||
}
|
||||
|
||||
public function print(Contract $contract, Payment $payment)
|
||||
{
|
||||
$contxt = stream_context_create([
|
||||
'ssl' => [
|
||||
'verify_peer' => FALSE,
|
||||
'verify_peer_name' => FALSE,
|
||||
'allow_self_signed'=> TRUE
|
||||
]
|
||||
]);
|
||||
$pdf = PDF::setOptions(['isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true])->loadView('receipt', compact('contract', 'payment'));
|
||||
$pdf->getDomPDF()->setHttpContext($contxt);
|
||||
return $pdf->stream($payment->date . '_quittung.pdf');
|
||||
}
|
||||
|
||||
public function destroy(Request $request, Contract $contract)
|
||||
{
|
||||
if (Payment::destroy((int)$request->get('id'))) {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ class Payment extends Model
|
|||
};
|
||||
}
|
||||
|
||||
public function getPrintLinkAttribute()
|
||||
{
|
||||
return route('payments.print', [$this->contract->id, $this->id]);
|
||||
}
|
||||
|
||||
public function getDeleteLinkAttribute()
|
||||
{
|
||||
return route('payments.destroy', [$this->contract->id, $this->id]);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Providers;
|
|||
|
||||
use App\Models\Car;
|
||||
use App\Models\Contact;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Contract;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
|
@ -56,12 +57,16 @@ class RouteServiceProvider extends ServiceProvider
|
|||
});
|
||||
|
||||
Route::bind('contract', function ($value) {
|
||||
if (in_array(Route::currentRouteName(), ['contracts.show', 'contracts.restore', 'payments.destroy'])) {
|
||||
if (in_array(Route::currentRouteName(), ['contracts.show', 'contracts.restore', 'payments.destroy', 'payments.print'])) {
|
||||
return Contract::withTrashed()->find($value);
|
||||
}
|
||||
return Contract::find($value);
|
||||
});
|
||||
|
||||
Route::bind('payment', function ($value) {
|
||||
return \App\Models\Payment::find($value);
|
||||
});
|
||||
|
||||
Route::prefix('api')
|
||||
->middleware('api')
|
||||
->namespace($this->namespace)
|
||||
|
|
|
|||
|
|
@ -20493,6 +20493,10 @@ __webpack_require__.r(__webpack_exports__);
|
|||
key: 'type',
|
||||
value: 'Bezahlart',
|
||||
sortable: false
|
||||
}, {
|
||||
key: 'print',
|
||||
value: 'Quittung',
|
||||
sortable: false
|
||||
}, {
|
||||
key: 'delete',
|
||||
value: '',
|
||||
|
|
@ -26153,26 +26157,27 @@ var _hoisted_13 = {
|
|||
"class": "flex items-center"
|
||||
};
|
||||
var _hoisted_14 = ["onClick"];
|
||||
var _hoisted_15 = {
|
||||
key: 2,
|
||||
var _hoisted_15 = ["href"];
|
||||
var _hoisted_16 = {
|
||||
key: 3,
|
||||
"class": "2xl:px-5 lg:px-3 px-2 2xl:py-4 lg:py-3 py-2 flex items-center"
|
||||
};
|
||||
var _hoisted_16 = {
|
||||
var _hoisted_17 = {
|
||||
key: 0,
|
||||
"class": "border-t w-px"
|
||||
};
|
||||
var _hoisted_17 = {
|
||||
var _hoisted_18 = {
|
||||
key: 0
|
||||
};
|
||||
var _hoisted_18 = ["colspan"];
|
||||
var _hoisted_19 = {
|
||||
var _hoisted_19 = ["colspan"];
|
||||
var _hoisted_20 = {
|
||||
key: 3
|
||||
};
|
||||
var _hoisted_20 = {
|
||||
var _hoisted_21 = {
|
||||
"class": "inline-flex font-medium text-gray-500 ml-3"
|
||||
};
|
||||
|
||||
var _hoisted_21 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" Keine Einträge gefunden ");
|
||||
var _hoisted_22 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" Keine Einträge gefunden ");
|
||||
|
||||
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
var _this = this;
|
||||
|
|
@ -26294,12 +26299,25 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|||
name: "trash-alt"
|
||||
})], 8
|
||||
/* PROPS */
|
||||
, _hoisted_14)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($options.resolve(col.key, row)), 1
|
||||
, _hoisted_14)) : col.key == 'print' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("a", {
|
||||
key: 2,
|
||||
"class": "2xl:px-5 lg:px-3 px-2 2xl:py-4 lg:py-3 py-2 flex items-center",
|
||||
target: "_blank",
|
||||
href: row.print_link
|
||||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_unicon, {
|
||||
fill: "#b2b7ff",
|
||||
"hover-fill": "indigo",
|
||||
height: "24",
|
||||
width: "24",
|
||||
name: "file-download"
|
||||
})], 8
|
||||
/* PROPS */
|
||||
, _hoisted_15)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($options.resolve(col.key, row)), 1
|
||||
/* TEXT */
|
||||
))]);
|
||||
}), 128
|
||||
/* KEYED_FRAGMENT */
|
||||
)), row.link && !$props.hideArrow ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("td", _hoisted_16, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_inertia_link, {
|
||||
)), row.link && !$props.hideArrow ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("td", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_inertia_link, {
|
||||
"class": "xl:pr-4 pr-2 xl:py-4 py-2 flex items-center",
|
||||
href: row.link,
|
||||
tabindex: "-1"
|
||||
|
|
@ -26319,18 +26337,18 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|||
, ["href"])])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)]);
|
||||
}), 128
|
||||
/* KEYED_FRAGMENT */
|
||||
)), $props.data.total === 0 ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("tr", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", {
|
||||
)), $props.data.total === 0 ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("tr", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", {
|
||||
"class": "border-t px-6 py-4",
|
||||
colspan: $props.columns.length
|
||||
}, "Keine Einträge gefunden", 8
|
||||
/* PROPS */
|
||||
, _hoisted_18)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)])])) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_19, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_20, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_unicon, {
|
||||
, _hoisted_19)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)])])) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_20, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_unicon, {
|
||||
fill: "#7e8491",
|
||||
"class": "mr-2",
|
||||
height: "24",
|
||||
width: "24",
|
||||
name: "meh"
|
||||
}), _hoisted_21])])), $props.data.links ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(_component_Paginator, {
|
||||
}), _hoisted_22])])), $props.data.links ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(_component_Paginator, {
|
||||
key: 4,
|
||||
"class": "mt-6",
|
||||
links: $props.data.links
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export default {
|
|||
{ key: 'date', value: 'Datum', sortable: false },
|
||||
{ key: 'amount', value: 'Betrag', sortable: false },
|
||||
{ key: 'type', value: 'Bezahlart', sortable: false },
|
||||
{ key: 'print', value: 'Quittung', sortable: false },
|
||||
{ key: 'delete', value: '', sortable: false },
|
||||
],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@
|
|||
<span v-else-if="col.key == 'delete'" class="p-3 cursor-pointer" @click="this.$emit('delete', row.id)">
|
||||
<unicon fill="#f04040" hover-fill="red" height="24" width="24" name="trash-alt"></unicon>
|
||||
</span>
|
||||
<a v-else-if="col.key == 'print'" class="2xl:px-5 lg:px-3 px-2 2xl:py-4 lg:py-3 py-2 flex items-center" target="_blank" :href="row.print_link">
|
||||
<unicon fill="#b2b7ff" hover-fill="indigo" height="24" width="24" name="file-download"></unicon>
|
||||
</a>
|
||||
<span v-else class="2xl:px-5 lg:px-3 px-2 2xl:py-4 lg:py-3 py-2 flex items-center">
|
||||
{{ resolve(col.key, row) }}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<title>
|
||||
Quittung - {{ $contract->car->name }} - {{ $contract->contact->full_title }}
|
||||
</title>
|
||||
<style type="text/css">
|
||||
* {
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
table{
|
||||
font-size: x-small;
|
||||
}
|
||||
table tr td {
|
||||
padding: 1px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
.footnote {
|
||||
padding: 5px 0;
|
||||
margin: 25px 0 5px 0;
|
||||
font-size: 9px;
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
tfoot tr td{
|
||||
font-weight: bold;
|
||||
font-size: x-small;
|
||||
}
|
||||
.gray {
|
||||
background-color: lightgray
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<pre>
|
||||
<b>Your SwissCar GmbH</b>
|
||||
Bernstrasse 27
|
||||
8952 Schlieren
|
||||
|
||||
Tel: 079 680 34 44
|
||||
E-Mail: info@yourswisscar.com
|
||||
|
||||
MwSt-Nr: CHE-226.272.050
|
||||
</pre>
|
||||
</td>
|
||||
<td valign="top" alt="logo" width="100%" align="right"><x-logo /></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td><h1>
|
||||
Quittung
|
||||
</h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td width="15%"><b>Verkäufer</b></td>
|
||||
<td width="35%">Your SwissCar GmbH</td>
|
||||
<td width="15%"><b>Käufer</b></td>
|
||||
<td width="35%">{{ $contract->contact->full_title }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Strasse</td>
|
||||
<td>Bernstrasse 27</td>
|
||||
<td>Strasse</td>
|
||||
<td>{{ $contract->contact->address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PLZ / Ort</td>
|
||||
<td>8952 Schlieren</td>
|
||||
<td>PLZ / Ort</td>
|
||||
<td>{{ $contract->contact->full_city }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Telefon</td>
|
||||
<td>079 680 34 44</td>
|
||||
<td>Telefon</td>
|
||||
<td>{{ $contract->contact->phone }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td>E-Mail</td>
|
||||
<td>{{ $contract->contact->email }}</td>
|
||||
</tr>
|
||||
<tr><td> </td></tr>
|
||||
</table>
|
||||
<table width="100%">
|
||||
<tr><td>Fahrzeug:</td></tr>
|
||||
<tr>
|
||||
<td><b>{{ $contract->car->name_with_year }}</b>, Stammnr.: {{ $contract->car->stammnummer }}</td>
|
||||
</tr>
|
||||
<tr><td> </td></tr>
|
||||
<tr>
|
||||
<td>Hiermit wird die folgende Einzahlung für das oben genannte Fahrzeug bestätigt:</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td width="20%">Datum</td>
|
||||
<td>{{ $payment->date }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zahlungsart</td>
|
||||
<td>{{ $payment->type }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Betrag</td>
|
||||
<td><h4>{{ $payment->amount->format() }}</h4></td>
|
||||
</tr>
|
||||
<tr><td> </td></tr>
|
||||
<tr><td> </td></tr>
|
||||
<tr><td> </td></tr>
|
||||
</p>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>Ort, Datum</td>
|
||||
</tr>
|
||||
<tr><td> </td></tr>
|
||||
<tr>
|
||||
<td>Schlieren, {{ $payment->date }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -72,6 +72,7 @@ Route::middleware(['auth:sanctum', 'verified'])->group(function () {
|
|||
Route::get('create', [PaymentController::class, 'create'])->name('payments.create');
|
||||
Route::delete('delete', [PaymentController::class, 'destroy'])->name('payments.destroy');
|
||||
Route::post('/', [PaymentController::class, 'store'])->name('payments.store');
|
||||
Route::get('{payment}/print', [PaymentController::class, 'print'])->name('payments.print');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue