0

Hey guys here is my first question on stack overflow.

I am getting the following error message:

Trying to get property of non-object

When I am trying to view a refunded invoice within the system. Any help is much appreciated it! Thank you so much!

Here is the full code on the file:

   <?php

namespace App\Http\Controllers;

use App\Addon;
use App\Invoice;
use App\Package;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;

use App\PackagesCustomPrices;
use App\BookingSlot;
use App\BookingTime;
use App\Booking;

use Dompdf\Dompdf;

use App\Exports\InvoiceExport;
use Excel;


class AdminInvoicesController extends Controller
{

    /*
    |--------------------------------------------------------------------------
    | Admin Invoices Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for providing invoices views to admin.
    |
    */

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function export()
    {
        return Excel::download(new InvoiceExport, 'invoices.xlsx');
    }


    public function index()
    {

        $invoices = Invoice::select('invoices.*', 'bookings.first_name as first_name', 'bookings.last_name as last_name', 'bookings.id as booking_id', 'bookings.phone as phone')
                    ->join('bookings', 'bookings.id', 'invoices.booking_id')
                    ->where('invoices.archived', 0)->with('booking')->get();
        return view('invoices.index', compact('invoices'));
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $invoice = Invoice::findOrFail($id);

        //get package and addons
        $package = Package::find($invoice->booking->package->id);
        $addons = DB::table('addon_booking')->where('booking_id', '=', $invoice->booking_id)->get();

    //    $package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->first();

        $exp_booking = explode(" - ",$invoice->booking->booking_time);

        list($month,$day,$year) = explode('-', $invoice->booking->booking_date);
        $timestamp = mktime(0, 0, 0, $month, $day, $year);
        $event_date =  date('d-m-Y', $timestamp);

        //get day name to select slot timings
        $timestamp_for_event = strtotime($event_date);
        $today_number = date('N', $timestamp_for_event);        

        $its_holiday = BookingTime::where('today_is','=',$invoice->booking->booking_date)->first();
        if(isset($its_holiday->id))
        {
            $today_number = $its_holiday->id;
        }

        $get_slot = BookingSlot::where('opening','=',trim($exp_booking[0]))->where('closing','=',trim($exp_booking[1]))->where('booking_time_id','=',$today_number)->first();

        $package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->where('slot_id','=',$get_slot->id)->first();

        if(isset($package_custom->price))
        {
            $total = $package_custom->price;
        }
        else
        {
            $total = $package->price;
        }

        $invoice->booking->package->price = $total;
        //calculate total

        //add addons price if any
        // foreach($addons as $addon)
        // {
        //     $total = $total + Addon::find($addon->addon_id)->price;
        // }

        if($invoice->promo_discount)
        {
            $coupon = \App\CouponCode::where('code', $invoice->promo_used)->first();
            if($coupon->extra_items == 0){
                if($invoice->promo_discount)
                {
                    $discount = ($invoice->promo_discount / 100) * $total;
                    $total = $total - $discount;
                }

                foreach($addons as $addon)
                        {
                            $total = $total + Addon::find($addon->addon_id)->price;
                        }
            }
            else{

                foreach($addons as $addon)
                {
                    $total = $total + Addon::find($addon->addon_id)->price;
                }

                if($invoice->promo_discount)
                {
                    $discount = ($invoice->promo_discount / 100) * $total;
                    $total = $total - $discount;
                }
            }
        }
        else{
            foreach($addons as $addon)
            {
                $total = $total + Addon::find($addon->addon_id)->price;
            }
        }

        // print_r($total);

        // if($invoice->promo_discount)
        // {
        //     $discount = ($invoice->promo_discount / 100) * $total;
        //     $total = $total - $discount;
        // }

        // print_r($discount);
        // print_r($total);
        // exit();

        if(!$invoice->promo_discount && config('settings.enable_gst'))
        {
            $gst_amount = round(( config('settings.gst_percentage') / 100 ) * $total, 2);
        }

        else if($invoice->promo_discount && config('settings.enable_gst'))
        {
            if(config('settings.paypal_processing_fee') && $invoice->payment_method == __('app.paypal')){
                $total = $invoice->amount - (float) config('settings.paypal_processing_fee');
                // print_r($total);
                $gst_amount = round(( config('settings.gst_percentage') / 100 ) * $total, 2);
            }
            elseif (config('settings.stripe_processing_fee') && $invoice->payment_method == __('app.credit_card')) {
                $total = $invoice->amount - (float) config('settings.stripe_processing_fee');
                // print_r($total);
                $gst_amount = round(( config('settings.gst_percentage') / 100 ) * $total, 2);
            }
        }

        else
        {
            $gst_amount = 0;
        }
        // exit();

        return view('invoices.view', compact('invoice','gst_amount', 'total', 'discount'));
    }

