feat: 작업지시 목록에 assigned_to_me 필터 추가
- 작업자 화면에서 나에게 배정된 작업만 조회하도록 지원 - 주 담당자(assignee_id) 또는 공동 담당자(assignees) 모두 포함 - 프론트엔드 WorkerScreen의 assigned_to_me=1 파라미터 처리 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ public function index(array $params)
|
|||||||
$status = $params['status'] ?? null;
|
$status = $params['status'] ?? null;
|
||||||
$processId = $params['process_id'] ?? null;
|
$processId = $params['process_id'] ?? null;
|
||||||
$assigneeId = $params['assignee_id'] ?? null;
|
$assigneeId = $params['assignee_id'] ?? null;
|
||||||
|
$assignedToMe = isset($params['assigned_to_me']) && $params['assigned_to_me'];
|
||||||
$teamId = $params['team_id'] ?? null;
|
$teamId = $params['team_id'] ?? null;
|
||||||
$scheduledFrom = $params['scheduled_from'] ?? null;
|
$scheduledFrom = $params['scheduled_from'] ?? null;
|
||||||
$scheduledTo = $params['scheduled_to'] ?? null;
|
$scheduledTo = $params['scheduled_to'] ?? null;
|
||||||
@@ -63,6 +64,15 @@ public function index(array $params)
|
|||||||
$query->where('assignee_id', $assigneeId);
|
$query->where('assignee_id', $assigneeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 나에게 배정된 작업만 필터 (주 담당자 또는 공동 담당자)
|
||||||
|
if ($assignedToMe) {
|
||||||
|
$userId = $this->apiUserId();
|
||||||
|
$query->where(function ($q) use ($userId) {
|
||||||
|
$q->where('assignee_id', $userId)
|
||||||
|
->orWhereHas('assignees', fn ($aq) => $aq->where('user_id', $userId));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 팀 필터
|
// 팀 필터
|
||||||
if ($teamId !== null) {
|
if ($teamId !== null) {
|
||||||
$query->where('team_id', $teamId);
|
$query->where('team_id', $teamId);
|
||||||
@@ -329,8 +339,12 @@ public function destroy(int $id)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 상태 변경
|
* 상태 변경
|
||||||
|
*
|
||||||
|
* @param int $id 작업지시 ID
|
||||||
|
* @param string $status 변경할 상태
|
||||||
|
* @param array|null $resultData 완료 시 결과 데이터 (선택)
|
||||||
*/
|
*/
|
||||||
public function updateStatus(int $id, string $status)
|
public function updateStatus(int $id, string $status, ?array $resultData = null)
|
||||||
{
|
{
|
||||||
$tenantId = $this->tenantId();
|
$tenantId = $this->tenantId();
|
||||||
$userId = $this->apiUserId();
|
$userId = $this->apiUserId();
|
||||||
@@ -357,36 +371,106 @@ public function updateStatus(int $id, string $status)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oldStatus = $workOrder->status;
|
return DB::transaction(function () use ($workOrder, $status, $resultData, $tenantId, $userId) {
|
||||||
$workOrder->status = $status;
|
$oldStatus = $workOrder->status;
|
||||||
$workOrder->updated_by = $userId;
|
$workOrder->status = $status;
|
||||||
|
$workOrder->updated_by = $userId;
|
||||||
|
|
||||||
// 상태에 따른 타임스탬프 업데이트
|
// 상태에 따른 타임스탬프 업데이트
|
||||||
switch ($status) {
|
switch ($status) {
|
||||||
case WorkOrder::STATUS_IN_PROGRESS:
|
case WorkOrder::STATUS_IN_PROGRESS:
|
||||||
$workOrder->started_at = $workOrder->started_at ?? now();
|
$workOrder->started_at = $workOrder->started_at ?? now();
|
||||||
break;
|
break;
|
||||||
case WorkOrder::STATUS_COMPLETED:
|
case WorkOrder::STATUS_COMPLETED:
|
||||||
$workOrder->completed_at = now();
|
$workOrder->completed_at = now();
|
||||||
break;
|
// 모든 품목에 결과 데이터 저장
|
||||||
case WorkOrder::STATUS_SHIPPED:
|
$this->saveItemResults($workOrder, $resultData, $userId);
|
||||||
$workOrder->shipped_at = now();
|
break;
|
||||||
break;
|
case WorkOrder::STATUS_SHIPPED:
|
||||||
|
$workOrder->shipped_at = now();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$workOrder->save();
|
||||||
|
|
||||||
|
// 상태 변경 감사 로그
|
||||||
|
$this->auditLogger->log(
|
||||||
|
$tenantId,
|
||||||
|
self::AUDIT_TARGET,
|
||||||
|
$workOrder->id,
|
||||||
|
'status_changed',
|
||||||
|
['status' => $oldStatus],
|
||||||
|
['status' => $status]
|
||||||
|
);
|
||||||
|
|
||||||
|
return $workOrder->load(['assignee:id,name', 'assignees.user:id,name', 'team:id,name', 'process:id,process_name,process_code']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 작업지시 품목에 결과 데이터 저장
|
||||||
|
*/
|
||||||
|
private function saveItemResults(WorkOrder $workOrder, ?array $resultData, int $userId): void
|
||||||
|
{
|
||||||
|
$items = $workOrder->items;
|
||||||
|
$lotNo = $this->generateLotNo($workOrder);
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$itemResult = [
|
||||||
|
'completed_at' => now()->toDateTimeString(),
|
||||||
|
'good_qty' => $item->quantity, // 기본값: 지시수량 전체가 양품
|
||||||
|
'defect_qty' => 0,
|
||||||
|
'defect_rate' => 0,
|
||||||
|
'lot_no' => $lotNo,
|
||||||
|
'is_inspected' => false,
|
||||||
|
'is_packaged' => false,
|
||||||
|
'worker_id' => $userId,
|
||||||
|
'memo' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
// 개별 품목 결과 데이터가 있으면 병합
|
||||||
|
if ($resultData && isset($resultData['items'][$item->id])) {
|
||||||
|
$itemResult = array_merge($itemResult, $resultData['items'][$item->id]);
|
||||||
|
// 불량률 재계산
|
||||||
|
$totalQty = ($itemResult['good_qty'] ?? 0) + ($itemResult['defect_qty'] ?? 0);
|
||||||
|
$itemResult['defect_rate'] = $totalQty > 0
|
||||||
|
? round(($itemResult['defect_qty'] / $totalQty) * 100, 2)
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 품목 상태도 완료로 변경
|
||||||
|
$item->status = WorkOrderItem::STATUS_COMPLETED;
|
||||||
|
$options = $item->options ?? [];
|
||||||
|
$options['result'] = $itemResult;
|
||||||
|
$item->options = $options;
|
||||||
|
$item->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LOT 번호 생성
|
||||||
|
*/
|
||||||
|
private function generateLotNo(WorkOrder $workOrder): string
|
||||||
|
{
|
||||||
|
$date = now()->format('ymd');
|
||||||
|
$prefix = 'KD-SA';
|
||||||
|
|
||||||
|
// 오늘 날짜의 마지막 LOT 번호 조회
|
||||||
|
$lastLotNo = WorkOrderItem::where('tenant_id', $workOrder->tenant_id)
|
||||||
|
->whereNotNull('options->result->lot_no')
|
||||||
|
->where('options->result->lot_no', 'like', "{$prefix}-{$date}-%")
|
||||||
|
->orderByDesc('id')
|
||||||
|
->value('options->result->lot_no');
|
||||||
|
|
||||||
|
if ($lastLotNo) {
|
||||||
|
// 마지막 번호에서 시퀀스 추출 후 증가
|
||||||
|
$parts = explode('-', $lastLotNo);
|
||||||
|
$seq = (int) end($parts) + 1;
|
||||||
|
} else {
|
||||||
|
$seq = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$workOrder->save();
|
return sprintf('%s-%s-%02d', $prefix, $date, $seq);
|
||||||
|
|
||||||
// 상태 변경 감사 로그
|
|
||||||
$this->auditLogger->log(
|
|
||||||
$tenantId,
|
|
||||||
self::AUDIT_TARGET,
|
|
||||||
$workOrder->id,
|
|
||||||
'status_changed',
|
|
||||||
['status' => $oldStatus],
|
|
||||||
['status' => $status]
|
|
||||||
);
|
|
||||||
|
|
||||||
return $workOrder->load(['assignee:id,name', 'assignees.user:id,name', 'team:id,name', 'process:id,process_name,process_code']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user