feat: [quality] 검사 상태 자동 재계산 + 수주처 선택 연동
- 개소별 inspection_status를 검사 데이터 내용 기반으로 자동 판정 (15개 판정필드 + 사진 유무 → pending/in_progress/completed) - 문서 status를 개소 상태 집계로 자동 재계산 - inspectLocation, updateLocations 모두 적용 - QualityDocumentLocation에 STATUS_IN_PROGRESS 상수 추가 - transformToFrontend에 client_id 매핑 추가
This commit is contained in:
@@ -12,6 +12,8 @@ class QualityDocumentLocation extends Model
|
||||
|
||||
const STATUS_PENDING = 'pending';
|
||||
|
||||
const STATUS_IN_PROGRESS = 'in_progress';
|
||||
|
||||
const STATUS_COMPLETED = 'completed';
|
||||
|
||||
protected $fillable = [
|
||||
|
||||
@@ -257,6 +257,9 @@ public function update(int $id, array $data)
|
||||
$this->updateLocations($doc->id, $locations);
|
||||
}
|
||||
|
||||
// 개소 상태 기반 문서 상태 재계산
|
||||
$this->recalculateDocumentStatus($doc);
|
||||
|
||||
$this->auditLogger->log(
|
||||
$doc->tenant_id,
|
||||
self::AUDIT_TARGET,
|
||||
@@ -476,9 +479,87 @@ private function updateLocations(int $docId, array $locations): void
|
||||
if (! empty($updateData)) {
|
||||
$location->update($updateData);
|
||||
}
|
||||
|
||||
// 검사 데이터 내용 기반 inspection_status 재계산
|
||||
$location->refresh();
|
||||
$newStatus = $this->determineLocationStatus($location->inspection_data);
|
||||
|
||||
if ($location->inspection_status !== $newStatus) {
|
||||
$location->update(['inspection_status' => $newStatus]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 개소 상태 기반 문서 상태 재계산
|
||||
*/
|
||||
private function recalculateDocumentStatus(QualityDocument $doc): void
|
||||
{
|
||||
$doc->load('locations');
|
||||
$total = $doc->locations->count();
|
||||
|
||||
if ($total === 0) {
|
||||
$doc->update(['status' => QualityDocument::STATUS_RECEIVED]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$completedCount = $doc->locations
|
||||
->where('inspection_status', QualityDocumentLocation::STATUS_COMPLETED)
|
||||
->count();
|
||||
$inProgressCount = $doc->locations
|
||||
->where('inspection_status', QualityDocumentLocation::STATUS_IN_PROGRESS)
|
||||
->count();
|
||||
|
||||
if ($completedCount === $total) {
|
||||
$doc->update(['status' => QualityDocument::STATUS_COMPLETED]);
|
||||
} elseif ($completedCount > 0 || $inProgressCount > 0) {
|
||||
$doc->update(['status' => QualityDocument::STATUS_IN_PROGRESS]);
|
||||
} else {
|
||||
$doc->update(['status' => QualityDocument::STATUS_RECEIVED]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 검사 데이터 내용 기반 개소 상태 판정
|
||||
*
|
||||
* - 데이터 없음 or 검사항목 0개+사진 없음 → pending
|
||||
* - 검사항목 일부 or 사진 없음 → in_progress
|
||||
* - 15개 검사항목 전부 + 사진 있음 → completed
|
||||
*/
|
||||
private function determineLocationStatus(?array $inspectionData): string
|
||||
{
|
||||
if (empty($inspectionData)) {
|
||||
return QualityDocumentLocation::STATUS_PENDING;
|
||||
}
|
||||
|
||||
$judgmentFields = [
|
||||
'appearanceProcessing', 'appearanceSewing', 'appearanceAssembly',
|
||||
'appearanceSmokeBarrier', 'appearanceBottomFinish', 'motor', 'material',
|
||||
'lengthJudgment', 'heightJudgment', 'guideRailGap', 'bottomFinishGap',
|
||||
'fireResistanceTest', 'smokeLeakageTest', 'openCloseTest', 'impactTest',
|
||||
];
|
||||
|
||||
$inspected = 0;
|
||||
foreach ($judgmentFields as $field) {
|
||||
if (isset($inspectionData[$field]) && $inspectionData[$field] !== null && $inspectionData[$field] !== '') {
|
||||
$inspected++;
|
||||
}
|
||||
}
|
||||
|
||||
$hasPhotos = ! empty($inspectionData['productImages']) && is_array($inspectionData['productImages']) && count($inspectionData['productImages']) > 0;
|
||||
|
||||
if ($inspected === 0 && ! $hasPhotos) {
|
||||
return QualityDocumentLocation::STATUS_PENDING;
|
||||
}
|
||||
|
||||
if ($inspected < count($judgmentFields) || ! $hasPhotos) {
|
||||
return QualityDocumentLocation::STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
return QualityDocumentLocation::STATUS_COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수주 동기화 (update 시 사용)
|
||||
*/
|
||||
@@ -668,6 +749,7 @@ private function transformToFrontend(QualityDocument $doc, bool $detail = false)
|
||||
'id' => $doc->id,
|
||||
'quality_doc_number' => $doc->quality_doc_number,
|
||||
'site_name' => $doc->site_name,
|
||||
'client_id' => $doc->client_id,
|
||||
'client' => $doc->client?->name ?? '',
|
||||
'location_count' => $doc->locations?->count() ?? 0,
|
||||
'required_info' => $this->calculateRequiredInfo($doc),
|
||||
@@ -784,9 +866,6 @@ public function inspectLocation(int $docId, int $locId, array $data)
|
||||
if (isset($data['change_reason'])) {
|
||||
$updateData['change_reason'] = $data['change_reason'];
|
||||
}
|
||||
if (isset($data['inspection_status'])) {
|
||||
$updateData['inspection_status'] = $data['inspection_status'];
|
||||
}
|
||||
if (array_key_exists('inspection_data', $data)) {
|
||||
$updateData['inspection_data'] = $data['inspection_data'];
|
||||
}
|
||||
@@ -795,11 +874,16 @@ public function inspectLocation(int $docId, int $locId, array $data)
|
||||
$location->update($updateData);
|
||||
}
|
||||
|
||||
// 상태를 진행중으로 변경 (접수 상태일 때)
|
||||
if ($doc->isReceived()) {
|
||||
$doc->update(['status' => QualityDocument::STATUS_IN_PROGRESS]);
|
||||
// 검사 데이터 기반 개소 상태 자동 판정
|
||||
$location->refresh();
|
||||
$newLocStatus = $this->determineLocationStatus($location->inspection_data);
|
||||
if ($location->inspection_status !== $newLocStatus) {
|
||||
$location->update(['inspection_status' => $newLocStatus]);
|
||||
}
|
||||
|
||||
// 문서 상태 재계산
|
||||
$this->recalculateDocumentStatus($doc);
|
||||
|
||||
return $location->fresh()->toArray();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user