%PDF- %PDF-
Mini Shell

Mini Shell

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

<?php

namespace App\Models;

use App\Exceptions\ProjectNotFoundException;
use App\Notifications\NotifyClientForProgressUpdate;
use Carbon\Carbon;
use Exception as ExceptionAlias;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded;
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded\InvalidBase64Data;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;

/**
 * @property integer id
 * @property string code
 * @property string name
 * @property string location
 * @property string person_responsible
 * @property mixed due_date
 * @property string status
 * @property string person_responsible_email
 * @property string person_responsible_phone
 * @property integer manager_id
 * @property integer client_id
 * @property mixed media
 * @property mixed services
 * @property User client
 * @property User manager
 */
class Project extends BaseModel implements HasMedia
{
    use SoftDeletes, HasMediaTrait;

    const PROJECT = 'projects';
    const PROJECT_DISK = 'projects';

    const DOCUMENTS = 'project_documents';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'code',
        'location',
        'person_responsible',
        'person_responsible_email',
        'person_responsible_phone',
        'due_date',
        'status',
    ];

    protected $casts = [
        'name'                     => 'string',
        'code'                     => 'string',
        'person_responsible'       => 'string',
        'person_responsible_email' => 'string',
        'person_responsible_phone' => 'string',
        'due_date'                 => 'date',
        'budget'                   => 'integer',
        'status'                   => 'string',
    ];

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

    protected $dates = [
        'due_date',
    ];

    public static function generateNewCode()
    {
        $count = self::withTrashed()
                     ->count() + 1;
        return str_pad($count, 10, "0", STR_PAD_LEFT);
    }

    /**
     * @param $code
     * @return \Illuminate\Database\Eloquent\Builder|Model|object|null
     * @throws ProjectNotFoundException
     */
    public static function getByCode($code)
    {
        $project = self::query()
                       ->where('code', $code)
                       ->first();
        if (!$project) {
            throw new ProjectNotFoundException();
        }
        return $project;
    }

    /**
     * @param Builder $query
     * @return mixed
     */
    public function scopeOrdered($query)
    {
        return $query->orderByRaw("FIELD(status , 'DONE') ASC")
                     ->orderBy('due_date', 'ASC');
    }

    /**
     *
     */
    public function registerMediaCollections()
    {
        $this->addMediaCollection(self::PROJECT)
             ->useDisk(self::PROJECT_DISK);
    }

    public function services()
    {
        return $this->belongsToMany(Service::class);
    }

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

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

    public function statuses()
    {
        return $this->hasMany(ProjectStatus::class);
    }

    public function postCreated()
    {
        ProjectStatus::createStatus($this, auth()
            ->guard('api')
            ->user(), ProjectStatus::CREATED);
    }

    /**
     * @return bool
     * @throws ExceptionAlias
     */
    public function requestQuotation()
    {
        $status = ProjectStatus::IN_REVIEW;
        if ($this->status === $status || $this->status === ProjectStatus::CANCELED) {
            return false;
        }

        DB::beginTransaction();
        try {
            $this->status = $status;
            $user = auth()
                ->guard('api')
                ->user();
            ProjectStatus::createStatus($this, $user, $status);
            /** @var ProjectNote $note */
            $note = $this->notes()
                         ->make([
                             'message' => 'Hey there! I\'d like to request a quotation for this project.',
                         ]);
            $note->user()
                 ->associate($user);
            $note->save();
            $this->save();
            DB::commit();
            return true;
        } catch (ExceptionAlias $e) {
            DB::rollBack();
            throw $e;
        }
    }

    public function notes()
    {
        return $this->hasMany(ProjectNote::class);
    }

    /**
     * @param $managerId
     * @return bool
     * @throws ExceptionAlias
     */
    public function acceptQuotation($managerId)
    {
        $status = ProjectStatus::TODO;
        if ($this->status === ProjectStatus::TODO || $this->status !== ProjectStatus::IN_REVIEW) {
            return false;
        }

        DB::beginTransaction();
        try {
            $this->status = $status;
            $this->manager_id = $managerId;
            ProjectStatus::createStatus($this, auth()
                ->guard('api')
                ->user(), $status);
            $this->save();
            DB::commit();
            return true;
        } catch (ExceptionAlias $e) {
            DB::rollBack();
            throw $e;
        }
    }

    /**
     * @return bool
     * @throws ExceptionAlias
     */
    public function rejectQuotation()
    {
        $status = ProjectStatus::REJECTED;
        if ($this->status === ProjectStatus::REJECTED || $this->status !== ProjectStatus::IN_REVIEW) {
            return false;
        }

        DB::beginTransaction();
        try {
            $this->status = $status;
            ProjectStatus::createStatus($this, auth()
                ->guard('api')
                ->user(), $status);
            $this->save();
            DB::commit();
            return true;
        } catch (ExceptionAlias $e) {
            DB::rollBack();
            throw $e;
        }
    }

    /**
     * @param $message
     * @return bool
     * @throws ExceptionAlias
     */
    public function respond($message)
    {
        $status = ProjectStatus::TODO;
        if ($this->status !== ProjectStatus::IN_REVIEW) {
            return false;
        }
        DB::beginTransaction();
        try {
            $this->status = $status;
            ProjectStatus::createStatus($this, auth()
                ->guard('api')
                ->user(), $status);
            $this->save();
            /** @var ProjectNote $note */
            $note = $this->notes()
                         ->make([
                             'message' => $message,
                         ]);
            $note->user()
                 ->associate($this->getLoggedInUser());
            $note->save();
            DB::commit();
            return true;
        } catch (ExceptionAlias $e) {
            DB::rollBack();
            throw $e;
        }
    }

    public function cancel()
    {
        $status = ProjectStatus::CANCELED;
        if ($this->status !== $status) {
            $this->status = $status;
            ProjectStatus::createStatus($this, auth()
                ->guard('api')
                ->user(), $status);
            $this->save();
            return true;
        }
        return false;
    }

    public function markAsDone()
    {
        $status = ProjectStatus::DONE;
        if ($this->status !== $status) {
            $this->status = $status;
            ProjectStatus::createStatus($this, auth()
                ->guard('api')
                ->user(), $status);
            $this->save();
            return true;
        }
        return false;
    }

    public function canUploadFiles()
    {
        return true;
    }

    public function canDeleteFiles()
    {
        $user = $this->getLoggedInUser();
        return $user && $user->isAdmin();
    }

    public function canEdit()
    {
        return ($this->status !== ProjectStatus::CANCELED && ($this->status === ProjectStatus::DRAFT || $this->status === ProjectStatus::REJECTED)) && $this->isClient();
    }

    public function canRequestQuotation()
    {
        return ($this->status === ProjectStatus::DRAFT || $this->status === ProjectStatus::REJECTED) && $this->isClient();
    }

    public function canAcceptQuotation()
    {
        return $this->status === ProjectStatus::IN_REVIEW && !$this->isClient();
    }

    public function canRejectQuotation()
    {
        return $this->status === ProjectStatus::IN_REVIEW && !$this->isClient();
    }

    /**
     * @param $baseImage
     *
     * @return Project
     * @throws FileCannotBeAdded
     * @throws InvalidBase64Data
     */
    public function uploadImage($baseImage)
    {
        $name = md5(time());
        try {
            if ($media = $this->getMedia(self::PROJECT)
                              ->first()) {
                $media->delete();
            }
            $this->addMediaFromBase64($baseImage)
                 ->usingName($name)
                 ->usingFileName("$name.png")
                 ->toMediaCollection(self::PROJECT);
            return $this;
        } catch (InvalidBase64Data $e) {
            throw $e;
        } catch (FileCannotBeAdded $e) {
            throw $e;
        }
    }

    /**
     * @return string
     */
    public function getLogo()
    {
        $media = $this->getMedia(self::PROJECT)
                      ->first();
        if ($media) {
            return asset($media->getUrl());
        }
        return asset('svg/project.png');
    }

    public function getDocuments()
    {
        return $this->getMedia(self::DOCUMENTS);
    }

    public function getDocumentsCount()
    {
        return $this->media()
                    ->where('collection_name', self::DOCUMENTS)
                    ->count();
    }

    public function deleteMedia($ids = [])
    {
        $this->media()
             ->whereIn('id', $ids)
             ->delete();
    }

    public function getLastMessageDate()
    {
        /** @var ProjectNote $note */
        $note = $this->notes()
                     ->latest()
                     ->first();
        return $note->updated_at;
    }

    public function canUpdateStatus()
    {
        return $this->status !== ProjectStatus::IN_REVIEW && !$this->isClient();
    }

    public function updateStatus($status)
    {
        if ($this->status !== $status) {
            $this->status = $status;
            ProjectStatus::createStatus($this, auth()
                ->guard('api')
                ->user(), $status);
            $this->save();
            /** @var ProjectNote $note */
            $note = $this->notes()
                         ->make([
                             'message' => ProjectStatus::getMessageByStatus($status),
                         ]);
            $note->user()
                 ->associate($this->getLoggedInUser());
            $note->save();
            $this->client->notify(new NotifyClientForProgressUpdate($this));
            return true;
        }
        return false;
    }

    public function getUnreadCount()
    {
        $user = $this->getLoggedInUser();
        /** @var Reciption $reciption */
        $reciption = Reciption::query()
                              ->where([
                                  'user_id'    => $user->id,
                                  'project_id' => $this->id,
                              ])
                              ->first();
        $date = $reciption
            ? Carbon::parse($reciption->last_read_at)
            : Carbon::now()
                    ->subCenturies(1);
        return ProjectNote::query()
                          ->where('project_id', $this->id)
                          ->where('created_at', '>', $date)
                          ->count();
    }

}

Zerion Mini Shell 1.0