From 04cab25ac57d05540afe87bb8ebd97be1b427d06 Mon Sep 17 00:00:00 2001 From: Vasyka Date: Tue, 8 Sep 2026 06:45:50 +0000 Subject: [PATCH] Shift labor category sort_order on conflict when saving 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 --- app/Models/Tenant/LaborCategory.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/app/Models/Tenant/LaborCategory.php b/app/Models/Tenant/LaborCategory.php index 953af4b..e9d9324 100644 --- a/app/Models/Tenant/LaborCategory.php +++ b/app/Models/Tenant/LaborCategory.php @@ -3,6 +3,7 @@ namespace App\Models\Tenant; use App\Models\Concerns\BelongsToTenant; +use App\Models\Scopes\TenantScope; use Illuminate\Database\Eloquent\Model; class LaborCategory extends Model @@ -11,6 +12,34 @@ class LaborCategory extends Model 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. */