'Клиент', 'service_partner' => 'Автосервис', ]; protected $fillable = [ 'company_id', 'protocol_number', 'client_id', 'vehicle_id', 'work_order_id', 'source_type', 'source_name', 'phone', 'car_model', 'plate_number', 'vin', 'mileage', 'year', 'injector_brand', 'injector_count', 'reason_new_injectors', 'reason_engine_overhaul', 'reason_check', 'conclusion_ok', 'conclusion_needs_cleaning', 'conclusion_needs_replacement', 'master_comment', 'master_id', 'master_name_signed', 'issue_date', 'client_acknowledged', ]; protected $casts = [ 'reason_new_injectors' => 'boolean', 'reason_engine_overhaul' => 'boolean', 'reason_check' => 'boolean', 'conclusion_ok' => 'boolean', 'conclusion_needs_cleaning' => 'boolean', 'conclusion_needs_replacement' => 'boolean', 'client_acknowledged' => 'boolean', 'issue_date' => 'date', 'mileage' => 'integer', 'year' => 'integer', 'injector_count' => 'integer', ]; public function client(): BelongsTo { return $this->belongsTo(Client::class); } public function vehicle(): BelongsTo { return $this->belongsTo(Vehicle::class); } public function workOrder(): BelongsTo { return $this->belongsTo(WorkOrder::class); } public function master(): BelongsTo { return $this->belongsTo(User::class, 'master_id'); } public function rows(): HasMany { return $this->hasMany(InjectorProtocolRow::class)->orderBy('position'); } protected static function booted(): void { static::creating(function (InjectorProtocol $p) { $p->protocol_number ??= static::generateNumber(); }); static::created(function (InjectorProtocol $p) { // Auto-seed empty rows for each injector position (1..N) $count = max(1, min(8, (int) $p->injector_count)); for ($i = 1; $i <= $count; $i++) { $p->rows()->create([ 'company_id' => $p->company_id, 'position' => $i, ]); } }); } /** * {PREFIX}-{YYYY}-{seq6} — per-tenant, per-year sequence. * * PREFIX is derived from the tenant (settings.protocol_prefix override, * else uppercase of the first 2–3 letters of the tenant slug — * 'psauto' → 'PS', 'autoplus' → 'AP', etc.). Falls back to 'PR' when * no tenant is resolvable. */ public static function generateNumber(): string { $tenant = app(TenantManager::class)->current(); $companyId = $tenant?->id ?? auth()->user()?->company_id ?? 0; $year = now()->year; $seq = static::withoutGlobalScopes() ->where('company_id', $companyId) ->whereYear('created_at', $year) ->count() + 1; $prefix = self::resolvePrefix($tenant); return sprintf('%s-%d-%06d', $prefix, $year, $seq); } /** Explicit tenant setting → slug initials → 'PR' fallback. */ protected static function resolvePrefix($tenant): string { if ($tenant) { $explicit = trim((string) data_get($tenant->settings ?? [], 'protocol_prefix')); if ($explicit !== '') { return mb_strtoupper($explicit); } $slug = (string) ($tenant->slug ?? ''); if ($slug !== '') { // Take first 2 characters of the slug — 'psauto' → 'PS' return mb_strtoupper(mb_substr($slug, 0, 2)); } } return 'PR'; } }