stevebauman/maintenance

View on GitHub
app/Models/WorkOrder.php

Summary

Maintainability
A
3 hrs
Test Coverage
<?php

namespace App\Models;

use App\Models\Traits\HasCategoryTrait;
use App\Models\Traits\HasEventsTrait;
use App\Models\Traits\HasLocationTrait;
use App\Models\Traits\HasNotesTrait;
use App\Models\Traits\HasUserTrait;
use App\Viewers\WorkOrder\WorkOrderViewer;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletes;
use Orchestra\Support\Facades\HTML;

class WorkOrder extends Model
{
    use SoftDeletes, HasNotesTrait, HasLocationTrait, HasUserTrait, HasEventsTrait, HasCategoryTrait;

    /**
     * The work orders table.
     *
     * @var string
     */
    protected $table = 'work_orders';

    /**
     * The work orders viewer.
     *
     * @var string
     */
    protected $viewer = WorkOrderViewer::class;

    /**
     * The work orders fillable attributes.
     *
     * @var array
     */
    protected $fillable = [
        'user_id',
        'location_id',
        'category_id',
        'request_id',
        'status_id',
        'priority_id',
        'subject',
        'description',
        'started_at',
        'completed_at',
    ];

    /**
     * The columns to keep revisions of.
     *
     * @var array
     */
    protected $revisionColumns = [
        'location_id',
        'category_id',
        'status_id',
        'priority_id',
        'subject',
        'description',
        'started_at',
        'completed_at',
    ];

    /**
     * The work orders revisionable formatted field names.
     *
     * @var array
     */
    protected $revisionColumnsFormatted = [
        'location_id'  => 'Location',
        'category_id'  => 'Work Order Category',
        'status_id'    => 'Status',
        'priority_id'  => 'Priority',
        'subject'      => 'Subject',
        'description'  => 'Description',
        'started_at'   => 'Started At',
        'completed_at' => 'Completed At',
    ];

    /**
     * The revision column means attributes.
     *
     * @var array
     */
    protected $revisionColumnsMean = [
        'location_id'   => 'revised_location',
        'category_id'   => 'revised_category',
        'status_id'     => 'revised_status',
        'priority_id'   => 'revised_priority',
    ];

    /**
     * The belongsTo work request relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function request()
    {
        return $this->belongsTo(WorkRequest::class, 'request_id');
    }

    /**
     * The belongsToMany comments relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function comments()
    {
        return $this->belongsToMany(Comment::class, 'work_order_comments', 'work_order_id', 'comment_id');
    }

    /**
     * The hasOne status relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function status()
    {
        return $this->hasOne(Status::class, 'id', 'status_id');
    }

    /**
     * The hasOne priority relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function priority()
    {
        return $this->hasOne(Priority::class, 'id', 'priority_id');
    }

    /**
     * The belongsToMany assets relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function assets()
    {
        return $this->belongsToMany(Asset::class, 'work_order_assets', 'work_order_id', 'asset_id');
    }

    /**
     * The hasOne report relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function report()
    {
        return $this->hasOne(WorkOrderReport::class, 'work_order_id');
    }

    /**
     * The hasMany assignments relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function assignments()
    {
        return $this->hasMany(WorkOrderAssignment::class, 'work_order_id', 'id');
    }

    /**
     * The belongsToMany attachments relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function attachments()
    {
        return $this->belongsToMany(Attachment::class, 'work_order_attachments', 'work_order_id', 'attachment_id');
    }

    /**
     * The belongsToMany inventory parts relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function parts()
    {
        return $this->belongsToMany(InventoryStock::class, 'work_order_parts', 'work_order_id', 'stock_id')->withTimestamps()->withPivot('quantity');
    }

    /**
     * The hasMany sessions relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function sessions()
    {
        return $this->hasMany(WorkOrderSession::class, 'work_order_id')->latest();
    }

    /**
     * The hasMany notifiable users relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function notifiableUsers()
    {
        return $this->hasMany(WorkOrderNotification::class, 'work_order_id', 'id');
    }

    /**
     * Retrieves the revised status attribute.
     *
     * @param int|string $id
     *
     * @return null|string
     */
    public function getRevisedStatusAttribute($id)
    {
        if ($id) {
            $status = $this->status()->find($id);

            if ($status instanceof Status) {
                return $status->getLabel();
            }
        }

        return;
    }

