222 lines
5.5 KiB
PHP
222 lines
5.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Models\Qualitys;
|
||
|
|
|
||
|
|
use App\Models\Items\Item;
|
||
|
|
use App\Models\Scopes\BelongsToTenant;
|
||
|
|
use App\Models\Tenants\User;
|
||
|
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||
|
|
use Illuminate\Database\Eloquent\Model;
|
||
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 통합 검사 모델 (IQC/PQC/FQC)
|
||
|
|
*
|
||
|
|
* @property int $id
|
||
|
|
* @property int $tenant_id
|
||
|
|
* @property string $inspection_no 검사번호
|
||
|
|
* @property string $inspection_type 검사유형 (IQC, PQC, FQC)
|
||
|
|
* @property string $status 상태 (waiting, in_progress, completed)
|
||
|
|
* @property string|null $result 판정결과 (pass, fail)
|
||
|
|
* @property string $request_date 검사요청일
|
||
|
|
* @property string|null $inspection_date 검사일
|
||
|
|
* @property int|null $item_id 품목 ID
|
||
|
|
* @property string $lot_no LOT번호
|
||
|
|
* @property int|null $inspector_id 검사자 ID
|
||
|
|
* @property array|null $meta 메타정보 (process_name, quantity, unit 등)
|
||
|
|
* @property array|null $items 검사항목 배열
|
||
|
|
* @property array|null $attachments 첨부파일 배열
|
||
|
|
* @property array|null $extra 추가정보 (remarks, opinion 등)
|
||
|
|
*
|
||
|
|
* @mixin IdeHelperInspection
|
||
|
|
*/
|
||
|
|
class Inspection extends Model
|
||
|
|
{
|
||
|
|
use SoftDeletes;
|
||
|
|
|
||
|
|
protected $table = 'inspections';
|
||
|
|
|
||
|
|
protected $fillable = [
|
||
|
|
'tenant_id',
|
||
|
|
'inspection_no',
|
||
|
|
'inspection_type',
|
||
|
|
'status',
|
||
|
|
'result',
|
||
|
|
'request_date',
|
||
|
|
'inspection_date',
|
||
|
|
'item_id',
|
||
|
|
'lot_no',
|
||
|
|
'inspector_id',
|
||
|
|
'meta',
|
||
|
|
'items',
|
||
|
|
'attachments',
|
||
|
|
'extra',
|
||
|
|
'created_by',
|
||
|
|
'updated_by',
|
||
|
|
];
|
||
|
|
|
||
|
|
protected $casts = [
|
||
|
|
'meta' => 'array',
|
||
|
|
'items' => 'array',
|
||
|
|
'attachments' => 'array',
|
||
|
|
'extra' => 'array',
|
||
|
|
'request_date' => 'date',
|
||
|
|
'inspection_date' => 'date',
|
||
|
|
];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 검사 유형 상수
|
||
|
|
*/
|
||
|
|
public const TYPE_IQC = 'IQC'; // 수입검사 (Incoming Quality Control)
|
||
|
|
|
||
|
|
public const TYPE_PQC = 'PQC'; // 공정검사 (Process Quality Control)
|
||
|
|
|
||
|
|
public const TYPE_FQC = 'FQC'; // 최종검사 (Final Quality Control)
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 상태 상수
|
||
|
|
*/
|
||
|
|
public const STATUS_WAITING = 'waiting';
|
||
|
|
|
||
|
|
public const STATUS_IN_PROGRESS = 'in_progress';
|
||
|
|
|
||
|
|
public const STATUS_COMPLETED = 'completed';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 판정결과 상수
|
||
|
|
*/
|
||
|
|
public const RESULT_PASS = 'pass';
|
||
|
|
|
||
|
|
public const RESULT_FAIL = 'fail';
|
||
|
|
|
||
|
|
protected static function booted(): void
|
||
|
|
{
|
||
|
|
static::addGlobalScope(new BelongsToTenant);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== Relationships =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 품목
|
||
|
|
*/
|
||
|
|
public function item()
|
||
|
|
{
|
||
|
|
return $this->belongsTo(Item::class, 'item_id');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 검사자
|
||
|
|
*/
|
||
|
|
public function inspector()
|
||
|
|
{
|
||
|
|
return $this->belongsTo(User::class, 'inspector_id');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 생성자
|
||
|
|
*/
|
||
|
|
public function creator()
|
||
|
|
{
|
||
|
|
return $this->belongsTo(User::class, 'created_by');
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== Accessors (meta JSON 필드) =====
|
||
|
|
|
||
|
|
protected function processName(): Attribute
|
||
|
|
{
|
||
|
|
return Attribute::make(
|
||
|
|
get: fn () => $this->meta['process_name'] ?? null,
|
||
|
|
set: fn ($value) => $this->setMetaValue('process_name', $value),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function quantity(): Attribute
|
||
|
|
{
|
||
|
|
return Attribute::make(
|
||
|
|
get: fn () => $this->meta['quantity'] ?? null,
|
||
|
|
set: fn ($value) => $this->setMetaValue('quantity', $value),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function unit(): Attribute
|
||
|
|
{
|
||
|
|
return Attribute::make(
|
||
|
|
get: fn () => $this->meta['unit'] ?? null,
|
||
|
|
set: fn ($value) => $this->setMetaValue('unit', $value),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== Accessors (extra JSON 필드) =====
|
||
|
|
|
||
|
|
protected function remarks(): Attribute
|
||
|
|
{
|
||
|
|
return Attribute::make(
|
||
|
|
get: fn () => $this->extra['remarks'] ?? null,
|
||
|
|
set: fn ($value) => $this->setExtraValue('remarks', $value),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function opinion(): Attribute
|
||
|
|
{
|
||
|
|
return Attribute::make(
|
||
|
|
get: fn () => $this->extra['opinion'] ?? null,
|
||
|
|
set: fn ($value) => $this->setExtraValue('opinion', $value),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== Helper Methods =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* meta JSON 필드에 값 설정
|
||
|
|
*/
|
||
|
|
protected function setMetaValue(string $key, $value): array
|
||
|
|
{
|
||
|
|
$meta = $this->meta ?? [];
|
||
|
|
$meta[$key] = $value;
|
||
|
|
$this->attributes['meta'] = json_encode($meta);
|
||
|
|
|
||
|
|
return $meta;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* extra JSON 필드에 값 설정
|
||
|
|
*/
|
||
|
|
protected function setExtraValue(string $key, $value): array
|
||
|
|
{
|
||
|
|
$extra = $this->extra ?? [];
|
||
|
|
$extra[$key] = $value;
|
||
|
|
$this->attributes['extra'] = json_encode($extra);
|
||
|
|
|
||
|
|
return $extra;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 검사번호 자동 생성
|
||
|
|
*/
|
||
|
|
public static function generateInspectionNo(int $tenantId, string $type): string
|
||
|
|
{
|
||
|
|
$prefix = match ($type) {
|
||
|
|
self::TYPE_IQC => 'IQC',
|
||
|
|
self::TYPE_PQC => 'PQC',
|
||
|
|
self::TYPE_FQC => 'FQC',
|
||
|
|
default => 'INS',
|
||
|
|
};
|
||
|
|
|
||
|
|
$date = now()->format('Ymd');
|
||
|
|
|
||
|
|
$lastNo = static::withoutGlobalScopes()
|
||
|
|
->where('tenant_id', $tenantId)
|
||
|
|
->where('inspection_no', 'like', "{$prefix}-{$date}-%")
|
||
|
|
->orderByDesc('inspection_no')
|
||
|
|
->value('inspection_no');
|
||
|
|
|
||
|
|
if ($lastNo) {
|
||
|
|
$seq = (int) substr($lastNo, -4) + 1;
|
||
|
|
} else {
|
||
|
|
$seq = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
return sprintf('%s-%s-%04d', $prefix, $date, $seq);
|
||
|
|
}
|
||
|
|
}
|