Files
autocrm/app/Models/Tenant/InjectorProtocol.php
Vasyka 6de9c615f7 fix(injector-protocols): derive protocol prefix from tenant slug (not hardcoded PS)
'PS' was baked in — wrong for multi-tenant. Now:
  1. Honor $tenant->settings['protocol_prefix'] if set
  2. Else use uppercase first 2 chars of tenant slug
     ('psauto' → 'PS', 'autoplus' → 'AP', 'plusrepair' → 'PL')
  3. Fallback 'PR' if no tenant resolvable

Format changed from 'PS-{companyId}-{year}-{seq}' to '{PREFIX}-{year}-{seq}'
— dropped the redundant companyId since prefix already identifies the
tenant contextually.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-26 11:52:14 +00:00

131 lines
4.0 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Models\Tenant;
use App\Models\Concerns\BelongsToTenant;
use App\Tenancy\TenantManager;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class InjectorProtocol extends Model
{
use BelongsToTenant;
public const SOURCE_TYPES = [
'client' => 'Клиент',
'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 23 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';
}
}