first commit
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled

This commit is contained in:
2025-04-23 00:14:33 +06:00
commit 356f56eebd
197 changed files with 21536 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ActivityLog extends Model
{
protected $table = 'activity_log';
protected $fillable = [
'log_name',
'description',
'subject_id',
'subject_type',
'causer_id',
'causer_type',
'properties'
];
public function subject()
{
return $this->morphTo();
}
public function causer()
{
return $this->morphTo();
}
}

24
app/Models/Approval.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Approval extends Model
{
protected $casts = [
'metadata' => 'array',
'step' => ApprovalStep::class
];
public function transitionTo($status, $comment = null)
{
$this->update([
'status' => $status,
'comment' => $comment,
'completed_at' => now()
]);
$this->document->notifyApprovers();
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ApprovalWorkflow extends Model
{
protected $casts = ['steps' => 'array'];
public function getCurrentStep(Document $document)
{
$lastApproval = $document->approvals()->latest()->first();
return $lastApproval ? $this->steps[$lastApproval->step_index + 1] : $this->steps[0];
}
}

17
app/Models/Category.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Category extends Model
{
protected $fillable = ['name', 'slug'];
public function projects(): BelongsToMany
{
return $this->belongsToMany(Project::class);
}
}

75
app/Models/Document.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
namespace App\Models;
use App\Events\DocumentVersionUpdated;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
class Document extends Model
{
use LogsActivity;
protected static $logAttributes = ['name', 'status'];
protected static $logOnlyDirty = true;
protected $fillable = [
'name',
'status',
'project_id',
'folder_id',
'current_version_id'
];
public function versions() {
return $this->hasMany(DocumentVersion::class);
}
public function approvals() {
return $this->hasMany(Approval::class);
}
public function comments() {
return $this->hasMany(Comment::class)->whereNull('parent_id');
}
public function createVersion($file)
{
return $this->versions()->create([
'file_path' => $file->store("documents/{$this->id}/versions"),
'hash' => hash_file('sha256', $file),
'user_id' => auth()->id(),
'version_number' => $this->versions()->count() + 1
]);
}
public function getCurrentVersionAttribute()
{
return $this->versions()->latest()->first();
}
public function uploadVersion($file)
{
$this->versions()->create([
'file_path' => $file->store("projects/{$this->id}/versions"),
'hash' => hash_file('sha256', $file),
'version' => $this->versions()->count() + 1,
'user_id' => auth()->id()
]);
event(new DocumentVersionUpdated($this));
return $version;
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logExcept(['current_version_id'])
->logUnguarded();
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DocumentVersion extends Model
{
//
}

43
app/Models/Folder.php Normal file
View File

@@ -0,0 +1,43 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Folder extends Model
{
protected $fillable = [
'name',
'parent_id',
'project_id',
'icon',
'color',
'description',
];
public function descendants()
{
return $this->belongsToMany(Folder::class, 'folder_closure', 'ancestor_id', 'descendant_id')
->withPivot('depth');
}
public function documents()
{
return $this->hasMany(Document::class);
}
public function parent()
{
return $this->belongsTo(Folder::class, 'parent_id');
}
public function children()
{
return $this->hasMany(Folder::class, 'parent_id')->with('children');
}
public function project()
{
return $this->belongsTo(Project::class);
}
}

80
app/Models/Project.php Normal file
View File

@@ -0,0 +1,80 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
protected $fillable = [
'name',
'description',
'creator_id',
'status',
'project_image_path',
'address',
'province',
'country',
'postal_code',
'latitude',
'longitude',
'icon',
'start_date',
'deadline',
// Agrega cualquier otro campo nuevo aquí
];
public function folders() {
return $this->hasMany(Folder::class);
}
public function documents() {
return $this->hasMany(Document::class);
}
public function rootFolders()
{
return $this->folders()->whereNull('parent_id')->with('children');
}
public function creator()
{
return $this->belongsTo(User::class, 'creator_id');
}
public function managers()
{
return $this->belongsToMany(User::class, 'project_managers');
}
public function users()
{
return $this->belongsToMany(User::class, 'project_users');
}
public function scopeFilter(Builder $query, array $filters)
{
$query->when($filters['search'] ?? false, function($query, $search) {
$query->where(function($query) use ($search) {
$query->where('name', 'like', "%{$search}%")
->orWhere('description', 'like', "%{$search}%");
});
});
// Agrega más filtros según necesites
/*
$query->when($filters['status'] ?? false, function($query, $status) {
$query->where('status', $status);
});
*/
}
public function categories()
{
return $this->belongsToMany(Category::class);
}
}

63
app/Models/User.php Normal file
View File

@@ -0,0 +1,63 @@
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;
use HasRoles;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'is_protected' => 'boolean',
];
}
/**
* Get the user's initials
*/
public function initials(): string
{
return Str::of($this->name)
->explode(' ')
->map(fn (string $name) => Str::of($name)->substr(0, 1))
->implode('');
}
}