Skip to content

구매·재고 Prototype — Frontend 핸드오프

목적과 경계

기존 구매·매입채무의 앞 단계에 구매요청 → 승인 → 발주 → 입고 흐름을 추가한다. 입고는 재고 원자이며 회계 매입 확정이 아니다. 입고별 purchaseCandidates를 만든 뒤 기존 매입 거래 화면에서 증빙 확인 후 연결하는 것이 불변식이다.

제조 BOM·MRP·생산계획·고급 SCM은 이 범위에 포함하지 않는다.

2026-07-17 기준 서버 연결 범위는 구매요청 초안 생성 → 제출 → 전자결재 요청 → 승인/반려 반영 → 발주다. 입고부터는 로컬 prototype만 유지하며 서버 발주에는 입고 버튼을 노출하지 않는다.

구현 위치

text
src/composables/useProcurementInventory.js
src/composables/procurementRequestRepo.js
src/composables/procurementRequestPersistence.js
src/composables/useProcurementRequestWorkspace.js
src/components/purchasing/console/purchase-order/
src/components/purchasing/console/inventory/
src/views/purchasing/console/purchase-order/IndexView.vue
src/views/purchasing/console/inventory/IndexView.vue

라우터와 메뉴는 총괄 통합 단계에서 다음 뷰를 연결한다.

  • 구매·발주: purchasing/console/purchase-order/IndexView.vue
  • 재고 현황: purchasing/console/inventory/IndexView.vue

상태 모델

useProcurementInventory는 후속 흐름을 시연하는 로컬 reactive singleton이다. procurementRequestRepo는 Supabase 설정과 VITE_PROCUREMENT_REQUEST_PERSISTENCE=true가 모두 있을 때만 서버 adapter를 선택한다. 결재자 목록은 workforce 직접 조회가 아니라 approval의 get_approval_participant_directory를 사용한다. procurementRequestPersistence가 서버 요청·안전한 결재요약·발주·공급사·결재자 목록과 명령 상태를 소유한다. useProcurementRequestWorkspace는 현재 Account의 Company·Office를 명령 context로 공급한다.

서버 행은 UI adapter에서 다음처럼 변환한다.

  • 고객 노출 구매요청 등록번호 → 목록의 구매요청 등록번호

  • UUID → entityId·Vue rowKey로만 유지하고 화면에 표시하지 않음. 중복 가능한 구매요청 등록번호를 row key로 쓰지 않음

  • requestingUnitName → 요청부서

  • estimatedUnitPrice → 예상금액 계산

  • draft/submitted/approved/rejected/ordered초안/제출/승인완료/반려/발주완료

  • submitted + approvalSummary.linkState=open결재중

  • 서버 제출 행은 도메인 전용 request_procurement_approval을 호출한다. 화면 호환 모델의 employeeId/assignmentId에는 approval participant user UUID가 들어가며 서버 translator가 v2 participant로 검증한다.

  • 서버 승인완료 행은 ap_vendor Office assignment를 선택해 발주한다. 공급사 이름이나 등록번호를 자유 입력하지 않는다.

  • 구매 목록은 결재의 안전한 요약 RPC만 사용한다. 결재 본문·의견 table을 추가 조회하지 않는다.

  • requests: 요청, 승인완료, 발주완료

  • orders: 발주, 부분입고, 입고완료

  • receipts: 검수 완료된 실제 입고

  • stocks: itemId + Office 단위 재고

  • purchaseCandidates: 입고 근거 매입등록 후보

  • assetCandidates: 자산 추적 품목의 개별 등록 후보

핵심 액션은 createRequest, approveRequest, createOrderFromRequest, receiveOrder, markPurchaseCandidateLinked, markAssetCandidateRegistered다.

UX 규칙

  • 승인 완료된 요청만 발주로 전환한다.
  • 반려된 요청에는 발주 액션을 노출하지 않는다.
  • 서버 제출은 현재 선택한 Office로 고정하고, actor ID는 클라이언트에서 보내지 않는다.
  • 서버 저장은 createDraft 응답 revision을 곧바로 submitexpectedRevision에 사용한다.
  • 응답 유실 뒤 같은 입력을 재시도하면 보류 중인 create·submit 요청 키를 재사용해 중복 초안을 막는다. 같은 fingerprint의 동시 호출은 하나의 Promise를 공유하고, 입력 또는 작업범위가 바뀌면 별도 키를 만든다.
  • 서버 명령 동안 제출 버튼을 비활성화하며 실패하면 폼을 닫지 않는다. loading은 in-flight 작업 Set에서 파생하므로 병렬 작업 하나가 먼저 끝나도 조기 해제되지 않는다.
  • Company·Office가 바뀌면 기존 서버 행을 즉시 비우고 새 범위를 조회한다. 이전 범위의 늦은 응답은 sequence token으로 버리며, 각 행의 Office 이름은 서버 join 결과를 사용한다.
  • 입고 수량은 발주 잔량을 초과할 수 없다.
  • 입고 완료 발주를 다시 입고할 수 없다.
  • 검색 결과와 자산 후보가 없을 때 각각 명시적인 빈 상태를 표시한다.
  • 모바일에서는 폼과 검색 필터가 단일 열로 바뀌며, 테이블은 카드 밖으로 화면을 밀지 않고 내부 스크롤한다.
  • 입고 후 회계 매입이 자동 확정된 것처럼 표현하지 않는다.

운영 전 교체점

  • 부분 입고 수량·검수 보류·반품/입고 취소 UI 추가
  • 거래처 마스터와 품목 마스터 Select 연결
  • 창고·로케이션 이동, 출고, 재고조사 원장 추가
  • 매입 거래 후보 상세 확인 화면과 실제 연결 API 추가
  • 자산관리로 넘길 때 개별 시리얼·책임자·위치 수집

검증

  • src/composables/useProcurementInventory.spec.js
  • src/composables/__tests__/procurementRequestRepo.spec.js
  • src/composables/__tests__/procurementRequestPersistence.spec.js
  • src/composables/__tests__/procurementRequestMigration.spec.js
  • src/composables/__tests__/procurementApprovalOrderMigration.spec.js
  • supabase/tests/procurement_approval_order_workflow_smoke.sql
  • src/components/purchasing/console/purchase-order/__tests__/MainOrg.spec.js
  • src/components/purchasing/console/inventory/__tests__/MainOrg.spec.js