04cab25ac5
When a category is saved with a sort_order already occupied by another record in the same company, all records at that position and above are incremented by 1 before the save, inserting the new one cleanly at the requested position. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
63 lines
2.0 KiB
PHP
63 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Tenant;
|
|
|
|
use App\Models\Concerns\BelongsToTenant;
|
|
use App\Models\Scopes\TenantScope;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
class LaborCategory extends Model
|
|
{
|
|
use BelongsToTenant;
|
|
|
|
protected $fillable = ['company_id', 'name', 'name_ro', 'name_ru', 'name_en', 'sort_order'];
|
|
|
|
protected static function boot(): void
|
|
{
|
|
parent::boot();
|
|
|
|
// When sort_order is changed to a value already occupied by another record,
|
|
// shift all records at that position and above up by 1 to make room.
|
|
static::saving(function (self $cat) {
|
|
$new = (int) $cat->sort_order;
|
|
$old = (int) ($cat->getOriginal('sort_order') ?? PHP_INT_MAX);
|
|
|
|
if ($new === $old) return;
|
|
|
|
$conflict = static::withoutGlobalScope(TenantScope::class)
|
|
->where('company_id', $cat->company_id)
|
|
->where('sort_order', $new)
|
|
->where('id', '!=', $cat->id ?? 0)
|
|
->exists();
|
|
|
|
if ($conflict) {
|
|
static::withoutGlobalScope(TenantScope::class)
|
|
->where('company_id', $cat->company_id)
|
|
->where('sort_order', '>=', $new)
|
|
->where('id', '!=', $cat->id ?? 0)
|
|
->increment('sort_order');
|
|
}
|
|
});
|
|
}
|
|
|
|
protected $casts = ['sort_order' => 'integer'];
|
|
|
|
/** Localized display label — falls back through ru→en→name_ro→name. */
|
|
public function label(?string $locale = null): string
|
|
{
|
|
$locale = $locale ?: app()->getLocale();
|
|
return $this->{"name_{$locale}"}
|
|
?: $this->name_ro
|
|
?: $this->name
|
|
?: '';
|
|
}
|
|
|
|
/** Options array keyed by canonical name (stored in labors.category). */
|
|
public static function optionsForSelect(): array
|
|
{
|
|
return static::orderBy('sort_order')->orderBy('name')->get()
|
|
->mapWithKeys(fn ($c) => [$c->name => $c->label()])
|
|
->toArray();
|
|
}
|
|
}
|