2

I have a list of clients who have many appointments in db. I want to iterate through the appointments totalling their duration for each client so I can create an invoice. When I run the below code the first client's appointments duration are added correctly. However my issue is, for the next client it seems to add the first clients duration too. Is array_sum the correct method?? What do i need to use if not?

foreach($clients as $client)
        { 
            $appointments = Client::find($client->id)->appointments()->get();

                foreach($appointments as $appointment)
                {

                    $date1      = $appointment->starts_at; 
                    $date2      = $appointment->ends_at;                        
                    $start      = Carbon::parse($date1);
                    $end        = Carbon::parse($date2);

                    $length     = $start->diffinhours($end);
                    $duration[] = $length;          //is this correct?
                    $total = array_sum($duration);    //is this correct?
                }

            $invoice                    = new Invoice;
            $invoice->total_hours       = $total;   
            dd($invoice);
            $invoice->save();   
        }
1
  • after each loop you need to reset the sum. I mean just before the second foreach loop code (after getting $appointments) make you total variable as 0 i.e. $total=0 Commented Jan 17, 2017 at 20:53

2 Answers 2

2

Reset the duration for each client and array_sum after the appointment loop:

foreach ($clients as $client)
{ 
    $appointments = Client::find($client->id)->appointments()->get();

    $duration = array();

    foreach ($appointments as $appointment)
    {
        $date1      = $appointment->starts_at; 
        $date2      = $appointment->ends_at;                        
        $start      = Carbon::parse($date1);
        $end        = Carbon::parse($date2);

        $length     = $start->diffinhours($end);
        $duration[] = $length;
    }

    $total = array_sum($duration);

    $invoice                    = new Invoice;
    $invoice->total_hours       = $total;   
    dd($invoice);
    $invoice->save();   
}
Sign up to request clarification or add additional context in comments.

Comments

1

Yes you can use this method, but you need to move it outside the loop and also you should empty $total with each iteration:

....
$duration = [];

foreach ($appointments as $appointment)
{
    $date1      = $appointment->starts_at; 
    $date2      = $appointment->ends_at;                        
    $start      = Carbon::parse($date1);
    $end        = Carbon::parse($date2);

    $length     = $start->diffinhours($end);
    $duration[] = $length;
}

$total = array_sum($duration);
....

Also, you could add start_at and end_at timestamps to the $dates array in a model and use this code instead:

foreach ($appointments as $appointment)
{
    $duration[] = $appointment->starts_at->diffInHours($appointment->ends_at);
}

1 Comment

Thanks for this. It works. I have also implemented your suggestion about $dates.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.