    public function print($id)
    {
        $invoice = Invoice::findOrFail($id);

        //get package and addons
        $package = Package::find($invoice->booking->package->id);
        $addons = DB::table('addon_booking')->where('booking_id', '=', $invoice->booking_id)->get();


    //    $package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->first();

        $exp_booking = explode(" - ",$invoice->booking->booking_time);

        list($month,$day,$year) = explode('-', $invoice->booking->booking_date);
        $timestamp = mktime(0, 0, 0, $month, $day, $year);
        $event_date =  date('d-m-Y', $timestamp);

        //get day name to select slot timings
        $timestamp_for_event = strtotime($event_date);
        $today_number = date('N', $timestamp_for_event);        

        $its_holiday = BookingTime::where('today_is','=',$invoice->booking->booking_date)->first();
        if(isset($its_holiday->id))
        {
            $today_number = $its_holiday->id;
        }


        $get_slot = BookingSlot::where('opening','=',trim($exp_booking[0]))->where('closing','=',trim($exp_booking[1]))->where('booking_time_id','=',$today_number)->first();



                $package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->where('slot_id','=',$get_slot->id)->first();        


        if(isset($package_custom->price))
        {
            $total = $package_custom->price;
        }
        else
        {
            $total = $package->price;
        }
        //calculate total
        $invoice->booking->package->price = $total;

        //add addons price if any
        foreach($addons as $addon)
        {
            $total = $total + Addon::find($addon->addon_id)->price;
        }

        if($invoice->promo_discount)
        {
            $discount = ($invoice->promo_discount / 100) * $total;
            $total = $total - $discount;
        }

        if(config('settings.enable_gst'))
        {
            $gst_amount = round(( config('settings.gst_percentage') / 100 ) * $total, 2);
        }
        else
        {
            $gst_amount = 0;
        }

        // instantiate and use the dompdf class
        // print_r(base_path() . "/vendor/autoload.php");

        require base_path() . "/vendor/autoload.php";

        $dompdf = new Dompdf();
        $dompdf->set_option('isHtml5ParserEnabled', true);

        $view_hello = view('invoices.print', compact('invoice','gst_amount', 'total', 'discount'));  

        $dompdf->loadHtml(utf8_decode($view_hello));

        // (Optional) Setup the paper size and orientation
        $dompdf->setPaper('A4', 'portrait');

        // Render the HTML as PDF
        $dompdf->render();

        // Output the generated PDF to Browser
        $dompdf->stream("welcome.".date("ymdhis").".pdf", array("Attachment"=>0));


        //return view('invoices.view', compact('invoice','gst_amount', 'total', 'discount'));        
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $invoice = Invoice::find($id);

        $invoice->update([
            'is_paid' => 1
        ]);

        return redirect()->route('invoices.index');
    }


    public function delete_all(Request $request)
    {
        $values = explode(',', $request->delete_values);

        // print_r($values);
        // exit();

        foreach ($values as $value) {
            if($value === null || empty($value)){
                continue;
            }
                $invoice = Invoice::findorFail($value);

                $booking = Booking::find($invoice->booking_id);
                if($booking){
                    $booking->addons()->detach();
                    $booking->delete();
                }


                //delete event if google calendar sync is enabled
                if(config('settings.sync_events_to_calendar') && config('settings.google_calendar_id') && $booking->google_calendar_event_id != NULL)
                {
                    try {
                        //remove google calendar event
                        $event = Event::find($booking->google_calendar_event_id);
                        $event->delete();
                    } catch(\Exception $ex) {
                        //do nothing
                    }
                }

                $invoice->delete();
        }

        Session::flash('booking_deleted', __('backend.invoice_deleted'));
        return redirect()->route('invoices.index');
    }

}

