new helpdesk module
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
final class Attachment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'helpdesk_attachments';
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = ['ticket_id', 'comment_id', 'user_id', 'disk', 'path', 'original_name', 'mime_type', 'size'];
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = ['size' => 'integer'];
|
||||
|
||||
/** @return BelongsTo<Ticket, Attachment> */
|
||||
public function ticket(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class, 'ticket_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<Comment, Attachment> */
|
||||
public function comment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Comment::class, 'comment_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<User, Attachment> */
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
public function url(): string
|
||||
{
|
||||
return Storage::disk($this->disk)->url($this->path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
final class Category extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'helpdesk_categories';
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = ['name', 'slug', 'color', 'description'];
|
||||
|
||||
/** @return HasMany<Ticket> */
|
||||
public function tickets(): HasMany
|
||||
{
|
||||
return $this->hasMany(Ticket::class, 'category_id');
|
||||
}
|
||||
|
||||
/** @return BelongsToMany<User> */
|
||||
public function agents(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'helpdesk_category_user', 'category_id', 'user_id')->withTimestamps();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
final class Comment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'helpdesk_comments';
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = ['ticket_id', 'user_id', 'body', 'is_internal'];
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = ['is_internal' => 'boolean'];
|
||||
|
||||
/** @return BelongsTo<Ticket, Comment> */
|
||||
public function ticket(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class, 'ticket_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<User, Comment> */
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
/** @return HasMany<Attachment> */
|
||||
public function attachments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Attachment::class, 'comment_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
final class Priority extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'helpdesk_priorities';
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = ['name', 'slug', 'color', 'sort_order'];
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = ['sort_order' => 'integer'];
|
||||
|
||||
/** @return HasMany<Ticket> */
|
||||
public function tickets(): HasMany
|
||||
{
|
||||
return $this->hasMany(Ticket::class, 'priority_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
final class Project extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'helpdesk_projects';
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = ['title', 'slug', 'color', 'description', 'archived_at'];
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = ['archived_at' => 'datetime'];
|
||||
|
||||
/** @return HasMany<Ticket> */
|
||||
public function tickets(): HasMany
|
||||
{
|
||||
return $this->hasMany(Ticket::class, 'project_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $slug
|
||||
* @property string $color
|
||||
* @property bool $is_closed
|
||||
*/
|
||||
final class Status extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'helpdesk_statuses';
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = ['name', 'slug', 'color', 'sort_order', 'is_closed'];
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = ['is_closed' => 'boolean', 'sort_order' => 'integer'];
|
||||
|
||||
/** @return HasMany<Ticket> */
|
||||
public function tickets(): HasMany
|
||||
{
|
||||
return $this->hasMany(Ticket::class, 'status_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $reference
|
||||
* @property string $subject
|
||||
* @property string $body
|
||||
*/
|
||||
final class Ticket extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'helpdesk_tickets';
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'reference', 'user_id', 'agent_id', 'status_id', 'priority_id', 'category_id', 'project_id',
|
||||
'subject', 'body', 'due_at', 'completed_at', 'last_activity_at', 'archived_at',
|
||||
];
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = [
|
||||
'due_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
'last_activity_at' => 'datetime',
|
||||
'archived_at' => 'datetime',
|
||||
];
|
||||
|
||||
/** @return BelongsTo<User, Ticket> */
|
||||
public function owner(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<User, Ticket> */
|
||||
public function agent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'agent_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<Status, Ticket> */
|
||||
public function status(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Status::class, 'status_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<Priority, Ticket> */
|
||||
public function priority(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Priority::class, 'priority_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<Category, Ticket> */
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class, 'category_id');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<Project, Ticket> */
|
||||
public function project(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Project::class, 'project_id');
|
||||
}
|
||||
|
||||
/** @return HasMany<Comment> */
|
||||
public function comments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'ticket_id')->latest();
|
||||
}
|
||||
|
||||
/** @return HasMany<Attachment> */
|
||||
public function attachments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Attachment::class, 'ticket_id')->latest();
|
||||
}
|
||||
|
||||
/** @param Builder<Ticket> $query @return Builder<Ticket> */
|
||||
public function scopeOpen(Builder $query): Builder
|
||||
{
|
||||
return $query->whereNull('completed_at');
|
||||
}
|
||||
|
||||
/** @param Builder<Ticket> $query @return Builder<Ticket> */
|
||||
public function scopeVisibleTo(Builder $query, User $user): Builder
|
||||
{
|
||||
if ((bool) ($user->helpdesk_admin ?? false)) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
if ((bool) ($user->helpdesk_agent ?? false)) {
|
||||
return $query->where(static function (Builder $subQuery) use ($user): void {
|
||||
$subQuery->where('agent_id', $user->id)->orWhere('user_id', $user->id);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->where('user_id', $user->id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user