refactor:견적 converted 상태를 데이터 기반(order_id)으로 변경

- Quote 모델에 getStatusAttribute() accessor 추가: order_id 존재 시 자동으로 'converted' 반환
- scopeConverted() → whereNotNull('order_id') 변경
- QuoteService/OrderService에서 status='converted' 직접 세팅 제거, order_id만 세팅
- 상태 필터 쿼리: converted는 order_id IS NOT NULL 기반
- 통계 쿼리: status='converted' → order_id IS NOT NULL
- 수주 직접 등록 시에도 자동으로 수주전환 상태 반영

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 07:43:21 +09:00
parent a2dbdae14b
commit d7ca8cfa00
4 changed files with 31 additions and 14 deletions

View File

@@ -73,9 +73,11 @@ public function index(array $params): LengthAwarePaginator
$query->where('quote_type', $quoteType);
}
// 상태 필터
if ($status) {
$query->where('status', $status);
// 상태 필터 (converted는 order_id 기반으로 판별)
if ($status === Quote::STATUS_CONVERTED) {
$query->whereNotNull('order_id');
} elseif ($status) {
$query->where('status', $status)->whereNull('order_id');
}
// 제품 카테고리 필터
@@ -592,12 +594,12 @@ public function cancelFinalize(int $id): Quote
throw new NotFoundHttpException(__('error.quote_not_found'));
}
if ($quote->status !== Quote::STATUS_FINALIZED) {
throw new BadRequestHttpException(__('error.quote_not_finalized'));
if ($quote->order_id) {
throw new BadRequestHttpException(__('error.quote_already_converted'));
}
if ($quote->status === Quote::STATUS_CONVERTED) {
throw new BadRequestHttpException(__('error.quote_already_converted'));
if ($quote->getRawOriginal('status') !== Quote::STATUS_FINALIZED) {
throw new BadRequestHttpException(__('error.quote_not_finalized'));
}
$quote->update([
@@ -705,9 +707,8 @@ public function convertToOrder(int $id): Quote
$order->recalculateTotals();
$order->save();
// 견적 상태 변경
// 견적에 수주 연결 (status는 accessor가 자동으로 'converted' 반환)
$quote->update([
'status' => Quote::STATUS_CONVERTED,
'order_id' => $order->id,
'updated_by' => $userId,
]);