asked on
How to add a PDF button and print pulled data into a pdf file
Hello Experts,
I need to add a PDF button in order to print pdf file with data from the DB.
I'm trying to add the PDF button in admin.accountingsVouchers view
For this I have created the following steps:
in admin.vouchersAccountings index.blade.php I modified the file
@extends('layouts.admin')
@section('content')
<link href="{{ asset('css/va.css') }}" rel="stylesheet" />
<div class="content">
<div class="row">
<div class="col-md-12 mt-4">
<div class="panel panel-default">
<div class="panel-heading">
{{ trans('cruds.vouchersAccounting.title') }}
</div>
<div class="panel-body">
<div class="card">
<div class="card-header">
<h4 class="Green">Reports</h4>
<form name="search" id="search" method="post" action="{{ route('admin.vouchers-accountings.search') }}">
@csrf
<div class="form-group">
From
<div class='input-group date'>
<input id="date-from" name="from" type='text' class="form-control" value="{{ $from }}">
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
</div>
</div>
<div class="form-group">
To
<div class='input-group date' id='CalendarDateTime'>
<input id="date-to" name="to" type='text' class="form-control" value="{{ $to }} ">
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
</div>
</div>
<a class="btn btn-default" href="{{ route('admin.vouchersAccountings.getpdf', $createVoucher->id) }}">
{{ trans('global.datatables.pdf') }}
</a>
<button type="submit" class="btn btn-primary">Search</button>
I edited VouchersAccountingController.php and added a new function:
use App\CreateVoucher;
use PDF;
...
public function getpdf($VoucherId)
{
abort_if(Gate::denies('create_voucher_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$createVoucher = CreateVoucher::findOrFail($VoucherId);
$createVoucher->load('agent', 'room_type', 'hotel_name');
$pdf = PDF::loadView('admin.vouchersAccountings.getpdf', compact('createVoucher'));
return $pdf->download('voucher.pdf');
}
I added the following in routes:
Route::get('vouchers-accountings/getpdf/{id}', 'VouchersAccountingController@getpdf')->name('vouchers-accountings.getpdf');
When I try to browse to /vouchers-accountings it does show an error:
ErrorException Undefined variable: createVoucher (View: C:\laragon\www\vouchermanager3\resources\views\admin\vouchersAccountings\index.blade.php)
Why I'm getting this error is my controller has the
use App\CreateVoucher;
When you add the link in your index.blade file, you're trying to pass in the ID of the createVoucher, but you don't have an instance of a CreateVoucher available in your view - you've never retrieved one in the controller methods (index / search etc).
<a class="btn btn-default" href="{{ route('admin.vouchersAccou
Remember - your index blade view isn't showing details for a single, specific craeteVoucher - it's showing a list, so the only place you have access to a CreateVoucher instance is within the loop that displays the data, so it would make more sense to add the Get Pdf button on EACH ROW OF YOUR TABLE:
@foreach($Reports as $Report)
<tr>
<th> {{$Report->id}} </th>
<th> {{$Report->client_name}
...
<th>
<a class="btn btn-default" href="{{ route('admin.vouchersAccountings.getpdf', $Report->id) }}">
{{ trans('global.datatables.pdf') }}
</a>
</th>
ASKER
Hello Chris, thank you for your comment, I thought that by adding "use App\CreateVoucher;" it would import that Model because what we are doing here is just grabbing data from the table create_vouchers.
I have changed the code as you mentioned but i got an error:
ErrorException
Undefined variable: Report (View: C:\laragon\www\vouchermanager3\resources\views\admin\vouchersAccountings\index.blade.php)
through my project I have a PDF button in createvoucher/show.blade.php I was trying to follow up along with it to achieve same result
Adding use App\CreateVoucher doesn't retrieve anything from the database or set any variables - it simply allows you access to the Model is you need it.
I based my answer on your previous code from the admin.vouchersAccountings index.blade.php view. In there, you're looping through the $Reports variable, and you had a $Report variable.
Post up your vouchersAccountings/index.
ASKER
Thank you Chris,
This is my full Controller:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Gate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Carbon;
use App\CreateVoucher;
use PDF;
class VouchersAccountingController extends Controller
{
public function index(Request $request)
{
abort_if(Gate::denies('vouchers_accounting_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$from = Carbon::today()->subMonth();
$to = Carbon::today();
return $this->get_view($from, $to);
}
public function search(Request $request)
{
$from = Carbon::createFromFormat(config('panel.date_format'), $request->from);
$to = Carbon::createFromFormat(config('panel.date_format'), $request->to);
return $this->get_view($from, $to);
}
private function get_view(Carbon $from, Carbon $to)
{
$Reports = CreateVoucher::with(['hotel_name'])
->whereBetween('arrivaldate', [$from->toDateString(), $to->toDateString()])
->get();
$from = $from->format(config('panel.date_format'));
$to = $to->format(config('panel.date_format'));
return view('admin.vouchersAccountings.index', compact('Reports', 'from', 'to'));
}
public function getpdf($VoucherId)
{
abort_if(Gate::denies('vouchers_accountings_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$createVoucher = CreateVoucher::findOrFail($VoucherId);
$createVoucher->load('agent', 'room_type', 'hotel_name');
$pdf = PDF::loadView('admin.vouchersAccountings.getpdf', compact('createVoucher'));
return $pdf->download('voucher.pdf');
}
}
View:
@extends('layouts.admin')
@section('content')
<link href="{{ asset('css/va.css') }}" rel="stylesheet" />
<div class="content">
<div class="row">
<div class="col-md-12 mt-4">
<div class="panel panel-default">
<div class="panel-heading">
{{ trans('cruds.vouchersAccounting.title') }}
</div>
<div class="panel-body">
<div class="card">
<div class="card-header">
<h4 class="Green">Reports</h4>
<form name="search" id="search" method="post" action="{{ route('admin.vouchers-accountings.search') }}">
@csrf
<div class="form-group">
From
<div class='input-group date'>
<input id="date-from" name="from" type='text' class="form-control" value="{{ $from }}">
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
</div>
</div>
<div class="form-group">
To
<div class='input-group date' id='CalendarDateTime'>
<input id="date-to" name="to" type='text' class="form-control" value="{{ $to }} ">
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
</div>
</div>
<a class="btn btn-default" href="{{ route('admin.create-vouchers.getpdf', $Report->id) }}">
{{ trans('global.datatables.pdf') }}
</a>
<button type="submit" class="btn btn-primary">Search</button>
</form>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th>Voucher #</th>
<th>Client</th>
<th>Hotel</th>
<th>Arrival</th>
<th>Departure</th>
<th>Nights</th>
<th>Rooms</th>
<th>Payment Mode</th>
<th>Paid Amount</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@foreach($Reports as $Report)
<tr>
<th> {{$Report->id}} </th>
<th> {{$Report->client_name}} </th>
<th> {{$Report->hotel_name->hotel_name}} </th>
<th> {{$Report->arrivaldate}} </th>
<th> {{$Report->departuredate}} </th>
<th> {{$Report->night}} </th>
<th> {{$Report->number_of_room}}</th>
<th> {{$Report->payment_mode}}</th>
<th> {{$Report->total_amount}}</th>
<th class="{{ Str::snake($Report->status) }}"> {{$Report->status}}</th>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
You only have access to the $Report variable within the @foreach loop.
In your view, you're trying to use $Report->id (Line 35), but in your Controller, you're never setting a variable called $Report (hence the undefined error). Your view is responsible for displaying a collection of CreateVouchers (stored in the $Reports variable), so to access the ID, you need to loop over that collection.
If you want to get the PDF for each individual instance of a CreateVoucher, then you're going to need a button on each and every line of your table, because that's the only place you're going to have access to its ID.
Remove the code for the Get PDF button (line 35-57), and add the button to each row in the table instead:
<table class="table">
<thead>
<tr>
<th>Voucher #</th>
<th>Client</th>
<th>Hotel</th>
<th>Arrival</th>
<th>Departure</th>
<th>Nights</th>
<th>Rooms</th>
<th>Payment Mode</th>
<th>Paid Amount</th>
<th>Status</th>
<th>PDF</th>
</tr>
</thead>
<tbody>
@foreach($Reports as $Report)
<tr>
<th> {{$Report->id}} </th>
<th> {{$Report->client_name}} </th>
<th> {{$Report->hotel_name->hotel_name}} </th>
<th> {{$Report->arrivaldate}} </th>
<th> {{$Report->departuredate}} </th>
<th> {{$Report->night}} </th>
<th> {{$Report->number_of_room}}</th>
<th> {{$Report->payment_mode}}</th>
<th> {{$Report->total_amount}}</th>
<th class="{{ Str::snake($Report->status) }}"> {{$Report->status}}</th>
<th>
<a class="btn btn-default" href="{{ route('admin.create-vouchers.getpdf', $Report->id) }}">
{{ trans('global.datatables.pdf') }}
</a>
</th>
</tr>
@endforeach
</tbody>
</table>
ASKER
Hello Chris,
I apologize for this delay to respond and thank you again for your help.
I have tried the code you have mentioned which works fine however it's not the approach I'm trying to achieve, I'm trying to get all vouchers in a pdf for the period I have specified.
For example, if I want to get all vouchers from June to July, I need to generate only a single pdf file with all vouchers from that period, not one by one.
If you want a single PDF for a Date Range, then you'll need to pass in the $to and $from dates, like you do for the Search method. You can either pass them in as part of the querystring (a GET request), or you can pass them in as form data (a POST request). I'd recommend you go with the POST request - wrap your PDF button in a form and create hidden inputs for the to and from dates:
<form name="get-voucher-pdf" method="post" action="{{ route('admin.vouchers-accountings.getpdf') }}">
@csrf
<input type="hidden" name="to" value="{{ $to }}">
<input type="hidden" name="from" value="{{ $from }}">
<button type="submit" class="btn btn-primary">{{ trans('global.datatables.pdf') }}</button>
<form>
Now, change your route to a POST route and drop the voucher ID:Route::post('vouchers-accountings/getpdf', 'VouchersAccountingController@getpdf')->name('vouchers-accountings.getpdf');
And change your Controller method to query your Vouchers using the to and from dates you pass in:public function getpdf(Request $request)
{
$from = Carbon::createFromFormat(config('panel.date_format'), $request->from);
$to = Carbon::createFromFormat(config('panel.date_format'), $request->to);
$vouchers = CreateVoucher::with(['hotel_name', 'agent', 'room_type'])
->whereBetween('arrivaldate', [$from->toDateString(), $to->toDateString()])
->get();
$pdf = PDF::loadView('admin.vouchersAccountings.getpdf', compact('vouchers'));
return $pdf->download('voucher.pdf');
}
ASKER
ASKER
Hi Chris, while you read my previous comment, can I suggest that we keep what you did and simply add another PDF button next to Search which create a pdf for the whole selected range
What do you think?
Not sure why you're now getting the Bad Method call - we sorted out the get_view() method in a previous question, and there should be no changes to that, so you've obviously done something else. You'll also want 2 methods in your Controller, and probably 2 views - one for the Single Voucher PDF and one for Lists of Vouchers PDF.
The routes file would look something like this:
Route::get('vouchers-accountings/getpdf/{voucher}', 'VouchersAccountingController@get_single_pdf')->name('vouchers-accountings.get_single_pdf');
Route::post('vouchers-accountings/getpdf', 'VouchersAccountingController@get_list_pdf')->name('vouchers-accountings.get_list_pdf');
Notice that we've changed the names as well. You'll need to use those names in your Blade template to generate the correct url for the <form> and the <a href>ASKER
Hello Chris,
Under /var/www/vouchermanager/resources/views/admin/vouchersAccountings/
I created getpdf.blade.php
@extends('layouts.printlist')
@section('content')
<div class="content">
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-body">
<div class="form-group">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.id') }}
</th>
<td>
{{ $vouchers->id }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.client') }}
</th>
<td>
{{ $vouchers->client->fullname ?? '' }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.arrivaldate') }}
</th>
<td>
{{ $vouchers->arrivaldate }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.departuredate') }}
</th>
<td>
{{ $vouchers->departuredate }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.hotel_name') }}
</th>
<td>
{{ $vouchers->hotel_name->hotel_name ?? '' }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.room_type') }}
</th>
<td>
{{ $vouchers->room_type->room_type ?? ''}}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.number_of_room') }}
</th>
<td>
{{ $vouchers->number_of_room }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.night') }}
</th>
<td>
{{ $vouchers->night }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.room_price') }}
</th>
<td>
{{ $vouchers->room_price }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.total_amount') }}
</th>
<td>
{{ $vouchers->total_amount }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.payment_mode') }}
</th>
<td>
{{ App\CreateVoucher::PAYMENT_MODE_SELECT[$vouchers->payment_mode] ?? '' }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
Then I created printlist.blade.php under layouts
<html>
<head>
<meta charset="utf-8">
<title>Voucher Manager</title>
<link rel="stylesheet" href="css/mycss.css">
<link rel="license" href="https://www.opensource.org/licenses/mit-license/">
</head>
<body>
<center><span><img alt="" src="logo.png"></span></center>
<header>
<center>
<p class="title"> TRAVEL & TOURISM Co.</p>
</center>
<h1>REPORT</h1>
</header>
<article>
<table class="meta">
<tr>
<th><span contenteditable>Voucher #</span></th>
@php
$voucherid = str_pad($vouchers->id, 4, 0, STR_PAD_LEFT);
@endphp
<td><span contenteditable> {{ $voucherid }} </span></td>
</tr>
<tr>
<th><span contenteditable>Guest's Name </span></th>
<td><span contenteditable>{{ $vouchers->client_name }}</span></td>
</tr>
<tr>
<th><span contenteditable>Arrival Date </span></th>
<td><span contenteditable>{{ $vouchers->arrivaldate }}</span></td>
</tr>
<tr>
<th><span contenteditable>Departure Date</span></th>
<td><span contenteditable>{{ $vouchers->departuredate }}</span></td>
</tr>
</table>
<table class="inventory">
<thead>
<tr>
<th><span contenteditable>Hotel</span></th>
<th><span contenteditable>No Of Nights</span></th>
<th><span contenteditable>Rate Per Night</span></th>
<th><span contenteditable>Room Type</span></th>
<th><span contenteditable>Rooms</span></th>
<th><span contenteditable>Payment Method</span></th>
</tr>
</thead>
<tbody>
<tr>
<td> {{ $vouchers->hotel_name->hotel_name ?? '' }}<span contenteditable></span></td>
<td><span contenteditable>{{ $vouchers->night }}</span></td>
<td><span data-prefix>MAD {{ $vouchers->room_price }}</span><span contenteditable></span></td>
<td><span contenteditable>{{ $vouchers->room_type->room_type}}</span></td>
<td><span data-prefix>{{ $vouchers->number_of_room }}</span><span></span></td>
<td><span contenteditable> {{ App\CreateVoucher::PAYMENT_MODE_SELECT[$vouchers->payment_mode] ?? '' }}</span></td>
</tr>
</tbody>
</table>
<table class="balance">
<tr>
<th><span contenteditable>Total</span></th>
<td><span data-prefix>MAD</span><span> {{$vouchers->total_amount}}</span></td>
</tr>
</table>
</article>
<aside>
<h1><span contenteditable>Service</span></h1>
<p>{{ $vouchers->service }}</p>
</aside>
<aside>
<h1><span contenteditable>Observation</span></h1>
<p>{{ $vouchers->observation }}</p>
</aside>
</body>
</html>
When I click on PDF
I get the following Error:
You'll need 2 Blade files for the 2 different PDFs that you want to generate.
You're generating a List of Vouchers, so you'll need blade file for that that takes in a vollection of CreateVoucher instances and loops through them.
You'll also need a Blade template for the single instance of a CreateVoucher.
Post up your web.php and your Accounting Controller
ASKER
Hello Chris
I have created 2 views:
1st View:
2nd View:
Index.blade.php
Routes:
https://gitlab.com/webdev866/vouchermanager/-/blob/master/routes/web.php
Controller:
However I'm getting this error:
Illuminate\Routing\Exceptions\UrlGenerationException
Missing required parameter for [Route: admin.vouchers-accountings.get_single_pdf] [URI: admin/vouchers-accountings/getpdf/{voucher}] [Missing parameter: voucher]. (View: /var/www/vouchermanager/resources/views/admin/vouchersAccountings/index.blade.php)
http://vouchermanager.test/admin/vouchers-accountings
Please help me
Take a look at the route for the Single PDF:
Route::get('vouchers-accountings/getpdf/{voucher}', 'VouchersAccountingController@get_single_pdf')->name('vouchers-accountings.get_single_pdf');
So that will call a method named get_single_pdf, and it expects an argument called $voucher. Now take a look at that method, and you'll see that you have an argument called $request. You've also coded that method to expect the from and to date, which you don't need for the Single. It should look like this:
public function get_single_pdf(CreateVoucher $voucher)
{
$voucher->loadMissing([hotel_name', 'agent', 'room_type']);
$pdf = PDF::loadView('admin.vouchersAccountings.get_single_pdf', compact('voucher'));
return $pdf->download('voucher.pdf');
}
You'll see that the variable we pass into the View is called voucher (singular), so change your view to use that: $voucher->id instead of $vouchers->id. If you look at your route, you'll also see that the route for the Single is called admin.vouchers-accountings
<a class="btn btn-default" href="{{ route('admin.create-vouchers.get_single_pdf', $Report->id) }}">{{
trans('global.datatables.pdf') }}
</a>
Now for the List pdf - take a look at your form in the Index view and you'll see that you're submitting it to the get_single_pdf route - it should be submitted to the get_list_pdf route:
<form name="get-voucher-pdf" method="post" action="{{ route('admin.vouchers-accountings.get_list_pdf') }}">
Because you wanted to output a list, you need to loop over all the Vouchers. In your controller, you're passing in a collection of CreateVouchers using the variable $vouchers:$pdf = PDF::loadView('admin.vouch
So in your get_list_pdf View, you need a foreach loop, for example:
@foreach ($vouchers as $voucher)
<tr>
<td>{{ $voucher->id }}</td>
<td>{{ $vouchers->arrivaldate }}</td>
</tr>
@endforeach
ASKER
Thank you Chris for your help, I really appreciate it.
I corrected the mistakes I've done, really sorry but I started to grasp the concepts. thank you
I have now only an issue with get_list_pdf which doesn't list all the vouchers, my db has now just 2 vouchers but i'm getting only 1, also the From and To are not populated in the pdf I guess it's because it's not stored in the DB to be pulled
My current get_list_pdf view:
@extends('layouts.printlist')
@section('content')
<div class="content">
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-body">
<div class="form-group">
<table class="table table-bordered table-striped">
<tbody>
@foreach ($vouchers as $voucher)
<tr>
<td>{{ $voucher->id }}</td>
<td>{{ $voucher->arrivaldate }}</td>
<td>{{ $voucher->hotel }}</td>
<td>{{ $voucher->night }}</td>
<td>{{ $voucher->total_amount }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
my printlist
<html>
<head>
<meta charset="utf-8">
<title>Voucher Manager</title>
<link rel="stylesheet" href="css/mycss.css">
<link rel="license" href="https://www.opensource.org/licenses/mit-license/">
</head>
<body>
<center><span><img alt="" src="logo.png"></span></center>
<header>
<center>
<p class="title"> TRAVEL & TOURISM Co.</p>
</center>
<h1>REPORT</h1>
</header>
<article>
<table class="meta">
<tr>
<th><span contenteditable>From</span></th>
<td><span contenteditable> {{ $from ?? '' }} </span></td>
</tr>
<tr>
<th><span contenteditable>To</span></th>
<td><span contenteditable> {{ $to ?? ''}} </span></td>
</tr>
</table>
<table class="inventory">
<thead>
<tr>
<th><span contenteditable>Voucher#</span></th>
<th><span contenteditable>Arrival Date</span></th>
<th><span contenteditable>Departure Date</span></th>
<th><span contenteditable>Hotel</span></th>
<th><span contenteditable>No Of Nights</span></th>
<th><span contenteditable>Total</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><span contenteditable>{{ $voucher->id }}</span></td>
<td><span contenteditable>{{ $voucher->arrivaldate }}</span></td>
<td><span contenteditable>{{ $voucher->departuredate }}</span></td>
<td> {{ $voucher->hotel_name->hotel_name ?? '' }}<span contenteditable></span></td>
<td><span contenteditable>{{ $voucher->night }}</span></td>
<td><span contentediable>{{ $voucher->total_amount }} </span></td>
</tr>
</tbody>
</table>
<table class="balance">
<tr>
<th><span contenteditable>Total Balance</span></th>
<td><span data-prefix>MAD</span><span> {{$voucher->total_amount}}</span></td>
</tr>
</table>
</article>
</body>
</html>
Also how can I make a calulation of all total amount to be reflected in Total balance?
Thank you
Progress, which is great.
However, you have some issues with your Views. You have a Base Layout file (called printlist.blade.php), but this layout never INCLUDES anything else (child template), so it will never render the get_list_pdf.blade template - it will just output it exactly as it is. And in that template, you're never looping over anything ,so you'll only ever have one record. If you want to use Template Inheritance, then you create a base page template, and you 'yield' different sections. Your child template then sets the content of those sections. Quick Example:
// Base Template - base.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>@yield('page_title')</title>
</head>
<body>
<div>
@yield('content')
</div>
@yield('footer')
</body>
</html>
// Child Template - child.blade.php@extends('base')
@section('page_title', "My Child Page")
@section('content')
<h1>This will display wherever we've yielded the 'content' section in the Base Layout</h1>
@endsection
@section('footer')
<div>
<p>This will be rendered whenever we yield('footer')</p>
</div>
@endsection
Now if we load up the child view, we load up the base view, and yield the content from the child view.So, on that note, I would suggest you create a base print.blade.php file in layouts. Don't add any data in here - just add the basic page layout stuff - headers / footer etc, along with a @yield('content') line.
Then in your get_list_pdf.blade file, you will create the actual data layout (the table showing the list of Vouchers). This is where you create your inputs for From / To and loop over your Vouchers. That would all go in the @section('content') part
You can then use the same print base template for the get_single_pdf.blade file, as it's only the content that will change.
Now, as for why you're not getting the From and To dates - you need to pass those in as variables to the View, so in your controller, just make sure you pass them to the View:
public function get_list_pdf(Request $request)
{
$from = Carbon::createFromFormat(config('panel.date_format'), $request->from);
$to = Carbon::createFromFormat(config('panel.date_format'), $request->to);
$vouchers = CreateVoucher::with(['hotel_name', 'agent', 'room_type'])
->whereBetween('arrivaldate', [$from->toDateString(), $to->toDateString()])
->get();
$pdf = PDF::loadView('admin.vouchersAccountings.get_list_pdf', compact('vouchers', 'from', 'to'));
return $pdf->download('voucher.pdf');
}
You can see that we pass $vouchers, $from and $to in the loadView method, so they'll be available in your get_list_pdf child viewThere are a couple of ways to run the calculation for the Total, but let's get your views sorted first.
ASKER
Hello Chris,
I just want to ask before I proceed with the new instructions you provided, can you check this view blade because all I did was copying the getpdf.blade.php and replicate it, if I use this version will I still need to create a base and child layouts?
@extends('layouts.printlist')
@section('content')
<div class="content">
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-body">
<div class="form-group">
<table class="table table-bordered table-striped">
<tbody>
@foreach ($vouchers as $voucher)
<tr>
<th>
{{ trans('cruds.createVoucher.fields.id') }}
</th>
<td>
{{ $vouchers->id }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.client') }}
</th>
<td>
{{ $vouchers->client->fullname ?? '' }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.arrivaldate') }}
</th>
<td>
{{ $vouchers->arrivaldate }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.departuredate') }}
</th>
<td>
{{ $vouchers->departuredate }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.hotel_name') }}
</th>
<td>
{{ $vouchers->hotel_name->hotel_name ?? '' }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.room_type') }}
</th>
<td>
{{ $vouchers->room_type->room_type ?? ''}}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.number_of_room') }}
</th>
<td>
{{ $vouchers->number_of_room }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.night') }}
</th>
<td>
{{ $vouchers->night }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.room_price') }}
</th>
<td>
{{ $vouchers->room_price }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.total_amount') }}
</th>
<td>
{{ $vouchers->total_amount }}
</td>
</tr>
<tr>
<th>
{{ trans('cruds.createVoucher.fields.payment_mode') }}
</th>
<td>
{{ App\CreateVoucher::PAYMENT_MODE_SELECT[$vouchers->payment_mode] ?? '' }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
The template that you've just posted is a child template - you can see this because it 'extends' a parent / base template - look at the first line and you'll see :
@extends('layouts.printlis
When you load up this template, it will first load up your layouts/printlist.blade.ph
This is fundamental to using template inheritance within Laravel.
Now if you don't want to use Inheritance, you don't have to. Just create a single blade file that doesn't extend anything and doesn't have any @section / @yield statements. Doing this means that your blade files would need to be full HTML pages along with the relevant content, and you lose the advantage of re-using templates parts - you're likely to end up replicating lots of HTML, so I wouldn't recommend doing that.
@foreach ($vouchers as $voucher)
So inside that loop, each instance is referred to as $voucher, and yet in your HTML you're referring to it as $vouchers (plural):
{{ $vouchers->id }}
ASKER
Sorry Chris I still don't get it, which file?
Here is the get_list_pdf.blade.php
@extends('layouts.printlist')
@section('content')
<div class="content">
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-body">
<div class="form-group">
<table class="table table-bordered table-striped">
<tbody>
@foreach ($vouchers as $voucher)
<tr>
<td>{{ $voucher->id }}</td>
<td>{{ $voucher->arrivaldate }}</td>
<td>{{ $voucher->hotel }}</td>
<td>{{ $voucher->night }}</td>
<td>{{ $voucher->total_amount }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
printlist.blade.php
<html>
<head>
<meta charset="utf-8">
<title>Voucher Manager</title>
<link rel="stylesheet" href="css/mycss.css">
<link rel="license" href="https://www.opensource.org/licenses/mit-license/">
</head>
<body>
<center><span><img alt="" src="logo.png"></span></center>
<header>
<center>
<p class="title"> TRAVEL & TOURISM Co.</p>
</center>
<h1>REPORT</h1>
</header>
<article>
<table class="meta">
<tr>
<th><span contenteditable>From</span></th>
<td><span contenteditable> {{ $from ?? '' }} </span></td>
</tr>
<tr>
<th><span contenteditable>To</span></th>
<td><span contenteditable> {{ $to ?? ''}} </span></td>
</tr>
</table>
<table class="inventory">
<thead>
<tr>
<th><span contenteditable>Voucher#</span></th>
<th><span contenteditable>Arrival Date</span></th>
<th><span contenteditable>Departure Date</span></th>
<th><span contenteditable>Hotel</span></th>
<th><span contenteditable>No Of Nights</span></th>
<th><span contenteditable>Total</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><span contenteditable>{{ $voucher->id }}</span></td>
<td><span contenteditable>{{ $voucher->arrivaldate }}</span></td>
<td><span contenteditable>{{ $voucher->departuredate }}</span></td>
<td> {{ $voucher->hotel_name->hotel_name ?? '' }}<span contenteditable></span></td>
<td><span contenteditable>{{ $voucher->night }}</span></td>
<td><span contentediable>{{ $voucher->total_amount }} </span></td>
</tr>
</tbody>
</table>
<table class="balance">
<tr>
<th><span contenteditable>Total Balance</span></th>
<td><span data-prefix>MAD</span><span> {{$voucher->total_amount}}</span></td>
</tr>
</table>
</article>
</body>
</html>
ASKER
Hi Chris, please check my previous comment
I'm kinda lost,
Okay, I created base.blade.php and child.blade.php
base.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>@yield('page_title')</title>
<link rel="stylesheet" href="css/mycss.css">
</head>
<body>
<div>
@yield('content')
</div>
@yield('footer')
</body>
</html>
child.blade.php
@extends('base')
@section('page_title', "My Child Page")
@section('content')
<article>
<table class="meta">
<tr>
<th><span contenteditable>From</span></th>
<td><span contenteditable> {{ $from ?? '' }} </span></td>
</tr>
<tr>
<th><span contenteditable>To</span></th>
<td><span contenteditable> {{ $to ?? ''}} </span></td>
</tr>
</table>
<table class="inventory">
<thead>
<tr>
<th><span contenteditable>Voucher#</span></th>
<th><span contenteditable>Arrival Date</span></th>
<th><span contenteditable>Departure Date</span></th>
<th><span contenteditable>Hotel</span></th>
<th><span contenteditable>No Of Nights</span></th>
<th><span contenteditable>Total</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><span contenteditable>{{ $voucher->id }}</span></td>
<td><span contenteditable>{{ $voucher->arrivaldate }}</span></td>
<td><span contenteditable>{{ $voucher->departuredate }}</span></td>
<td> {{ $voucher->hotel_name->hotel_name ?? '' }}<span contenteditable></span></td>
<td><span contenteditable>{{ $voucher->night }}</span></td>
<td><span contentediable>{{ $voucher->total_amount }} </span></td>
</tr>
</tbody>
</table>
<table class="balance">
<tr>
<th><span contenteditable>Total Balance</span></th>
<td><span data-prefix>MAD</span><span> {{$voucher->total_amount}}</span></td>
</tr>
</table>
</article>
@endsection
@section('footer')
<div>
<p>This will be rendered whenever we yield('footer')</p>
</div>
@endsection
Result:
it does display 2 vouchers details but in plain text, I tried many way like specifying @extends('child') and other copy paste of my html inside base but it didn't work
I'm getting to a result but not sure where I made the mistake
ASKER
Thank you very much, it's working now perfectly, for the single voucher, it works fine unless if you want to make things neat and clean :)
I have 2 ideas in mind, I want to print of list pdf which only have the status of departed, (staying and future arrivals cannot be listed in the report because that report is used to request payment from the hotel for all the customers who stayed in the hotel for the period then departed)
I have created a model called Payments Collections, now the idea is that the admin will go through the paid vouchers from the hotel and mark the payment as collected, so basically I need to add another column similar to Status, called Payment Collection and grap the detail from the payment collection table and then list only vouchers that are departed and which payment is not collected
Like, get data where status = departed AND payment collected = not collected
When I create a voucher is it possible to have a record created automatically in Payment collection with voucher ID
If voucher is deleted the payment collection of that voucher changes to Cancelled.
I have 3 status: Collected / Not collected / Cancelled.
Should I open a new question for this?
Glad you got the PDFs working. I think for your other issues, you'll want to open a new question as it's completely off-topic from the PDF question.
Once posted, let me know and I'll try and take a look
Open in new window