diff --git a/.cursor/skills/abshode-domain-lookup/learned-notes.md b/.cursor/skills/abshode-domain-lookup/learned-notes.md index 36a2d8c..5e21d42 100644 --- a/.cursor/skills/abshode-domain-lookup/learned-notes.md +++ b/.cursor/skills/abshode-domain-lookup/learned-notes.md @@ -3,6 +3,7 @@ فرمت هر خط: - YYYY-MM-DD | موضوع | مسیر فایل(ها) | نکتهٔ ۱ خطی +- 2026-11-05 | کد کاربری مشتری بعدی | `Customer::nextSequentialId` در `creating` | کد کاربری=`customers.id`؛ بعد از UPDATE دستی id، AUTO_INCREMENT پایین نمی‌آید (۵۵۱ به‌جای ۲۴). ایجاد مشتری = اولین id خالی، نه شمارندهٔ InnoDB - 2026-11-04 | فرمت کد تفصیلی شایگان | `ShayeganSyncService::customerTafsilNumber` | کل `shayegan_kol_customer` (121) + کد کاربر ۷رقمی: مشتری 1 → `1210000001`. کد ذخیره‌شدهٔ قبلی عوض نمی‌شود - 2026-11-02 | جدول اسناد شایگان | `shayeganTable.vue` + `ShayeganController::table` | BaseTable؛ پاسخ بدون `query` را خود فرانت به `{rows,query}` برمی‌گرداند. ستون عملیات `ops` است تا در RTL هشدار fixed ندهد - 2026-11-02 | ویرایش کد حسابداری شایگان | `CustomerAccountingCodeModal.vue` | provider شایگان هم `moshtari_code` ذخیره می‌کند؛ قبلاً فقط پرگار/ته‌حساب/زرین قبول می‌شد و پیام «حسابداری فعال نیست» می‌آمد diff --git a/app/Models/Customer.php b/app/Models/Customer.php index 321dcee..e42f2c5 100644 --- a/app/Models/Customer.php +++ b/app/Models/Customer.php @@ -5,6 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Carbon\Carbon; use Rooyesh\Wallet\models\Wallet; @@ -200,6 +201,16 @@ class Customer extends Authenticatable implements JWTSubject protected static function booted(): void { + // کد کاربری = customers.id. AUTO_INCREMENT بعد از UPDATE دستی id پایین نمی‌آید + // (مثلاً ۱..۲۳ اصلاح شد ولی شمارنده روی ۵۵۱ ماند). همیشه اولین id خالی. + static::creating(function (self $customer) { + if (! empty($customer->id)) { + return; + } + $customer->id = self::nextSequentialId(); + $customer->incrementing = false; + }); + static::saving(function (self $customer) { $mobile = self::normalizeMobile($customer->mobile); if ($mobile === null) { @@ -211,6 +222,22 @@ class Customer extends Authenticatable implements JWTSubject }); } + /** کوچک‌ترین id آزاد، شامل ردیف‌های soft-deleted تا PK تکراری نشود. */ + public static function nextSequentialId(): int + { + $table = (new static)->getTable(); + $row = DB::selectOne( + "SELECT t.id + 1 AS next_id + FROM (SELECT 0 AS id UNION ALL SELECT id FROM `{$table}`) t + LEFT JOIN `{$table}` c ON c.id = t.id + 1 + WHERE c.id IS NULL + ORDER BY t.id + LIMIT 1" + ); + + return max(1, (int) ($row->next_id ?? 1)); + } + public static function normalizeMobile(?string $mobile): ?string { $digits = preg_replace('/\D+/', '', trim((string) $mobile));