0 AND target > actual) OR ' . '(target < 0 AND target < actual)'; break; case 'overpaid': $having = '(target > 0 AND target < actual) OR ' . '(target < 0 AND target > actual)'; break; case 'receivable': $having = 'target > actual'; break; case 'debt': $having = 'target < actual'; break; } // Run the database query to retreive the data from the database. $selection = DB::select(' SELECT p_t.*, p_t.amount * i_o2.factor as target, sum(i_o1.factor * s_b.amount) as actual FROM sub_bookings s_b INNER JOIN account_types a_t ON a_t.id = s_b.account_type_id INNER JOIN account_classes a_c ON a_c.id = a_t.account_class_id INNER JOIN i_o_types i_o1 ON i_o1.id = a_c.io_type_id INNER JOIN person_targets p_t ON p_t.id = s_b.person_target_id INNER JOIN i_o_types i_o2 ON i_o2.id = p_t.io_type_id GROUP BY s_b.person_target_id HAVING ' . $having . ';'); // Remove the unused columns 'target' and 'actual' from the query // result. // This is not necessary, unless you want to save the hydrated models to // the databse. In this case we would get an error since the // peron_targets table has no column 'target' and 'actual'. foreach ($selection as $personTarget) { unset($personTarget->target); unset($personTarget->actual); } // Create a collection of PersonTargets from the raw query result. return PersonTarget::hydrate($selection); } /************************************************************************** * BOOKINGS * **************************************************************************/ /* * Get all bookings associated with a target. * * @return Illuminate\Database\Eloquent\Collection */ public function bookings() { return $this->hasMany('\App\SubBooking'); } /************************************************************************** * IO TYPES * **************************************************************************/ /* * Get the IOType of the target. * * @return Illuminate\Database\Eloquent\Relations\BelongsTo */ public function ioType() { return $this->belongsTo('App\IOType'); } /************************************************************************** * TARGET AND ACTUAL VALUES * **************************************************************************/ /* * Get the signed amount of the target. * * @return float */ public function signedAmount() { return $this->amount * $this->ioType->factor; } /* * Get the actuals connected with the target. * * @return Illuminate\Database\Eloquent\Relations\HasMany */ public function actuals() { return $this->hasMany('App\SubBooking'); } /* * Return the sum of all actuals belonging to this target * * @return float */ public function actualsSum() { return $this->actuals->each(function ($item, $key) { $item['signedAmount'] = $item->signedAmount(); })->sum('signedAmount'); } /* * Get the difference of target and actually payed amount so far. I. e. * return the amount still to be payed. * * @return float */ public function difference() { return $this->signedAmount() - $this->actualsSum(); } }