Initial Ladill Queue release — enterprise QMS standalone app.
Deploy Ladill Queue / deploy (push) Successful in 56s
Deploy Ladill Queue / deploy (push) Successful in 56s
Phases 1–6: tickets, counters, displays, appointments, workflows, rules, analytics, reports, feedback, admin, device API, and Gitea deploy workflow for queue.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class AuditLog extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'queue_audit_logs';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'actor_ref', 'action',
|
||||
'subject_type', 'subject_id', 'metadata', 'ip_address', 'created_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'metadata' => 'array',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public static function record(
|
||||
string $ownerRef,
|
||||
string $action,
|
||||
?int $organizationId = null,
|
||||
?string $actorRef = null,
|
||||
?string $subjectType = null,
|
||||
?int $subjectId = null,
|
||||
?array $metadata = null,
|
||||
): self {
|
||||
return static::create([
|
||||
'owner_ref' => $ownerRef,
|
||||
'organization_id' => $organizationId,
|
||||
'actor_ref' => $actorRef,
|
||||
'action' => $action,
|
||||
'subject_type' => $subjectType,
|
||||
'subject_id' => $subjectId,
|
||||
'metadata' => $metadata,
|
||||
'ip_address' => request()?->ip(),
|
||||
'created_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Branch extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_branches';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'name', 'code', 'address', 'phone', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_active' => 'boolean'];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function departments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Department::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function serviceQueues(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceQueue::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function counters(): HasMany
|
||||
{
|
||||
return $this->hasMany(Counter::class, 'branch_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait BelongsToOwner
|
||||
{
|
||||
public function scopeOwned(Builder $query, string $ownerRef): Builder
|
||||
{
|
||||
return $query->where($this->getTable().'.owner_ref', $ownerRef);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Counter extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_counters';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'department_id',
|
||||
'name', 'code', 'status', 'settings', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'settings' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $counter) {
|
||||
$counter->uuid ??= (string) Str::uuid();
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function department(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Department::class, 'department_id');
|
||||
}
|
||||
|
||||
public function serviceQueues(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(ServiceQueue::class, 'queue_counter_service_queue', 'counter_id', 'service_queue_id')
|
||||
->withPivot('priority');
|
||||
}
|
||||
|
||||
public function tickets(): HasMany
|
||||
{
|
||||
return $this->hasMany(Ticket::class, 'counter_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CustomerFeedback extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'queue_customer_feedback';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'ticket_id', 'counter_id',
|
||||
'rating', 'service_quality', 'wait_experience', 'staff_professionalism', 'comments',
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
$model->uuid ??= (string) Str::uuid();
|
||||
});
|
||||
}
|
||||
|
||||
public function ticket(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class, 'ticket_id');
|
||||
}
|
||||
|
||||
public function counter(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Counter::class, 'counter_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Department extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_departments';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'branch_id', 'name', 'type', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_active' => 'boolean'];
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Device extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_devices';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id',
|
||||
'name', 'type', 'status', 'device_token', 'config', 'last_online_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'config' => 'array',
|
||||
'last_online_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $device) {
|
||||
$device->uuid ??= (string) Str::uuid();
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DisplayScreen extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_display_screens';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id',
|
||||
'name', 'layout', 'access_token', 'service_queue_ids', 'settings', 'is_active', 'last_seen_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'service_queue_ids' => 'array',
|
||||
'settings' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
'last_seen_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $screen) {
|
||||
$screen->uuid ??= (string) Str::uuid();
|
||||
$screen->access_token ??= Str::random(48);
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Member extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'queue_members';
|
||||
|
||||
protected $fillable = ['owner_ref', 'organization_id', 'user_ref', 'role', 'branch_id'];
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function hasRole(string ...$roles): bool
|
||||
{
|
||||
return in_array($this->role, $roles, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Organization extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_organizations';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'name', 'slug', 'logo_path', 'timezone', 'settings',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['settings' => 'array'];
|
||||
}
|
||||
|
||||
public function branches(): HasMany
|
||||
{
|
||||
return $this->hasMany(Branch::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function members(): HasMany
|
||||
{
|
||||
return $this->hasMany(Member::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function serviceQueues(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceQueue::class, 'organization_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class QueueAppointment extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_appointments';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'service_queue_id', 'ticket_id',
|
||||
'customer_name', 'customer_phone', 'customer_email', 'status', 'mode',
|
||||
'scheduled_at', 'checked_in_at', 'reference', 'metadata',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'scheduled_at' => 'datetime',
|
||||
'checked_in_at' => 'datetime',
|
||||
'metadata' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
$model->uuid ??= (string) Str::uuid();
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function serviceQueue(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ServiceQueue::class, 'service_queue_id');
|
||||
}
|
||||
|
||||
public function ticket(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class, 'ticket_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class QueueRule extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'queue_queue_rules';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'service_queue_id', 'rule_type', 'conditions', 'actions', 'sort_order', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'conditions' => 'array',
|
||||
'actions' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function serviceQueue(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ServiceQueue::class, 'service_queue_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ServiceQueue extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_service_queues';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'department_id',
|
||||
'name', 'description', 'color', 'prefix', 'strategy',
|
||||
'max_capacity', 'avg_service_seconds', 'operating_hours', 'priority_rules',
|
||||
'settings', 'is_active', 'is_paused', 'ticket_sequence',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'operating_hours' => 'array',
|
||||
'priority_rules' => 'array',
|
||||
'settings' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
'is_paused' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $queue) {
|
||||
$queue->uuid ??= (string) Str::uuid();
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function department(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Department::class, 'department_id');
|
||||
}
|
||||
|
||||
public function tickets(): HasMany
|
||||
{
|
||||
return $this->hasMany(Ticket::class, 'service_queue_id');
|
||||
}
|
||||
|
||||
public function counters(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Counter::class, 'queue_counter_service_queue', 'service_queue_id', 'counter_id')
|
||||
->withPivot('priority');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class ServiceSession extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'queue_service_sessions';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'ticket_id', 'counter_id', 'staff_ref',
|
||||
'started_at', 'ended_at', 'duration_seconds',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'started_at' => 'datetime',
|
||||
'ended_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function ticket(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class, 'ticket_id');
|
||||
}
|
||||
|
||||
public function counter(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Counter::class, 'counter_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Ticket extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_tickets';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'service_queue_id', 'counter_id',
|
||||
'ticket_number', 'status', 'priority', 'position', 'customer_name', 'customer_phone',
|
||||
'customer_email', 'source', 'qr_token', 'barcode', 'estimated_wait_seconds',
|
||||
'issued_at', 'called_at', 'serving_started_at', 'completed_at', 'metadata',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'metadata' => 'array',
|
||||
'issued_at' => 'datetime',
|
||||
'called_at' => 'datetime',
|
||||
'serving_started_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $ticket) {
|
||||
$ticket->uuid ??= (string) Str::uuid();
|
||||
$ticket->qr_token ??= Str::random(32);
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function serviceQueue(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ServiceQueue::class, 'service_queue_id');
|
||||
}
|
||||
|
||||
public function counter(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Counter::class, 'counter_id');
|
||||
}
|
||||
|
||||
public function events(): HasMany
|
||||
{
|
||||
return $this->hasMany(TicketEvent::class, 'ticket_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class TicketEvent extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'queue_ticket_events';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'ticket_id', 'event', 'actor_ref', 'counter_id', 'metadata', 'created_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'metadata' => 'array',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function ticket(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class, 'ticket_id');
|
||||
}
|
||||
|
||||
public function counter(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Counter::class, 'counter_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
/**
|
||||
* Thin local mirror of the platform identity (auth.ladill.com owns users).
|
||||
* Keyed by the OIDC `sub` (public_id); every CRM record is scoped to it.
|
||||
*/
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, Notifiable;
|
||||
|
||||
protected $fillable = ['public_id', 'name', 'email', 'avatar_url', 'password', 'last_app_active_at'];
|
||||
|
||||
protected $hidden = ['password', 'remember_token'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_app_active_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
|
||||
/** The owner reference used to scope every CRM record to this account. */
|
||||
public function ownerRef(): string
|
||||
{
|
||||
return (string) $this->public_id;
|
||||
}
|
||||
|
||||
public function avatarUrl(): ?string
|
||||
{
|
||||
$url = trim((string) $this->avatar_url);
|
||||
|
||||
return $url !== '' ? $url : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class VoiceAnnouncement extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'queue_voice_announcements';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'branch_id', 'ticket_id',
|
||||
'locale', 'message', 'voice', 'volume', 'repeat_count', 'status', 'played_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'played_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function ticket(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class, 'ticket_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Workflow extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'queue_workflows';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id',
|
||||
'name', 'description', 'industry_template', 'is_active', 'settings',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'settings' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
$model->uuid ??= (string) Str::uuid();
|
||||
});
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function steps(): HasMany
|
||||
{
|
||||
return $this->hasMany(WorkflowStep::class, 'workflow_id')->orderBy('sort_order');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class WorkflowStep extends Model
|
||||
{
|
||||
protected $table = 'queue_workflow_steps';
|
||||
|
||||
protected $fillable = [
|
||||
'workflow_id', 'service_queue_id', 'name', 'sort_order', 'settings',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['settings' => 'array'];
|
||||
}
|
||||
|
||||
public function workflow(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Workflow::class, 'workflow_id');
|
||||
}
|
||||
|
||||
public function serviceQueue(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ServiceQueue::class, 'service_queue_id');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user