From 020c1c50d80508baa7a0e4072ff9401d56f0d454 Mon Sep 17 00:00:00 2001 From: Lukas Halbritter Date: Wed, 19 Sep 2018 22:22:54 +0200 Subject: [PATCH] Added a bunch of new functions to the PersonTarget model, mainly to get filtered model collections from the database. --- app/PersonTarget.php | 139 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 132 insertions(+), 7 deletions(-) diff --git a/app/PersonTarget.php b/app/PersonTarget.php index 1ae83b8..940047e 100644 --- a/app/PersonTarget.php +++ b/app/PersonTarget.php @@ -2,18 +2,133 @@ namespace App; +use Illuminate\Support\Facades\DB; use Illuminate\Database\Eloquent\Model; class PersonTarget extends Model { + + /************************************************************************** + * PAYMENT STATES * + **************************************************************************/ + /* - * Get the signed amount of the target. + * Get all targets which are paid off. * - * @return float + * @return Illuminate\Database\Eloquent\Collection */ - public function signedAmount() + public static function paid() { - return $this->amount * $this->ioType->factor; + return PersonTarget::queryWhere('paid'); + } + + /* + * Get all targets which are underpaid. + * + * @return Illuminate\Database\Eloquent\Collection + */ + public static function underpaid() + { + return PersonTarget::queryWhere('underpaid'); + } + + /* + * Get all targets which are overpaid. + * + * @return Illuminate\Database\Eloquent\Collection + */ + public static function overpaid() + { + return PersonTarget::queryWhere('overpaid'); + } + + /* + * Get all targets which are a receivable. + * + * @return Illuminate\Database\Eloquent\Collection + */ + public static function receivable() + { + return PersonTarget::queryWhere('receivable'); + } + + /* + * Get all targets which are a debt. + * + * @return Illuminate\Database\Eloquent\Collection + */ + public static function debt() + { + return PersonTarget::queryWhere('debt'); + } + + /* + * Get the person targets which satisfy a given condition. + * Possible values for $cond are: + * + * 'paid' - all targets, which are paid + * 'underpaid' - all targets which are underpaid + * 'overpaid' - all targets which are overpaid + * 'receivable' - all targets which are a receivable, i. e. have a positive + * difference between target and actual value. + * 'debt' - all targets which are a debt, i. e. have a negative + * difference between target and actual value. + * + * @param string $cond + * @return array + */ + private static function queryWhere($cond) + { + // Set the having clause of the query according to the $cond argument. + $having = true; + + switch ($cond) { + case 'paid': + $having = 'target = actual'; + break; + case 'underpaid': + $having = '(target > 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); } /************************************************************************** @@ -31,7 +146,7 @@ class PersonTarget extends Model } /************************************************************************** - * IOTYPES * + * IO TYPES * **************************************************************************/ /* @@ -45,9 +160,19 @@ class PersonTarget extends Model } /************************************************************************** - * ACTUALS * + * 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. * @@ -76,6 +201,6 @@ class PersonTarget extends Model * @return float */ public function difference() { - return $this->actualsSum() + $this->signedAmount(); + return $this->signedAmount() - $this->actualsSum(); } }