Files
sam-docs/dev/dev_plans/quote-order-sync-improvement-plan.md
권혁성 db63fcff85 refactor: [docs] 팀별 폴더 구조 재편 (공유/개발/프론트/기획)
- 개발팀 전용 폴더 dev/ 생성 (standards, guides, quickstart, changes, deploys, data, history, dev_plans 이동)
- 프론트엔드 전용 폴더 frontend/ 생성 (api/ → frontend/api-specs/)
- 기획팀 폴더 requests/ 생성
- plans/ → dev/dev_plans/ 이름 변경
- README.md 신규 (사람용 안내), INDEX.md 재작성 (Claude Code용)
- resources.md 신규 (노션 링크용, assets/brochure 이관 예정)
- CURRENT_WORKS.md 삭제, TODO.md → dev/ 이동
- 전체 참조 경로 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:46:03 +09:00

6.1 KiB

견적 수정 → 기존 수주 업데이트 연동 개선 계획

작성일: 2026-02-07 목적: 견적 수정 시 연결된 기존 수주를 자동 업데이트하고, "수주등록" 대신 "수주 보기" 버튼 표시 상태: 🔄 진행중


📍 현재 진행 상태

항목 내용
마지막 완료 작업 분석 완료
다음 작업 Phase 1.1 - API 수정
진행률 0/4 (0%)
마지막 업데이트 2026-02-07

1. 개요

1.1 배경

사용자가 수주(33) 상세 → 견적(41) 수정 → 저장 후 "수주등록" 버튼이 표시되어 클릭 시 새 수주가 생성됨.

기대 동작: 견적 수정 → 기존 수주(33)에 자동 반영 + "수주 보기" 버튼으로 기존 수주 이동

1.2 근본 원인

  • Quote.order_id가 null인 상태에서 Order.quote_id만 설정된 경우 발생
  • QuoteService::update()quote->order_id 기준으로만 동기화 트리거
  • QuoteService::show()는 역방향 참조(Order.quote_id)를 고려하지 않음
  • 결과: 프론트에서 orderId = null → "수주등록" 버튼 표시

1.3 기존 구현 현황 (이미 구현된 부분)

기능 상태 위치
OrderService::syncFromQuote() 완전 구현 api/app/Services/OrderService.php:561-746
QuoteService::update() → syncFromQuote 호출 구현 (order_id 기준) api/app/Services/Quote/QuoteService.php:448
QuoteFooterBar "수주 보기" / "수주등록" 분기 구현 (orderId 기준) react/src/components/quotes/QuoteFooterBar.tsx:209
transformApiToV2: order_id → orderId 매핑 구현 react/src/components/quotes/types.ts:275,1008

1.4 변경 승인 정책

분류 예시 승인
즉시 가능 기존 메서드에 조건 추가 불필요
⚠️ 컨펌 필요 API 로직 변경, 데이터 보정 필수

2. 대상 범위

2.1 Phase 1: API 수정 (백엔드)

# 작업 항목 상태 비고
1.1 QuoteService::show() - 역방향 order 참조 보정 order_id null이면 orders() 관계로 탐색
1.2 QuoteService::update() - 역방향 sync 트리거 order_id null이어도 orders() 있으면 동기화

2.2 Phase 2: 프론트엔드 확인

# 작업 항목 상태 비고
2.1 견적 수정 후 view 모드 전환 시 데이터 갱신 확인 orderId가 정상 반영되는지
2.2 "수주 보기" 버튼 동작 확인 기존 수주로 정상 이동하는지

3. 작업 절차

3.1 상세 변경 사항

1.1 QuoteService::show() 수정

파일: api/app/Services/Quote/QuoteService.php (line 168-187)

현재 동작: Quote 모델을 그대로 반환 (order_id가 null이면 null 그대로)

변경: quote.order_id가 null인데 Order.quote_id로 연결된 수주가 있으면 order_id를 보정

// show() 메서드 내, return $quote; 직전에 추가
if (!$quote->order_id) {
    $linkedOrder = \App\Models\Orders\Order::where('quote_id', $quote->id)
        ->where('tenant_id', $tenantId)
        ->first();
    if ($linkedOrder) {
        // DB에도 반영 (데이터 정합성 복구)
        $quote->update(['order_id' => $linkedOrder->id]);
        $quote->refresh();
    }
}

1.2 QuoteService::update() 동기화 트리거 확장

파일: api/app/Services/Quote/QuoteService.php (line 447-460)

현재 동작: if ($quote->order_id) 일 때만 syncFromQuote 호출

변경: order_id가 null이어도 orders() 관계로 연결된 수주가 있으면 동기화 실행

// 기존 코드 (line 448)
if ($quote->order_id) {

// 변경 후
$orderId = $quote->order_id;
if (!$orderId) {
    // 역방향 참조로 연결된 수주 찾기
    $linkedOrder = \App\Models\Orders\Order::where('quote_id', $quote->id)
        ->where('tenant_id', $tenantId)
        ->first();
    if ($linkedOrder) {
        $quote->update(['order_id' => $linkedOrder->id]);
        $orderId = $linkedOrder->id;
    }
}
if ($orderId) {

3.2 영향 범위

영향 받는 부분 변경 여부 설명
QuoteService::show() 수정 역방향 참조 보정
QuoteService::update() 수정 sync 트리거 확장
OrderService::syncFromQuote() 변경 없음 이미 완전 구현
QuoteFooterBar.tsx 변경 없음 orderId 기준 분기 이미 구현
QuoteRegistrationV2.tsx 변경 없음 orderId 전달 이미 구현
types.ts (transformApiToV2) 변경 없음 order_id → orderId 매핑 이미 구현

4. 검증 방법

4.1 테스트 시나리오

# 시나리오 예상 결과
1 수주(33) 상세 → 견적(41) 수정 → 저장 기존 수주(33) 품목 자동 업데이트
2 견적(41) 상세 view 모드 진입 "수주 보기" 버튼 표시 (수주등록 아님)
3 "수주 보기" 버튼 클릭 수주(33) 상세 페이지로 이동
4 견적 수정 후 금액 변경 수주 총금액도 동기화

4.2 성공 기준

  • 견적 수정 시 연결된 수주가 자동 업데이트됨
  • "수주 보기" 버튼이 정상 표시됨
  • 기존 수주로 정상 네비게이션됨
  • 기존 convertToOrder() 플로우에 영향 없음

5. 참고 파일

파일 역할
api/app/Services/Quote/QuoteService.php 견적 서비스 (show, update, convertToOrder)
api/app/Services/OrderService.php 수주 서비스 (syncFromQuote)
api/app/Models/Quote/Quote.php 견적 모델 (orders() 관계)
api/app/Models/Orders/Order.php 수주 모델 (quote() 관계)
react/src/components/quotes/QuoteFooterBar.tsx 견적 푸터 바 (버튼 분기)
react/src/components/quotes/QuoteRegistrationV2.tsx 견적 등록/수정 V2
react/src/components/quotes/types.ts 타입 및 API→V2 변환
react/src/app/[locale]/(protected)/sales/quote-management/[id]/page.tsx 견적 상세 페이지

이 문서는 /sc:plan 스킬로 생성되었습니다.