Mager updated

This commit is contained in:
Simon Pocrnjič
2025-09-27 17:45:55 +02:00
parent d17e34941b
commit 7227c888d4
74 changed files with 6339 additions and 342 deletions
+9
View File
@@ -12,6 +12,15 @@ class Account extends Model
/** @use HasFactory<\Database\Factories\Person/AccountFactory> */
use HasFactory;
protected $fillable = [
'reference',
'description',
'contract_id',
'type_id',
'active',
'balance_amount',
];
public function debtor(): BelongsTo
{
return $this->belongsTo(\App\Models\Person\Person::class, 'debtor_id');
+8 -1
View File
@@ -8,6 +8,7 @@
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Builder;
use Laravel\Scout\Searchable;
@@ -19,7 +20,8 @@ class ClientCase extends Model
use Searchable;
protected $fillable = [
'client_id'
'client_id',
'person_id'
];
protected $hidden = [
@@ -65,4 +67,9 @@ public function activities(): HasMany
public function segments(): BelongsToMany {
return $this->belongsToMany(\App\Models\Segment::class)->withTimestamps();
}
public function documents(): MorphMany
{
return $this->morphMany(\App\Models\Document::class, 'documentable');
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace App\Models;
use App\Traits\Uuid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
class Document extends Model
{
use HasFactory;
use Uuid;
use SoftDeletes;
protected $fillable = [
'uuid',
'name',
'description',
'user_id',
'disk',
'path',
'file_name',
'original_name',
'extension',
'mime_type',
'size',
'checksum',
'is_public',
'preview_path',
'preview_mime',
'preview_generated_at',
];
protected $casts = [
'is_public' => 'boolean',
'size' => 'integer',
'preview_generated_at' => 'datetime',
];
protected $appends = [];
public function documentable(): MorphTo
{
return $this->morphTo();
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
// No direct public URL exposure; serve via controller stream
protected static function booted(): void
{
static::deleting(function (Document $doc) {
// Only delete files on force delete to keep data when soft-deleted
if (method_exists($doc, 'isForceDeleting') && $doc->isForceDeleting()) {
try {
if ($doc->path) {
$disk = $doc->disk ?: 'public';
Storage::disk($disk)->delete($doc->path);
}
} catch (\Throwable $e) {
// swallow; avoid failing delete due to storage issue
}
try {
if ($doc->preview_path) {
$previewDisk = config('files.preview_disk', 'public');
Storage::disk($previewDisk)->delete($doc->preview_path);
}
} catch (\Throwable $e) {
// swallow
}
}
});
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Email extends Model
{
protected $fillable = [
'person_id',
'value',
'label',
'is_primary',
'is_active',
'valid',
'verified_at',
'preferences',
'meta',
];
protected $casts = [
'is_primary' => 'boolean',
'is_active' => 'boolean',
'valid' => 'boolean',
'verified_at' => 'datetime',
'preferences' => 'array',
'meta' => 'array',
];
public function person(): BelongsTo
{
return $this->belongsTo(\App\Models\Person\Person::class, 'person_id');
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Import extends Model
{
use HasFactory;
protected $fillable = [
'uuid','user_id','import_template_id','client_id','source_type','file_name','original_name','disk','path','size','sheet_name','status','total_rows','valid_rows','invalid_rows','imported_rows','started_at','finished_at','failed_at','error_summary','meta'
];
protected $casts = [
'error_summary' => 'array',
'meta' => 'array',
'started_at' => 'datetime',
'finished_at' => 'datetime',
'failed_at' => 'datetime',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function template(): BelongsTo
{
return $this->belongsTo(ImportTemplate::class, 'import_template_id');
}
public function client(): BelongsTo
{
return $this->belongsTo(Client::class);
}
public function rows(): HasMany
{
return $this->hasMany(ImportRow::class);
}
public function events(): HasMany
{
return $this->hasMany(ImportEvent::class);
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ImportEvent extends Model
{
use HasFactory;
protected $fillable = [
'import_id','user_id','event','level','message','context','import_row_id'
];
protected $casts = [
'context' => 'array',
];
public function import(): BelongsTo
{
return $this->belongsTo(Import::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function row(): BelongsTo
{
return $this->belongsTo(ImportRow::class, 'import_row_id');
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ImportRow extends Model
{
use HasFactory;
protected $fillable = [
'import_id','row_number','sheet_name','record_type','raw_data','mapped_data','status','errors','warnings','entity_type','entity_id','fingerprint'
];
protected $casts = [
'raw_data' => 'array',
'mapped_data' => 'array',
'errors' => 'array',
'warnings' => 'array',
];
public function import(): BelongsTo
{
return $this->belongsTo(Import::class);
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class ImportTemplate extends Model
{
use HasFactory;
protected $fillable = [
'uuid', 'name', 'description', 'source_type', 'default_record_type', 'sample_headers', 'user_id', 'client_id', 'is_active', 'meta'
];
protected $casts = [
'sample_headers' => 'array',
'meta' => 'array',
'is_active' => 'boolean',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function client(): BelongsTo
{
return $this->belongsTo(Client::class);
}
public function mappings(): HasMany
{
return $this->hasMany(ImportTemplateMapping::class);
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ImportTemplateMapping extends Model
{
use HasFactory;
protected $fillable = [
'import_template_id', 'entity', 'source_column', 'target_field', 'transform', 'apply_mode', 'options', 'position'
];
protected $casts = [
'options' => 'array',
];
public function template(): BelongsTo
{
return $this->belongsTo(ImportTemplate::class, 'import_template_id');
}
}
+22
View File
@@ -3,6 +3,7 @@
namespace App\Models\Person;
use App\Traits\Uuid;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -52,6 +53,10 @@ protected static function booted(){
if(!isset($person->user_id)){
$person->user_id = auth()->id();
}
// Ensure a unique 6-character alphanumeric 'nu' is set globally on create
if (empty($person->nu)) {
$person->nu = static::generateUniqueNu();
}
});
}
@@ -88,6 +93,13 @@ public function addresses(): HasMany
->orderBy('id');
}
public function emails(): HasMany
{
return $this->hasMany(\App\Models\Email::class, 'person_id')
->where('is_active', '=', 1)
->orderBy('id');
}
public function group(): BelongsTo
{
return $this->belongsTo(\App\Models\Person\PersonGroup::class, 'group_id');
@@ -108,4 +120,14 @@ public function clientCase(): HasOne
return $this->hasOne(\App\Models\ClientCase::class);
}
/**
* Generate a unique 6-character alphanumeric identifier for 'nu'.
*/
protected static function generateUniqueNu(): string
{
do {
$nu = Str::random(6); // [A-Za-z0-9]
} while (static::where('nu', $nu)->exists());
return $nu;
}
}