    /**
     * Retrieves the revised priority attribute.
     *
     * @param int|string $id
     *
     * @return null|string
     */
    public function getRevisedPriorityAttribute($id)
    {
        if ($id) {
            $priority = $this->priority()->find($id);

            if ($priority instanceof Priority) {
                return $priority->getLabel();
            }
        }

        return;
    }

    /**
     * Closes all sessions on the current work order.
     *
     * @return array
     */
    public function closeSessions()
    {
        $closed = [];

        foreach ($this->sessions as $session) {
            if ($session instanceof WorkOrderSession && is_null($session->out)) {
                $session->out = $this->freshTimestamp();

                if ($session->save()) {
                    $closed[] = $session;
                }
            }
        }

        return $closed;
    }

    /**
     * Checks if the current work order is complete by checking if a report
     * has been filled out.
     *
     * @return bool
     */
    public function isComplete()
    {
        return $this->report ? true : false;
    }

    /**
     * Checks if the current work has workers assigned to it.
     *
     * @return bool
     */
    public function hasWorkersAssigned()
    {
        return $this->assignments->count() > 0;
    }

    /**
     * Checks if the user is currently checked into the current work order.
     *
     * @return bool
     */
    public function userCheckedIn()
    {
        $session = $this->getCurrentSession();

        if ($session instanceof WorkOrderSession) {
            return $session->in && is_null($session->out);
        }

        return false;
    }

    /**
     * Returns the current users work order session record.
     *
     * @return WorkOrderSession|null
     */
    public function getCurrentSession()
    {
        return $this->sessions()->where('user_id', auth()->id())->first();
    }

    /**
     * Alias for getUserNotifications().
     *
     * @return object
     */
    public function getNotifyAttribute()
    {
        return $this->getUserNotifications();
    }

    /**
     * Returns the current users work order notifications.
     *
     * @return object
     */
    public function getUserNotifications()
    {
        return $this->notifiableUsers()->where('user_id', auth()->id())->first();
    }

    /**
     * Returns the current work order
     * sessions for the specified user.
     *
     * @param int|string $userId
     *
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function getUserSessions($userId)
    {
        return $this->sessions()->where('user_id', $userId)->latest()->get();
    }

    /**
     * Returns the specified users last session.
     *
     * @param int|string $userId
     *
     * @return WorkOrderSession|null
     */
    public function getLastUsersSession($userId)
    {
        return $this->sessions()->where('user_id', $userId)->latest()->firstOrFail();
    }

    /**
     * Retrieves all of the users work order
     * sessions grouped by each user.
     *
     * @return Builder
     */
    public function getUniqueSessions()
    {
        return $this->sessions()->unique();
    }

    /**
     * Returns an HTML label for the work orders started at date.
     *
     * @return string
     */
    public function getStartedAtLabel()
    {
        if ($this->started_at) {
            $class = 'label label-success';
            $icon = 'fa fa-check';
            $message = $this->started_at;
        } else {
            $class = 'label label-danger';
            $icon = 'fa fa-times';
            $message = 'Has not been started.';
        }

        $icon = HTML::create('i', '', ['class' => $icon]);

        return HTML::raw("<span class='$class'>$icon $message</span>");
    }

    /**
     * Returns an HTML label for the work orders completed at date.
     *
     * @return string
     */
    public function getCompletedAtLabel()
    {
        if ($this->isComplete()) {
            $class = 'label label-success';
            $icon = 'fa fa-check';
            $message = $this->completed_at;
        } else {
            $class = 'label label-danger';
            $icon = 'fa fa-times';
            $message = 'No report has been created.';
        }

        $icon = HTML::create('i', '', ['class' => $icon]);

        return HTML::raw("<span class='$class'>$icon $message</span>");
    }

    /**
     * Set the default work order category id to null if the given value is empty.
     *
     * @param int|string $value
     */
    public function setCategoryIdAttribute($value)
    {
        $this->attributes['category_id'] = $value ? $value : null;
    }

    /**
     * Set the default location id to null if the given value is empty.
     *
     * @param int|string $value
     */
    public function setLocationIdAttribute($value)
    {
        $this->attributes['location_id'] = $value ? $value : null;
    }

    /**
     * Completes the work order by saving the completed at timestamp to now.
     *
     * @param int|string $statusId
     *
     * @return $this|bool
     */
    public function complete($statusId)
    {
        if (is_null($this->started_at)) {
            $this->started_at = $this->freshTimestamp();
        }

        $this->completed_at = $this->freshTimestamp();
        $this->status_id = $statusId;

        return $this->save();
    }
}