The line of code that contains the error is below:

$package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->where('slot_id','=',$get_slot->id)->first();
JESSE
  • 21
  • 5
  • You are probably going to have to add more code as it's simply not really possible to give you an answer. But most likely one of this segments has a null value: $invoice->booking->package->id or $get_slot->id – Arturo Alvarado Apr 02 '20 at 20:58
  • Arturo, Thanks for the reply I edited my post and added more code. Please let me know if that helps. – JESSE Apr 02 '20 at 21:04
  • Hi Jesse, The line that has the issue is trying to access some variables, to which at least one does not have a value. Anything below (after) the line that has the issue is irrelevant to the issue itself. With what you posted, what I can see is that you are trying to set a value for $get_slot. But it is possible that it doesn't find a row that satisfies the query, so $get_slot will be null, and cause the error below. Also, we can't see where the value of $invoice comes from. So that could also be the problem. Please follow the suggestions below using dd() to find the null variable. – Arturo Alvarado Apr 03 '20 at 22:51

4 Answers4

1

In short you are trying to get a property value of a variable that has no value. From your code it can be from either $invoice or $get_slot.

The first step is to find out which variables have the problem. dd() is great for that as dd = stands for die and dump, which simply returns the value and halts the execution.

So you need to insert dd() right before your problem line:

$get_slot = BookingSlot::where('opening','=',trim($exp_booking[0]))->where('closing','=',trim($exp_booking[1]))->where('booking_time_id','=',$today_number)->first();

dd($invoice);
dd($invoice->booking);
dd($invoice->booking->package);
dd($get_slot);

$package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->where('slot_id','=',$get_slot->id)->first();

Now keep in mind that dd() will die after it dumps, so you will only see the return of the first value you tested.

So if dd($invoice) returns a value, then just comment it out like:

$get_slot = BookingSlot::where('opening','=',trim($exp_booking[0]))->where('closing','=',trim($exp_booking[1]))->where('booking_time_id','=',$today_number)->first();
// dd($invoice);
dd($invoice->booking);
dd($invoice->booking->package);
dd($get_slot);

$package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->where('slot_id','=',$get_slot->id)->first();

If that one returns a value then continue commenting out until you find the one that is null.

So let's say that the problem is with $get_slot, then you can dump the sql query to work out what the problem is.

You could do that getting the SQL of $get_slot query before the $get_slot line with:

$query = BookingSlot::where('opening','=',trim($exp_booking[0]))->where('closing','=',trim($exp_booking[1]))->where('booking_time_id','=',$today_number)->toSql();
dd($query);

$get_slot = BookingSlot::where('opening','=',trim($exp_booking[0]))->where('closing','=',trim($exp_booking[1]))->where('booking_time_id','=',$today_number)->first();

Take this query to your SQL client to try to figure out why it's not returning a value. Which of course can be that $today_number or $exp_booking don't have what you expect, or you are missing data, or you have an issue with the design of your DB. But that gives you the tools to work out what the issue is.

