%PDF- %PDF-
Direktori : /var/www/html/geotechnics/api/app/Models/ |
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(); } }