Link to home
Start Free TrialLog in
Avatar of zack tim
zack timFlag for Morocco

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>

Open in new window


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');     }

Open in new window

I added the following in routes:

Route::get('vouchers-accountings/getpdf/{id}', 'VouchersAccountingController@getpdf')->name('vouchers-accountings.getpdf');

Open in new window



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)

Open in new window

Why I'm getting this error is my controller has the

use App\CreateVoucher;

Open in new window


Avatar of David H.H.Lee
David H.H.Lee
Flag of Malaysia image

Perhaps you can change $createVoucher to other variable name that not same with your CreateVoucher function name instead.
Example: $MyVoucher
...
        $MyVoucher = CreateVoucher::findOrFail($VoucherId);
        $MyeVoucher->load('agent', 'room_type', 'hotel_name');
        $pdf = PDF::loadView('admin.vouchersAccountings.getpdf', compact('MyVoucher'));
...


Open in new window

Hey Zack,,

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.vouchersAccountings.getpdf', $createVoucher->id) }}">

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>

Open in new window

Avatar of zack tim

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) 

Open in new window

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 


https://www.experts-exchange.com/questions/29242803/How-to-add-printing-functionality-to-laravel-form.html

Hey Zack,

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.blade.php file and the index method from your VouchersAccounting Controller and I'll take a look.





 

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');
    }
}

Open in new window


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

Open in new window



Right,

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>

Open in new window

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.

Ahh right. In your original code, you were passing in the Voucher ID, so I presumed you want a PDF for each Voucher.

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>

Open in new window

Now, change your route to a POST route and drop the voucher ID:

Route::post('vouchers-accountings/getpdf', 'VouchersAccountingController@getpdf')->name('vouchers-accountings.getpdf');

Open in new window

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');
}

Open in new window

thank you Chris,


I encountered an error, check this screenshot


User generated image

If I change the following from controller index method


return $this->get_view($from, $to);

Open in new window

to

return $this->getpdf($from, $to);

Open in new window


I get another error:

User generated image


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?

Hey Zack,

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');

Open in new window

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>

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

Open in new window


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>

Open in new window


When I click on PDF


User generated image


I get the following Error:


User generated image


OK,

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

Hello Chris


I have created 2 views:


1st View:

https://gitlab.com/webdev866/vouchermanager/-/blob/master/resources/views/admin/vouchersAccountings/get_single_pdf.blade.php


2nd View:


https://gitlab.com/webdev866/vouchermanager/-/blob/master/resources/views/admin/vouchersAccountings/get_list_pdf.blade.php


Index.blade.php


https://gitlab.com/webdev866/vouchermanager/-/blob/master/resources/views/admin/vouchersAccountings/index.blade.php


Routes:


https://gitlab.com/webdev866/vouchermanager/-/blob/master/routes/web.php


Controller:


https://gitlab.com/webdev866/vouchermanager/-/blob/master/app/Http/Controllers/Admin/VouchersAccountingController.php


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

OK,

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');

Open in new window


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');
}

Open in new window

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.get_single_pdf but in your Index view, you've named it wrong - you've called it admin.create-vouchers.get_single_pdf

<a class="btn btn-default" href="{{ route('admin.create-vouchers.get_single_pdf', $Report->id) }}">{{ 
    trans('global.datatables.pdf') }}
</a>

Open in new window


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') }}">

Open in new window

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.vouchersAccountings.get_list_pdf', compact('vouchers'));

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

Open in new window

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


User generated image

User generated image

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

Open in new window

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>

Open in new window


Also how can I make a calulation of all total amount to be reflected in Total balance?


Thank you

OK,

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>

Open in new window

// 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

Open in new window

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');
    }

Open in new window

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 view

There are a couple of ways to run the calculation for the Total, but let's get your views sorted first.

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

Open in new window


Hey Zack,

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.printlist')

When you load up this template, it will first load up your layouts/printlist.blade.php template, and within that file, it will look for a line that says @yield('content'). Wherever it finds that, it will drop in the HTML that the template above has within the @section('content') block.

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.
On another note, the code in your template is wrong. You're running a @foreach loop:

@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 }}

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

Open in new window

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>

Open in new window


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>

Open in new window


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

Open in new window


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


User generated image


I'm getting to a result but not sure where I made the mistake

ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

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



User generated image


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?

Hey Zack,

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