- 품질관리서(quality_documents) CRUD API 14개 엔드포인트 - 실적신고(performance_reports) 관리 API 6개 엔드포인트 - DB 마이그레이션 4개 테이블 (quality_documents, quality_document_orders, quality_document_locations, performance_reports) - 모델 4개 + 서비스 2개 + 컨트롤러 2개 + FormRequest 4개 - stats() ambiguous column 버그 수정 (JOIN 시 테이블 접두사 추가) - missing() status_code 컬럼명/값 수정 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
132 lines
3.0 KiB
PHP
132 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Qualitys;
|
|
|
|
use App\Models\Members\User;
|
|
use App\Models\Orders\Client;
|
|
use App\Traits\Auditable;
|
|
use App\Traits\BelongsToTenant;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
|
|
class QualityDocument extends Model
|
|
{
|
|
use Auditable, BelongsToTenant, SoftDeletes;
|
|
|
|
protected $table = 'quality_documents';
|
|
|
|
const STATUS_RECEIVED = 'received';
|
|
|
|
const STATUS_IN_PROGRESS = 'in_progress';
|
|
|
|
const STATUS_COMPLETED = 'completed';
|
|
|
|
protected $fillable = [
|
|
'tenant_id',
|
|
'quality_doc_number',
|
|
'site_name',
|
|
'status',
|
|
'client_id',
|
|
'inspector_id',
|
|
'received_date',
|
|
'options',
|
|
'created_by',
|
|
'updated_by',
|
|
'deleted_by',
|
|
];
|
|
|
|
protected $casts = [
|
|
'options' => 'array',
|
|
'received_date' => 'date',
|
|
];
|
|
|
|
// ===== Relationships =====
|
|
|
|
public function client()
|
|
{
|
|
return $this->belongsTo(Client::class, 'client_id');
|
|
}
|
|
|
|
public function inspector()
|
|
{
|
|
return $this->belongsTo(User::class, 'inspector_id');
|
|
}
|
|
|
|
public function creator()
|
|
{
|
|
return $this->belongsTo(User::class, 'created_by');
|
|
}
|
|
|
|
public function documentOrders()
|
|
{
|
|
return $this->hasMany(QualityDocumentOrder::class);
|
|
}
|
|
|
|
public function locations()
|
|
{
|
|
return $this->hasMany(QualityDocumentLocation::class);
|
|
}
|
|
|
|
public function performanceReport()
|
|
{
|
|
return $this->hasOne(PerformanceReport::class);
|
|
}
|
|
|
|
// ===== 채번 =====
|
|
|
|
public static function generateDocNumber(int $tenantId): string
|
|
{
|
|
$prefix = 'KD-QD';
|
|
$yearMonth = now()->format('Ym');
|
|
|
|
$lastNo = static::withoutGlobalScopes()
|
|
->where('tenant_id', $tenantId)
|
|
->where('quality_doc_number', 'like', "{$prefix}-{$yearMonth}-%")
|
|
->orderByDesc('quality_doc_number')
|
|
->value('quality_doc_number');
|
|
|
|
if ($lastNo) {
|
|
$seq = (int) substr($lastNo, -4) + 1;
|
|
} else {
|
|
$seq = 1;
|
|
}
|
|
|
|
return sprintf('%s-%s-%04d', $prefix, $yearMonth, $seq);
|
|
}
|
|
|
|
// ===== Status Helpers =====
|
|
|
|
public function isReceived(): bool
|
|
{
|
|
return $this->status === self::STATUS_RECEIVED;
|
|
}
|
|
|
|
public function isInProgress(): bool
|
|
{
|
|
return $this->status === self::STATUS_IN_PROGRESS;
|
|
}
|
|
|
|
public function isCompleted(): bool
|
|
{
|
|
return $this->status === self::STATUS_COMPLETED;
|
|
}
|
|
|
|
public static function mapStatusToFrontend(string $status): string
|
|
{
|
|
return match ($status) {
|
|
self::STATUS_RECEIVED => 'reception',
|
|
self::STATUS_IN_PROGRESS => 'in_progress',
|
|
self::STATUS_COMPLETED => 'completed',
|
|
default => $status,
|
|
};
|
|
}
|
|
|
|
public static function mapStatusFromFrontend(string $status): string
|
|
{
|
|
return match ($status) {
|
|
'reception' => self::STATUS_RECEIVED,
|
|
default => $status,
|
|
};
|
|
}
|
|
}
|