Arturo Alvarado
  • 498
  • 1
  • 5
  • 10
  • Arturo thanks for your help I did what you advised me to do and I am getting a "null" on the following: `dd($get_slot;` I also added the entire code of the file on my original post. I am not sure what to do after this? – JESSE Apr 06 '20 at 02:11
  • Ok, so the problem is that the query for get_slot is simply not returning any value. If you are using mysql, you can have it log all your queries, which I've done before to make sure my logic is correct. https://stackoverflow.com/questions/6479107/how-to-enable-mysql-query-log. However, you can start by simply dumping the query of get slot and run in in your sql client so you can work out what the problem with the query is. I'll update the answer to show how you can do that. – Arturo Alvarado Apr 06 '20 at 11:41
  • Arturo, I found out the issue. The system I am working on is an online boat reservation system. The invoice I was trying to view was processed with an old pricing in the database. The prices have now changed so I guess the error is generating because the old pricing on the invoice item no longer exists on the database. So when the query executes the old price doesn't match the new price so therefor the value is now null? Is there a way to store invoice values to a separate table to avoid this type of issues? – JESSE Apr 06 '20 at 18:01
  • Jesse, sure, you can call it invoice-new. But I don't think that will be the best approach in the long run. The question is, do you need to keep compatibility with the old invoice pricing? Or can't you just migrate the old data at once to the new pricing? I would suggest that you migrate if possible, but if you really can't then yeah, have two invoice tables. But this can be confusing at a later time, and produce weird results to developers in the future, exactly just it did to you. If you can't, then just pick a better name than Invoice-New :) – Arturo Alvarado Apr 06 '20 at 21:10
  • If you do want more specific questions regarding the Invoice and Pricing database migration, I would suggest opening a specific question with that regard, where you could post details that may get you good help. And glad to hear that you figured out what the problem is. – Arturo Alvarado Apr 06 '20 at 21:17
  • Ok, Thanks Arturo for your help! – JESSE Apr 06 '20 at 21:18
0

almost $invoice or$get_slot is empty or return array object or have not the wanted property so you cannot get property from object . you can use if(!empty($invoice)&&!empty($get_slot)) to check not empty object. you can also use dd() function to know returned data in each object.

0
if ($invoice && $invoice->booking && $invoice->booking->package && $get_slot){
    $package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->where('slot_id','=',$get_slot->id)->first();
}

one of the variables can be null. You should check

erhan
  • 69
  • 2
  • 8
  • Erha, Thank so you much I replaced my line of code with yours and it worked. I can see the invoice now however the subtotal line shows as $0.0 on the invoice for some reason the line of code is not pulling proper subtotal amount? Any ideas? – JESSE Apr 02 '20 at 21:18
  • where is the subtotal? – erhan Apr 03 '20 at 20:20
  • The problem with this solution is that you don't actually get to find out what the problem is. This solution simply avoids the overall error being thrown, but doesn't resolve the underling problem that is that you have an undefined variable that you are trying to reach. – Arturo Alvarado Apr 03 '20 at 22:45
  • erhan, If I understand your code it basically tells the system to execute the code even if a value is null correct? The issue here is that when a customer reserved that item it was priced at a different price but pricing has changed so that's why when I view the invoice is saying that the old value is not found. Not sure if that makes sense? – JESSE Apr 06 '20 at 05:25
  • Actually it's doing the opposite, it's telling the system to skip the next line if any of those values are null. So that's why you don't get the Error, but you don't get the expected result. Which of course doesn't really solve your problem, you are just skipping the parts that throw errors, but that Error is there for a reason, which is that something in your logic is missing, you just need to work out what it is, rather than just skip the part that throws the big ugly error. – Arturo Alvarado Apr 06 '20 at 11:56
0

The best way to handle this sort of problem is to read the error message very literally, and work back to the answer from there: Trying to get a property of a non-object First we look for a property in the indicated line of code where we learn we need to make sure $invoice, $invoice->booking, $invoice->booking->package, and $get_slot all exist.

I'm certain that $invoice is null. If that's the whole code body of the file, as you say in your question, then $invoice is never defined.

Before this line:

$package_custom = PackagesCustomPrices::where('package_id','=',$invoice->booking->package->id)->where('slot_id','=',$get_slot->id)->first();

Add this:

dd($invoice);

and go from there.

Jeremy Anderson
  • 826
  • 5
  • 16
  • Jeremy, Thanks for your response. I added the complete code on the file to my post. Can you please advise? – JESSE Apr 02 '20 at 21:22
  • Arturo's answer contains good suggestions, please try them out. I have marked it as correct, although it is not code-complete it contains good next steps to troubleshoot your problem. – Jeremy Anderson Apr 04 '20 at 11:28
  • Thanks I Jeremy I did that and commented on his comment. – JESSE Apr 06 '20 at 02:16