%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /var/www/html/hrsys/api/app/Models/
Upload File :
Create Path :
Current File : /var/www/html/hrsys/api/app/Models/Project.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Throwable;

/**
 * @property integer id
 * @property string code
 * @property string name
 * @property mixed start_date
 * @property mixed end_date
 * @property integer estimation
 * @property integer price
 * @property string currency
 * @property string notes
 * @property integer client_id
 * @property integer manager_id
 * @property Client client
 * @property User manager
 * @property mixed users
 * @property boolean is_private
 */
class Project extends BaseModel
{
    const EURO = 'EURO';
    const ALL = 'ALBANIAN_LEK';
    const USD = 'USD';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'code',
        'name',
        'start_date',
        'end_date',
        'estimation',
        'price',
        'currency',
        'notes',
        'is_private',
    ];

    protected $guarded = [
        'client_id',
        'manager_id',
    ];

    protected $dates = [
        'start_date',
        'end_date',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'id'         => 'integer',
        'code'       => 'string',
        'name'       => 'string',
        'start_date' => 'date',
        'end_date'   => 'date',
        'estimation' => 'integer',
        'price'      => 'integer',
        'currency'   => 'string',
        'notes'      => 'string',
        'client_id'  => 'integer',
        'manager_id' => 'integer',
    ];

    /**
     * @param $data
     * @return Project
     * @throws Throwable
     */
    public static function createItem($data)
    {
        try {
            DB::beginTransaction();
            /** @var Project $project */
            $project = self::query()
                           ->make([
                               'code'       => $data['code'],
                               'name'       => $data['name'],
                               'start_date' => $data['start_date'],
                               'end_date'   => $data['end_date'],
                               'estimation' => $data['estimation'],
                               'price'      => $data['price'],
                               'currency'   => array_key_exists('currency', $data)
                                   ? $data['currency']
                                   : self::EURO,
                               'notes'      => array_key_exists('notes', $data)
                                   ? $data['notes']
                                   : null,
                           ]);
            $project->client()
                    ->associate($data['client_id']);
            $project->manager()
                    ->associate($data['manager_id']);
            $project->save();
            DB::commit();
            return $project;
        } catch (Throwable $e) {
            DB::rollBack();
            throw $e;
        }
    }

    public function client()
    {
        return $this->belongsTo(Client::class);
    }

    public function manager()
    {
        return $this->belongsTo(User::class, 'manager_id');
    }

    public function scopePrivate(Builder $query, $user)
    {
        return $query->where(function (Builder $q) use ($user) {
            $q->where('is_private', false);
            $q->orWhere(function (Builder $u) use ($user) {
                $u->where('is_private', true);
                $u->where('manager_id', $user->id);
            });
        });
    }

    /**
     * @param $data
     * @return Project
     * @throws Throwable
     */
    public function updateItem($data)
    {
        try {
            DB::beginTransaction();
            $this->update([
                'code'       => $data['code'],
                'name'       => $data['name'],
                'start_date' => $data['start_date'],
                'end_date'   => $data['end_date'],
                'estimation' => $data['estimation'],
                'price'      => $data['price'],
                'currency'   => array_key_exists('currency', $data)
                    ? $data['currency']
                    : self::EURO,
                'notes'      => array_key_exists('notes', $data)
                    ? $data['notes']
                    : null,
            ]);
            $this->client()
                 ->associate($data['client_id']);
            $this->manager()
                 ->associate($data['manager_id']);
            $this->save();
            DB::commit();
            return $this;
        } catch (Throwable $e) {
            DB::rollBack();
            throw $e;
        }
    }

    public function timecards()
    {
        return $this->hasMany(Timecard::class);
    }

    public function users()
    {
        return $this->belongsToMany(User::class, 'user_project');
    }

    public function canLogTimecard($userId)
    {
        return self::query()
                   ->where('manager_id', $userId)
                   ->orWhereHas('users', function (Builder $q) use ($userId) {
                       $q->where('user_id', $userId);
                   })
                   ->exists();
    }

    public function performance()
    {
        $totalHours = Timecard::query()
                              ->where('project_id', $this->id)
                              ->get([
                                  DB::raw('SUM(hours) as hours'),
                              ]);
        $approvedTimecard = Timecard::query()
                                    ->where('project_id', $this->id)
                                    ->where('status', Timecard::APPROVED)
                                    ->get([
                                        DB::raw('SUM(hours) as hours'),
                                        DB::raw('SUM(approved_hours) as approved_hours'),
                                    ]);

        $totalWorked = head(head($totalHours))->hours;
        $toApprove = head(head($totalHours))->hours - head(head($approvedTimecard))->hours;
        $approvedHours = head(head($approvedTimecard))->approved_hours;

        $users = Timecard::query()
                         ->where('project_id', $this->id)
                         ->groupBy('user_id')
                         ->get('user_id')
                         ->pluck('user_id');
        $usersPerformance = collect();
        foreach ($users as $user) {
            /** @var User $user */
            $user = User::query()
                        ->find($user);
            $usersPerformance->push($this->getUserPerformance($user));
        }

        return [
            'total_worked'      => $totalWorked,
            'to_approve'        => $toApprove,
            'approved_hours'    => $approvedHours,
            'performance'       => round(100 * $approvedHours / max($totalWorked, 1), 0) . "%",
            'users_performance' => $usersPerformance,
        ];
    }

    public function getUserPerformance(User $user)
    {
        $hoursWorked = Timecard::query()
                               ->where('project_id', $this->id)
                               ->where('user_id', $user->id)
                               ->get([
                                   DB::raw('SUM(hours) as hours'),
                                   DB::raw('SUM(approved_hours) as approved_hours'),
                               ]);
        $toApprove = Timecard::query()
                             ->where('project_id', $this->id)
                             ->where('user_id', $user->id)
                             ->where('status', Timecard::TO_APPROVE)
                             ->get([
                                 DB::raw('SUM(hours) as hours'),
                             ]);
        $totalWorked = head(head($hoursWorked))->hours;
        $toApprove = head(head($toApprove))->hours;
        $approvedHours = head(head($hoursWorked))->approved_hours;
        $performance = round(100 * $approvedHours / max($totalWorked, 1), 0) . "%";
        return [
            'name'           => $user->getFullName(),
            'total_worked'   => $totalWorked,
            'to_approve'     => $toApprove,
            'approved_hours' => $approvedHours,
            'performance'    => $performance,
        ];
    }

    public function getPaymentInfo()
    {
        $approvedTimecard = Timecard::query()
                                    ->where('project_id', $this->id)
                                    ->where('status', Timecard::APPROVED)
                                    ->get([
                                        DB::raw('SUM(approved_hours) as approved_hours'),
                                    ]);
        $payments = $this->payments()
                         ->where('status', Payment::PAID)
                         ->get(DB::raw('SUM(amount) as amount'));

        $approvedHours = head(head($approvedTimecard))->approved_hours;
        $estimatedPayment = $this->estimation * $this->price;
        $approvedPayment = $approvedHours * $this->price;
        $paid = head(head($payments))->amount;
        return [
            'estimation'        => $this->estimation,
            'estimated_payment' => $estimatedPayment,
            'approved_payment'  => $approvedPayment,
            'paid'              => $paid,
            'to_pay'            => max($approvedPayment - $paid, 0),
            'currency'          => $this->currency,
        ];
    }

    public function payments()
    {
        return $this->hasMany(Payment::class);
    }

}

Zerion Mini Shell 1.0