Merge branch 'main' of http://114.203.209.83:3000/SamProject/sam-docs
This commit is contained in:
@@ -818,7 +818,6 @@ sudo supervisorctl restart sam-mng-worker:*
|
||||
| Skill | 설명 |
|
||||
|-------|------|
|
||||
| `pptx-skill` | PowerPoint 생성 |
|
||||
| `ppt-auto-generator` | 마크다운/텍스트에서 PPT 생성 |
|
||||
| `pdf-template-skill` | PDF 템플릿 분석/생성 |
|
||||
| `text-analyzer-skill` | 텍스트 분석 및 PDF 구조 매핑 |
|
||||
| `proposal-skill` | 제안서 생성 |
|
||||
|
||||
13
INDEX.md
13
INDEX.md
@@ -24,6 +24,10 @@
|
||||
| 견적관리 | `features/quotes/README.md` | 견적 시스템, BOM 계산 |
|
||||
| 급여관리 API | `frontend/api-specs/payroll-api.md` | 급여관리 API 전체 명세 (18개 엔드포인트) |
|
||||
| 바로빌 회계 API | `frontend/api-specs/barobill-api.md` | 카드/은행/홈택스 REST API (42개 엔드포인트) |
|
||||
| 바로빌 시스템 | `features/barobill/README.md` | SOAP 연동, 테스트/운영 모드, 과금, 멀티테넌트, 이관 계획 |
|
||||
| 바로빌 출시 계획 | `dev/dev_plans/barobill-service-launch-plan.md` | 4단계 출시 로드맵 (SOAP 이관→UI→베타→출시) |
|
||||
| 재공품 생산 정책 | `rules/wip-production-policy.md` | 재공품(WIP) 개념, 제조업 공통 패턴, SAM 처리 방식 |
|
||||
| 재고생산관리 API | `frontend/api-specs/stock-production-api.md` | 재고생산 API 명세 (기존 수주 API + STOCK 타입) |
|
||||
| 결재관리 | `dev/dev_plans/approval-system-unification-plan.md` | MNG→API 결재 통합 계획 |
|
||||
| API 품질 | `system/api-code-quality-audit.md` | 정석 패턴 R1~R6, 안티패턴, 보안, 체크리스트 |
|
||||
| API 학습 | `dev/guides/api-request-lifecycle.md` | Client API로 배우는 요청 생명주기 8단계 |
|
||||
@@ -138,6 +142,7 @@ DB 도메인별:
|
||||
| [pricing-policy.md](rules/pricing-policy.md) | 단가 정책 |
|
||||
| [numbering-rules.md](rules/numbering-rules.md) | 채번 규칙 |
|
||||
| [client-policy.md](rules/client-policy.md) | 고객사 관리 정책 |
|
||||
| [wip-production-policy.md](rules/wip-production-policy.md) | 재공품(WIP) 생산 정책 (개념, MTS/MTO/ATO, 제조업 공통 패턴) |
|
||||
| [billing-policy.md](rules/billing-policy.md) | 과금 정책 (CONFIDENTIAL) |
|
||||
| [customer-pricing.md](rules/customer-pricing.md) | 고객 요금표 |
|
||||
| [partner-commission.md](rules/partner-commission.md) | 영업파트너 수당 체계 |
|
||||
@@ -164,14 +169,19 @@ DB 도메인별:
|
||||
| [ai/README.md](features/ai/README.md) | AI 분석 |
|
||||
| [card-vehicle/README.md](features/card-vehicle/README.md) | 법인카드·차량 |
|
||||
| [settlement/README.md](features/settlement/README.md) | 정산 |
|
||||
| [sales/stock-production.md](features/sales/stock-production.md) | 재고생산관리 (내부 오더 방식, 수주 테이블 공유) |
|
||||
| [sales/demo-tenant-policy.md](features/sales/demo-tenant-policy.md) | 영업파트너 데모 테넌트 정책 (3-Tier 전략) |
|
||||
| [sales/demo-tenant-usage-guide.md](features/sales/demo-tenant-usage-guide.md) | 데모 테넌트 사용 가이드 (영업파트너/관리자용) |
|
||||
| [barobill/README.md](features/barobill/README.md) | 바로빌 연동 시스템 (SOAP API, 테스트/운영 모드, 과금, 이관 계획) |
|
||||
| [barobill/tenant-onboarding.md](features/barobill/tenant-onboarding.md) | 바로빌 테넌트 온보딩 (개념 정의, 6단계 프로세스, 베타테스트와의 차이) |
|
||||
| [barobill-kakaotalk/README.md](features/barobill-kakaotalk/README.md) | 바로빌 카카오톡 |
|
||||
| [quality-management/README.md](features/quality-management/README.md) | 품질관리 (제품검사, 실적신고) |
|
||||
| [approvals/README.md](features/approvals/README.md) | 결재관리 시스템 |
|
||||
| [approvals/mng-api-comparison.md](features/approvals/mng-api-comparison.md) | 결재관리 MNG↔API 비교 분석 및 React 구현 가이드 |
|
||||
| [email/README.md](features/email/README.md) | 이메일 시스템 (테넌트별 SMTP 설정, 프리셋, 연결 테스트) |
|
||||
| [construction-pmis/bim-viewer.md](features/construction-pmis/bim-viewer.md) | BIM 뷰어 (Three.js 기반 웹 3D 건물 모델 뷰어) |
|
||||
| [rd/README.md](features/rd/README.md) | R&D 메뉴 전체 개요 |
|
||||
| [rd/fire-shutter-drawing-guide-rail.md](features/rd/fire-shutter-drawing-guide-rail.md) | 방화셔터 가이드레일 SVG/3D 렌더링 기술 명세 |
|
||||
|
||||
---
|
||||
|
||||
@@ -230,6 +240,7 @@ DB 도메인별:
|
||||
| [20260314_api_quality_improvement_deploy.md](dev/changes/20260314_api_quality_improvement_deploy.md) | API 품질 개선 배포 — 테스트 56개 + N+1 최적화 3건 (근거 문서 포함) |
|
||||
| [20260315_eval_removal_safe_math_evaluator.md](dev/changes/20260315_eval_removal_safe_math_evaluator.md) | API 보안 개선 — eval() 3건 제거, SafeMathEvaluator 도입 |
|
||||
| [20260316_sales_policy_changes.md](changes/20260316_sales_policy_changes.md) | 영업 정책 변경 — 수당 구조 개편 및 무료 체험 폐지 |
|
||||
| [20260316_stock_production_order.md](dev/changes/20260316_stock_production_order.md) | 재고생산관리 기능 추가 (STOCK 타입, 절곡 공정 자동, 생산지시 연동) |
|
||||
|
||||
---
|
||||
|
||||
@@ -260,7 +271,9 @@ DB 도메인별:
|
||||
| [barobill-api.md](frontend/api-specs/barobill-api.md) | 바로빌 회계 데이터 API 명세 (42개 엔드포인트) |
|
||||
| [equipment-api.md](requests/equipment-frontend-request.md) | 설비관리 React 프론트엔드 구현 요청 (26개 엔드포인트 + 화면 가이드) |
|
||||
| [vehicle-api.md](frontend/api-specs/vehicle-api.md) | 차량관리 API 명세 (20개 엔드포인트: 차량목록, 차량일지, 정비이력, 사진) |
|
||||
| [stock-production-api.md](frontend/api-specs/stock-production-api.md) | 재고생산관리 API 명세 (기존 수주 API + STOCK 타입) |
|
||||
| [vehicle-react-implementation.md](plans/vehicle-react-implementation.md) | 차량관리 React 구현 요청서 (3개 메뉴, 컴포넌트 구조, 타입 정의) |
|
||||
| [stock-production-react-request.md](plans/stock-production-react-request.md) | 재고생산관리 React 구현 요청서 (수주 화면 단순화, API 스펙 포함) |
|
||||
|
||||
### frontend/integration/ — 프론트엔드 개발 가이드
|
||||
|
||||
|
||||
@@ -200,8 +200,8 @@
|
||||
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3);">점검/납기 알림</p>
|
||||
</div>
|
||||
<div style="flex: 1; background: rgba(255,255,255,0.04); border-radius: 5pt; padding: 5pt 8pt; text-align: center;">
|
||||
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 600; color: rgba(255,255,255,0.6);">이카운트 연동</p>
|
||||
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3);">기존 ERP 동기화</p>
|
||||
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 600; color: rgba(255,255,255,0.6);">바로빌 회계</p>
|
||||
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3);">세금계산서·카드</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
173
dev/changes/20260316_stock_production_order.md
Normal file
173
dev/changes/20260316_stock_production_order.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# 재고생산관리 기능 추가
|
||||
|
||||
**날짜:** 2026-03-16
|
||||
**작업자:** Claude Code
|
||||
|
||||
---
|
||||
|
||||
## 변경 개요
|
||||
|
||||
수주 없이 재고 목적으로 생산하는 경우를 관리하는 **재고생산관리** 기능을 추가했다.
|
||||
기존 `orders` 테이블을 공유하며, `order_type_code = 'STOCK'`으로 일반 수주와 구분한다.
|
||||
|
||||
### 설계 원칙
|
||||
|
||||
- **내부 오더(Internal Order)** 패턴 — 재고생산도 수주로 취급
|
||||
- 기존 테이블/API 재사용 — 별도 테이블/엔드포인트 없음
|
||||
- 하류 시스템(작업지시, 생산, 출하, 품질검사) 변경 없이 동작
|
||||
|
||||
---
|
||||
|
||||
## 수정된 파일
|
||||
|
||||
### 커밋 1: `feat: [order] 재고생산관리(STOCK) 타입 추가`
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|----------|
|
||||
| `app/Models/Orders/Order.php` | `TYPE_STOCK = 'STOCK'` 상수 추가 |
|
||||
| `app/Http/Requests/Order/StoreOrderRequest.php` | STOCK validation 허용, `production_reason`/`target_stock_qty` 옵션 추가 |
|
||||
| `app/Http/Requests/Order/UpdateOrderRequest.php` | 동일 |
|
||||
| `app/Services/OrderService.php` | STK 채번, stats `order_type` 필터, 매출 생성 스킵 |
|
||||
| `app/Http/Controllers/Api/V1/OrderController.php` | stats에 `order_type` 파라미터 전달 |
|
||||
|
||||
### 커밋 2: `feat: [order] 재고생산 생산지시 자동 처리`
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|----------|
|
||||
| `app/Services/OrderService.php` | `store()`: STOCK → `site_name='재고생산'` 자동 설정 |
|
||||
| `app/Services/OrderService.php` | `createProductionOrder()`: STOCK 분기 추가 (절곡 자동, project_name, scheduled_date) |
|
||||
| `lang/ko/error.php` | `bending_process_not_found` 에러 메시지 추가 |
|
||||
| `lang/en/error.php` | 동일 (영문) |
|
||||
|
||||
---
|
||||
|
||||
## 상세 변경 사항
|
||||
|
||||
### 1. Order 모델 — 타입 상수
|
||||
|
||||
```php
|
||||
public const TYPE_ORDER = 'ORDER'; // 수주
|
||||
public const TYPE_PURCHASE = 'PURCHASE'; // 발주
|
||||
public const TYPE_STOCK = 'STOCK'; // 재고생산 (신규)
|
||||
```
|
||||
|
||||
### 2. 채번 규칙
|
||||
|
||||
| 타입 | 접두사 | 형식 | 예시 |
|
||||
|------|--------|------|------|
|
||||
| ORDER | `ORD` | `ORD{YYYYMMDD}{NNNN}` | `ORD202603160001` |
|
||||
| STOCK | `STK` | `STK{YYYYMMDD}{NNNN}` | `STK202603160001` |
|
||||
|
||||
### 3. store() — STOCK 자동 처리
|
||||
|
||||
```php
|
||||
if ($isStock) {
|
||||
$data['site_name'] = '재고생산';
|
||||
}
|
||||
```
|
||||
|
||||
### 4. createProductionOrder() — STOCK 분기
|
||||
|
||||
| 항목 | ORDER (기존) | STOCK (신규) |
|
||||
|------|-------------|-------------|
|
||||
| 공정 매칭 | BOM item_id → process_items 매핑 | **절곡 공정 직접 할당** (BOM 스킵) |
|
||||
| project_name | `order.site_name ?? client_name` | `'재고생산'` 고정 |
|
||||
| scheduled_date | `order.delivery_date` | `now()` |
|
||||
| 매출 생성 | `sales_recognition` 정책 적용 | **생성 안 함** |
|
||||
|
||||
절곡 공정 조회:
|
||||
```php
|
||||
$bendingProcess = Process::where('tenant_id', $tenantId)
|
||||
->where('process_name', '절곡')
|
||||
->where('is_active', true)
|
||||
->first();
|
||||
```
|
||||
|
||||
### 5. stats() — order_type 필터
|
||||
|
||||
```php
|
||||
public function stats(?string $orderType = null): array
|
||||
```
|
||||
|
||||
`GET /api/v1/orders/stats?order_type=STOCK` 으로 재고생산 전용 통계 조회 가능.
|
||||
|
||||
### 6. 매출 생성 스킵
|
||||
|
||||
```php
|
||||
if ($status === Order::STATUS_CONFIRMED
|
||||
&& $order->order_type_code !== Order::TYPE_STOCK // STOCK 제외
|
||||
&& $order->shouldCreateSaleOnConfirm()) {
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 영향범위 분석
|
||||
|
||||
| 영역 | 영향 | 이유 |
|
||||
|------|------|------|
|
||||
| 기존 수주(ORDER) | ❌ 없음 | `$isStock` 조건 분기, else 블록에서 기존 코드 그대로 실행 |
|
||||
| 기존 발주(PURCHASE) | ❌ 없음 | 동일 |
|
||||
| 작업지시(WorkOrder) | ✅ 정상 동작 | `sales_order_id` FK로 연결, 절곡 공정 할당됨 |
|
||||
| 생산/품질검사 | ❌ 없음 | WorkOrder 기반 하류 시스템, Order 타입 무관 |
|
||||
| 출하(Shipment) | ❌ 없음 | WorkOrder 참조, Order.site_name 미사용 |
|
||||
| 캘린더 | ✅ 표시됨 | `project_name='재고생산'`, `scheduled_date=now()` |
|
||||
| 생산지시 목록 | ✅ 표시됨 | `site_name='재고생산'`으로 현장명 표시 |
|
||||
|
||||
---
|
||||
|
||||
## 버그 수정 (2026-03-17)
|
||||
|
||||
### 커밋 3: `fix: [production] 생산지시 생성 시 $isStock 미정의 오류 및 수량 정수 변환`
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|----------|
|
||||
| `app/Services/OrderService.php` | `DB::transaction` 클로저 `use`절에 `$isStock` 변수 추가 |
|
||||
| `app/Services/OrderService.php` | `work_order_items.quantity`를 `(int)` 캐스팅하여 정수로 저장 |
|
||||
|
||||
**원인**: `$isStock`가 line 1242에서 정의되지만, `DB::transaction` 클로저의 `use`절에 포함되지 않아 클로저 내부에서 참조 불가 → 500 에러 발생
|
||||
|
||||
### 커밋 4: `fix: [production] 생산지시 생성 시 $process 미정의 오류 수정`
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|----------|
|
||||
| `app/Services/OrderService.php` | `$process = null;` 초기화 추가 (if 블록 밖에서도 참조 가능하도록) |
|
||||
|
||||
**원인**: `$process`가 `if ($processId)` 블록 안에서만 정의되지만, 블록 밖 line 1420에서 team_id 결정 시 참조 → 공정 없는 품목 처리 시 500 에러 발생
|
||||
|
||||
### 커밋 5 (React): `fix: [stocks] 재고생산 수량을 정수로 표시`
|
||||
|
||||
| 파일 | 변경 내용 |
|
||||
|------|----------|
|
||||
| `src/components/stocks/actions.ts` | `transformItemApiToFrontend`에서 `Math.floor(Number())` 적용 |
|
||||
| `src/components/stocks/actions.ts` | 금액 필드도 `Number()`로 안전한 형변환 적용 |
|
||||
|
||||
**원인**: API의 Eloquent `decimal:4` 캐스트가 수량을 `"1.0000"` 문자열로 반환하여 프론트엔드에서 소수점 그대로 표시
|
||||
|
||||
---
|
||||
|
||||
## 테스트 체크리스트
|
||||
|
||||
- [x] STOCK 수주 생성 → `order_no` STK 접두사 확인
|
||||
- [x] STOCK 수주 생성 → `site_name='재고생산'` 자동 설정 확인
|
||||
- [ ] STOCK 수주 확정 → 매출 자동 생성 안 됨 확인
|
||||
- [x] STOCK 생산지시 생성 → 절곡 공정 자동 선택 확인
|
||||
- [x] STOCK 생산지시 생성 → `project_name='재고생산'` 확인
|
||||
- [x] STOCK 생산지시 생성 → `scheduled_date=today` 확인
|
||||
- [ ] 기존 ORDER 수주 생산지시 → 기존 BOM 매칭 정상 동작 확인
|
||||
- [ ] 생산지시 목록에서 STOCK 건 표시 확인
|
||||
- [x] 생산지시 생성 시 `$isStock` 미정의 오류 수정 확인
|
||||
- [x] 생산지시 생성 시 `$process` 미정의 오류 수정 확인
|
||||
- [x] `work_order_items.quantity` 정수 저장 확인
|
||||
- [x] 프론트엔드 수량 정수 표시 확인
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [재고생산관리 기능 설명](../../features/sales/stock-production.md)
|
||||
- [재고생산관리 API 명세](../../frontend/api-specs/stock-production-api.md)
|
||||
- [프론트엔드 구현 요청서](../../frontend/requests/stock-production-react-request.md)
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-17
|
||||
242
dev/dev_plans/barobill-service-launch-plan.md
Normal file
242
dev/dev_plans/barobill-service-launch-plan.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# 바로빌 서비스 출시 단계별 준비 계획
|
||||
|
||||
> **작성일**: 2026-03-17
|
||||
> **상태**: 계획 수립
|
||||
> **담당**: R&D실
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
|
||||
MNG에서 운영 중인 바로빌 연동 시스템을 서비스(API+React)로 이관하여, 멀티테넌트 고객이 직접 사용할 수 있는 SaaS 형태로 출시한다.
|
||||
|
||||
### 1.2 현재 상태
|
||||
|
||||
- **MNG (백오피스)**: 바로빌 SOAP 연동 완료, tenant_id=1 (코드브릿지엑스)에서 실무 운영 중
|
||||
- **API**: DB 모델 15개 + REST API 42개 엔드포인트 구현 완료 (데이터 조회/분개용)
|
||||
- **React**: 바로빌 설정 페이지 기본 구현
|
||||
|
||||
### 1.3 목표
|
||||
|
||||
고객(테넌트)이 SAM 서비스에서 바로빌 기능을 직접 설정하고 사용할 수 있도록 한다:
|
||||
- 계좌조회, 카드내역, 홈택스 세금계산서 자동 수집
|
||||
- 전자세금계산서 발행
|
||||
- 카카오톡/SMS 알림
|
||||
|
||||
---
|
||||
|
||||
## 2. 단계별 로드맵
|
||||
|
||||
```
|
||||
Phase 1 Phase 2 Phase 3 Phase 4
|
||||
SOAP 이관 UI 구현 베타테스트 정식 출시
|
||||
(API 개발) (React 개발) (내부→외부) (온보딩 가동)
|
||||
───────────── → ───────────── → ───────────── → ─────────────
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Phase 1: SOAP 연동 이관 (API 개발)
|
||||
|
||||
> **핵심**: MNG의 BarobillService를 API로 이관하여 멀티테넌트 지원
|
||||
|
||||
### 3.1 작업 목록
|
||||
|
||||
| # | 작업 | 상세 | 난이도 |
|
||||
|---|------|------|--------|
|
||||
| 1-1 | BarobillService 이관 | MNG 1,761줄 → API로 이동, 멀티테넌트 리팩토링 | 상 |
|
||||
| 1-2 | 회원사 관리 API | 등록/수정/조회/상태확인 엔드포인트 | 중 |
|
||||
| 1-3 | 인증서 관리 API | 등록URL/유효성/만료일 조회 엔드포인트 | 중 |
|
||||
| 1-4 | 계좌 관리 API | 등록/목록/입출금 조회 엔드포인트 | 중 |
|
||||
| 1-5 | 카드 관리 API | 등록/수정/해지/사용내역 조회 엔드포인트 | 중 |
|
||||
| 1-6 | 세금계산서 발행 API | 작성/발행/조회 엔드포인트 | 상 |
|
||||
| 1-7 | 동기화 스케줄러 | 은행/카드/홈택스 자동 수집 (Queue Job) | 중 |
|
||||
| 1-8 | 테스트/운영 모드 전환 API | 회원사별 server_mode 전환 | 하 |
|
||||
|
||||
### 3.2 기술 과제
|
||||
|
||||
| 과제 | 설명 | 대응 방안 |
|
||||
|------|------|----------|
|
||||
| CERTKEY 관리 | 현재 전역 1개 → 멀티테넌트 대응 필요 | 바로빌 파트너 계약 구조 확인 후 결정 |
|
||||
| PHP SOAP 확장 | API 서버에 `php-soap` 설치 필요 | Docker/서버 환경 확인 |
|
||||
| 암호화 키 공유 | MNG/API 간 `APP_KEY` 동일해야 복호화 가능 | 현재 동일 키 사용 중 (확인 필요) |
|
||||
| 동기화 부하 | 테넌트 수 증가 시 SOAP 호출량 증가 | Queue 분산, 호출 간격 조절 |
|
||||
|
||||
### 3.3 환경 준비
|
||||
|
||||
```bash
|
||||
# API 서버에 PHP SOAP 확장 확인
|
||||
php -m | grep soap
|
||||
|
||||
# 없으면 설치 (개발 서버 Level 2)
|
||||
sudo apt install php8.4-soap
|
||||
sudo systemctl restart php8.4-fpm
|
||||
|
||||
# .env 설정 추가
|
||||
BAROBILL_CERT_KEY_TEST=<테스트 인증키>
|
||||
BAROBILL_CERT_KEY_PROD=<운영 인증키>
|
||||
BAROBILL_CORP_NUM=<파트너 사업자번호>
|
||||
BAROBILL_TEST_MODE=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Phase 2: UI 구현 (React 개발)
|
||||
|
||||
> **핵심**: 고객이 직접 바로빌을 설정하고 데이터를 조회할 수 있는 화면
|
||||
|
||||
### 4.1 작업 목록
|
||||
|
||||
| # | 작업 | 상세 | 난이도 |
|
||||
|---|------|------|--------|
|
||||
| 2-1 | 바로빌 설정 페이지 | 회원사 등록/수정, 서버 모드 표시 | 중 |
|
||||
| 2-2 | 인증서 관리 화면 | 등록 URL 안내, 유효기간 표시, 갱신 알림 | 중 |
|
||||
| 2-3 | 계좌 관리 화면 | 등록 계좌 목록, 등록 URL 안내 | 중 |
|
||||
| 2-4 | 카드 관리 화면 | 등록 카드 목록, 추가/해지 | 중 |
|
||||
| 2-5 | 카드 거래내역 조회 | 기간별 조회, 분개 연동, 숨김/분할 | 상 |
|
||||
| 2-6 | 은행 거래내역 조회 | 기간별 조회, 분개 연동, 오버라이드/분할 | 상 |
|
||||
| 2-7 | 홈택스 세금계산서 | 매출/매입 조회, 분개 연동 | 중 |
|
||||
| 2-8 | 세금계산서 발행 화면 | 작성/발행 폼, 미리보기 | 상 |
|
||||
|
||||
### 4.2 화면 구성 (메뉴 구조)
|
||||
|
||||
```
|
||||
재무관리
|
||||
├─ 계좌관리
|
||||
│ ├─ 보유계좌 관리 (바로빌 계좌 등록 포함)
|
||||
│ └─ 계좌 입출금 내역
|
||||
├─ 카드관리
|
||||
│ ├─ 법인카드 관리 (바로빌 카드 등록 포함)
|
||||
│ └─ 카드 사용내역
|
||||
├─ 세금계산서
|
||||
│ ├─ 매출 세금계산서
|
||||
│ ├─ 매입 세금계산서
|
||||
│ └─ 세금계산서 발행
|
||||
└─ 설정
|
||||
└─ 바로빌 연동 설정 (인증서, 모드, 충전잔액)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Phase 3: 베타테스트
|
||||
|
||||
> **핵심**: 내부 → 외부 순서로 검증, 테스트 모드 사용
|
||||
|
||||
### 5.1 내부 베타테스트
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **대상** | tenant_id=1 (코드브릿지엑스 본사) |
|
||||
| **기간** | 2주 |
|
||||
| **모드** | 테스트 모드 |
|
||||
| **검증 항목** | 전체 기능 동작, UI/UX, 데이터 정합성 |
|
||||
| **비교 기준** | MNG 운영 데이터와 서비스 데이터 일치 확인 |
|
||||
|
||||
**내부 베타 체크리스트**:
|
||||
|
||||
- [ ] 회원사 등록/수정 정상 동작
|
||||
- [ ] 인증서 등록 URL 정상 접근
|
||||
- [ ] 계좌 등록 및 입출금 내역 조회
|
||||
- [ ] 카드 등록 및 사용내역 조회
|
||||
- [ ] 홈택스 매출/매입 세금계산서 수집
|
||||
- [ ] 세금계산서 발행 (테스트 서버)
|
||||
- [ ] 분개 연동 정상 동작
|
||||
- [ ] 동기화 스케줄러 자동 수집 확인
|
||||
- [ ] MNG 데이터와 서비스 데이터 일치
|
||||
|
||||
### 5.2 외부 베타테스트
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **대상** | 선별 고객사 2~3곳 |
|
||||
| **기간** | 2~4주 |
|
||||
| **모드** | 테스트 모드 |
|
||||
| **검증 항목** | 실사용 시나리오, 다양한 사업자 유형, 피드백 수집 |
|
||||
|
||||
**외부 베타 체크리스트**:
|
||||
|
||||
- [ ] 다양한 사업자번호로 회원 등록
|
||||
- [ ] 다양한 은행/카드사 연동 확인
|
||||
- [ ] 고객 직접 인증서/계좌/카드 등록 가능 확인
|
||||
- [ ] 고객 피드백 수집 및 반영
|
||||
- [ ] 성능 (다수 테넌트 동시 동기화)
|
||||
|
||||
---
|
||||
|
||||
## 6. Phase 4: 정식 출시
|
||||
|
||||
> **핵심**: 운영 모드 전환, 과금 시작, 온보딩 프로세스 가동
|
||||
|
||||
### 6.1 출시 준비 체크리스트
|
||||
|
||||
**인프라**:
|
||||
- [ ] API 서버 `php-soap` 확장 설치 확인
|
||||
- [ ] 운영 `.env`에 `BAROBILL_CERT_KEY_PROD`, `BAROBILL_CORP_NUM` 설정
|
||||
- [ ] `BAROBILL_TEST_MODE=false` 설정
|
||||
- [ ] 동기화 스케줄러 Supervisor 등록
|
||||
- [ ] 바로빌 운영 CERTKEY 충전잔액 확보
|
||||
|
||||
**과금**:
|
||||
- [ ] `barobill_pricing_policies` 요금 정책 데이터 입력
|
||||
- [ ] 월정액 구독 자동 과금 배치 등록 (매월 1일)
|
||||
- [ ] 과금 내역 고객 조회 화면 (선택)
|
||||
|
||||
**운영**:
|
||||
- [ ] 인증서 만료 알림 (이메일/카카오톡)
|
||||
- [ ] 충전잔액 부족 알림
|
||||
- [ ] 동기화 실패 알림 및 재시도 로직
|
||||
- [ ] 바로빌 장애 시 대응 매뉴얼
|
||||
|
||||
### 6.2 온보딩 프로세스 정립
|
||||
|
||||
정식 출시 후 신규 고객 가입 시:
|
||||
|
||||
```
|
||||
계약 → 테넌트 생성 → 회원등록(테스트) → 인증서/계좌/카드 → 검증 → 운영전환 → 실무사용
|
||||
```
|
||||
|
||||
> 상세 프로세스: `features/barobill/tenant-onboarding.md` 참조
|
||||
|
||||
---
|
||||
|
||||
## 7. 바로빌 파트너 정책 확인 필요 사항
|
||||
|
||||
> **경고: 개발 착수 전 바로빌 측에 확인해야 할 사항**
|
||||
|
||||
| # | 확인 사항 | 이유 | 현재 상태 |
|
||||
|---|----------|------|----------|
|
||||
| 1 | 멀티테넌트 CERTKEY 구조 | 파트너 1개 키로 다수 회원사 관리 가능한지 | 미확인 |
|
||||
| 2 | 테스트 서버 제한 | 테스트 API 호출 횟수/기간 제한 | 미확인 |
|
||||
| 3 | 과금 구조 | 파트너 단가표 (건당/월정액) | 미확인 |
|
||||
| 4 | SLA | 바로빌 API 가용성 보장 수준 | 미확인 |
|
||||
| 5 | 회원사 대량 등록 | 일괄 등록 API 또는 제한 | 미확인 |
|
||||
| 6 | 인증서 대리 등록 | 고객 대신 등록 가능 여부 | 미확인 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 리스크 및 대응
|
||||
|
||||
| 리스크 | 영향 | 대응 |
|
||||
|--------|------|------|
|
||||
| 바로빌 API 장애 | 거래 데이터 수집 중단 | 재시도 로직 + 장애 알림 |
|
||||
| 인증서 만료 | 계좌/세금계산서 조회 불가 | 만료 30일 전 알림 |
|
||||
| SOAP 호출 지연 | 페이지 응답 지연 | 비동기 Queue 처리 |
|
||||
| 테넌트 급증 | 동기화 부하 | 호출 간격 분산, 우선순위 큐 |
|
||||
| 충전잔액 부족 | API 호출 실패 | 잔액 모니터링 + 자동 알림 |
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
| 문서 | 설명 |
|
||||
|------|------|
|
||||
| [바로빌 연동 시스템](../../features/barobill/README.md) | 전체 구조, 모드, 과금 |
|
||||
| [테넌트 온보딩](../../features/barobill/tenant-onboarding.md) | 온보딩 6단계 프로세스 |
|
||||
| [바로빌 API 명세](../../frontend/api-specs/barobill-api.md) | REST API 42개 엔드포인트 |
|
||||
| [이관 현황](../../system/migration-status.md) | MNG→API+React 전체 이관 현황 |
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-17
|
||||
BIN
dev/dev_plans/barobill-service-launch-plan.pptx
Normal file
BIN
dev/dev_plans/barobill-service-launch-plan.pptx
Normal file
Binary file not shown.
398
features/barobill/README.md
Normal file
398
features/barobill/README.md
Normal file
@@ -0,0 +1,398 @@
|
||||
# 바로빌(Barobill) 연동 시스템
|
||||
|
||||
> **작성일**: 2026-03-17
|
||||
> **상태**: MNG 운영 중 / 서비스 이관 준비
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
|
||||
바로빌은 전자세금계산서, 계좌조회, 카드내역, 홈택스 연동, 카카오톡/SMS 발송 등을 제공하는 SOAP 기반 B2B 서비스다. SAM에서 재무/회계 데이터를 자동 수집하고 세금계산서를 발행하기 위해 연동한다.
|
||||
|
||||
### 1.2 현재 상태
|
||||
|
||||
| 항목 | MNG (백오피스) | API (서비스) | React (프론트) |
|
||||
|------|:------------:|:----------:|:------------:|
|
||||
| SOAP 연동 서비스 | ✅ 완료 (1,761줄) | 기본 설정만 | — |
|
||||
| 회원사 관리 | ✅ 운영 중 | 모델만 존재 | 설정 페이지 |
|
||||
| 카드 거래 조회 | ✅ 운영 중 | ✅ REST API 16개 | — |
|
||||
| 은행 거래 조회 | ✅ 운영 중 | ✅ REST API 13개 | — |
|
||||
| 홈택스 세금계산서 | ✅ 운영 중 | ✅ REST API 13개 | — |
|
||||
| 카카오톡/SMS | ✅ 운영 중 | — | — |
|
||||
| 과금 시스템 | ✅ 구현 완료 | — | — |
|
||||
|
||||
> **핵심**: tenant_id=1 (코드브릿지엑스 본사)에서 실무 운영 중. 서비스 이관 시 멀티테넌트 SOAP 연동이 핵심 과제.
|
||||
|
||||
### 1.3 바로빌 공식 자료
|
||||
|
||||
- 개발자 센터: `https://dev.barobill.co.kr/`
|
||||
- 운영 WSDL: `https://ws.baroservice.com/`
|
||||
- 테스트 WSDL: `https://testws.baroservice.com/`
|
||||
|
||||
---
|
||||
|
||||
## 2. 테스트 모드 vs 운영 모드
|
||||
|
||||
> **경고: 개발 시 반드시 테스트 모드를 사용한다. 운영 모드는 실제 과금이 발생한다.**
|
||||
|
||||
### 2.1 모드 비교
|
||||
|
||||
| 항목 | 테스트 모드 | 운영 모드 |
|
||||
|------|-----------|----------|
|
||||
| WSDL 엔드포인트 | `https://testws.baroservice.com/` | `https://ws.baroservice.com/` |
|
||||
| CERTKEY | 테스트용 별도 발급 | 운영용 별도 발급 |
|
||||
| 과금 | ❌ 무과금 | ✅ 실제 과금 |
|
||||
| 데이터 | 테스트 데이터 (초기화 가능) | 실제 세금계산서/거래 데이터 |
|
||||
| 국세청 전송 | ❌ 미전송 | ✅ 실제 전송 |
|
||||
| 회원사 등록 | 테스트 서버에 등록 | 운영 서버에 등록 |
|
||||
| 인증서 | 테스트 인증서 사용 가능 | 실제 공동인증서 필수 |
|
||||
|
||||
### 2.2 모드 전환 구조
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────────┐
|
||||
│ 모드 결정 흐름 │
|
||||
├───────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. BarobillMember.server_mode │
|
||||
│ └─ 'test' 또는 'production' (회원사별 설정) │
|
||||
│ │
|
||||
│ 2. BarobillService.switchServerMode(isTestMode) │
|
||||
│ └─ SOAP 클라이언트 재초기화 │
|
||||
│ └─ initializeConfig() 호출 │
|
||||
│ │
|
||||
│ 3. initializeConfig() │
|
||||
│ ├─ DB 우선: BarobillConfig.getActive(isTestMode) │
|
||||
│ │ └─ environment = 'test' | 'production' │
|
||||
│ └─ .env 폴백: │
|
||||
│ ├─ test → BAROBILL_CERT_KEY_TEST │
|
||||
│ └─ prod → BAROBILL_CERT_KEY_PROD │
|
||||
│ │
|
||||
│ 4. SOAP URL 구성 │
|
||||
│ ├─ test → testws.baroservice.com/* │
|
||||
│ └─ prod → ws.baroservice.com/* │
|
||||
│ │
|
||||
└───────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.3 설정 우선순위
|
||||
|
||||
1. **DB 설정** (`barobill_configs` 테이블) — 최우선
|
||||
2. **.env 환경변수** — DB 설정 없을 때 폴백
|
||||
|
||||
```php
|
||||
// BarobillService::initializeConfig()
|
||||
$dbConfig = BarobillConfig::getActive($this->isTestMode);
|
||||
|
||||
if ($dbConfig) {
|
||||
// DB에서 cert_key, corp_num, base_url 사용
|
||||
} else {
|
||||
// .env에서 BAROBILL_CERT_KEY_TEST/PROD, BAROBILL_CORP_NUM 사용
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 환경변수
|
||||
|
||||
```bash
|
||||
# .env (MNG, API 동일)
|
||||
BAROBILL_CERT_KEY_TEST=<테스트 인증키>
|
||||
BAROBILL_CERT_KEY_PROD=<운영 인증키>
|
||||
BAROBILL_CORP_NUM=<파트너 사업자번호>
|
||||
BAROBILL_TEST_MODE=true # 기본값: 테스트 모드
|
||||
```
|
||||
|
||||
### 2.5 개발 시 주의사항
|
||||
|
||||
```
|
||||
✅ 로컬/개발 서버: BAROBILL_TEST_MODE=true (기본값)
|
||||
✅ 운영 서버: BAROBILL_TEST_MODE=false + 운영 CERTKEY
|
||||
✅ 회원사별 server_mode로 개별 전환 가능
|
||||
❌ 테스트 CERTKEY로 운영 서버 호출 불가 (에러 -11102)
|
||||
❌ 운영 모드에서 테스트 데이터 생성 금지 (실제 과금)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 아키텍처
|
||||
|
||||
### 3.1 전체 데이터 흐름
|
||||
|
||||
```
|
||||
바로빌 SOAP API (ws.baroservice.com)
|
||||
│
|
||||
│ SOAP (6개 서비스)
|
||||
▼
|
||||
┌─────────────────────────────────┐
|
||||
│ MNG (BarobillService) │
|
||||
│ ├─ CORPSTATE — 회원사 관리 │
|
||||
│ ├─ TI — 전자세금계산서 │
|
||||
│ ├─ BANKACCOUNT — 계좌조회 │
|
||||
│ ├─ CARD — 카드조회 │
|
||||
│ ├─ KAKAOTALK — 알림톡 │
|
||||
│ └─ SMS — 문자 발송 │
|
||||
└──────────┬──────────────────────┘
|
||||
│ MySQL 저장
|
||||
▼
|
||||
┌─────────────────────────────────┐
|
||||
│ MySQL (samdb) │
|
||||
│ ├─ barobill_members │
|
||||
│ ├─ barobill_card_transactions │
|
||||
│ ├─ barobill_bank_transactions │
|
||||
│ ├─ hometax_invoices │
|
||||
│ └─ (18개 테이블) │
|
||||
└──────────┬──────────────────────┘
|
||||
│ REST API
|
||||
▼
|
||||
┌─────────────────────────────────┐
|
||||
│ API (42개 엔드포인트) │
|
||||
│ ├─ /api/v1/barobill-card-* │
|
||||
│ ├─ /api/v1/barobill-bank-* │
|
||||
│ └─ /api/v1/hometax-invoices/* │
|
||||
└──────────┬──────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────┐
|
||||
│ React (사용자 UI) │
|
||||
│ └─ BarobillIntegration 컴포넌트│
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.2 SOAP 서비스 목록
|
||||
|
||||
| 서비스 | WSDL 경로 | 기능 |
|
||||
|--------|----------|------|
|
||||
| CORPSTATE | `/CORPSTATE.asmx` | 회원사 등록/조회/수정 |
|
||||
| TI | `/TI.asmx` | 전자세금계산서 발행/조회 |
|
||||
| BANKACCOUNT | `/BANKACCOUNT.asmx` | 계좌 등록/입출금 내역 조회 |
|
||||
| CARD | `/CARD.asmx` | 카드 등록/사용내역 조회 |
|
||||
| KAKAOTALK | `/KAKAOTALK.asmx` | 카카오톡 알림톡 발송 |
|
||||
| SMS | `/SMS.asmx` | 문자 메시지 발송 |
|
||||
|
||||
### 3.3 인증 구조
|
||||
|
||||
```
|
||||
모든 API 호출
|
||||
└─ CERTKEY (파트너 인증키) — 필수 파라미터
|
||||
├─ 바로빌 파트너 계약 시 발급
|
||||
├─ 테스트/운영 별도 키
|
||||
└─ BarobillService.call()에서 자동 주입
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 과금 정책
|
||||
|
||||
### 4.1 바로빌 과금 구조 (SAM 내부 정책)
|
||||
|
||||
| 서비스 | 월정액 | 비고 |
|
||||
|--------|-------|------|
|
||||
| 계좌조회 (`bank_account`) | 10,000원/월 | 테넌트별 |
|
||||
| 카드내역 (`card`) | 10,000원/월 | 테넌트별 |
|
||||
| 홈택스 매입/매출 (`hometax`) | 0원 | 본사 부담 (무료 제공) |
|
||||
|
||||
### 4.2 추가 과금 (건별)
|
||||
|
||||
`BarobillPricingPolicy` 모델 기반:
|
||||
|
||||
| 서비스 | 무료 기본량 | 추가 과금 단위 | 추가 금액 |
|
||||
|--------|-----------|-------------|----------|
|
||||
| 법인카드 등록 (`card`) | 정책 설정값 | 정책 설정값 | 정책 설정값 |
|
||||
| 계산서 발행 (`tax_invoice`) | 정책 설정값 | 건당 | 정책 설정값 |
|
||||
| 계좌조회 수집 (`bank_account`) | 정책 설정값 | 정책 설정값 | 정책 설정값 |
|
||||
|
||||
> 과금 계산: `BarobillPricingPolicy::calculateBilling(usageCount)` — 무료 제공량 초과분만 과금
|
||||
|
||||
### 4.3 과금 처리 흐름
|
||||
|
||||
```
|
||||
매월 1일 (배치)
|
||||
└─ BarobillBillingService::processMonthlyBilling()
|
||||
├─ 활성 구독 조회 (BarobillSubscription::active())
|
||||
├─ 이미 과금된 기록 중복 방지
|
||||
├─ BarobillBillingRecord 생성 (subscription 타입)
|
||||
└─ BarobillMonthlySummary 갱신
|
||||
|
||||
건별 발생 시
|
||||
└─ BarobillBillingService::recordUsage()
|
||||
├─ BarobillBillingRecord 생성 (usage 타입)
|
||||
└─ BarobillMonthlySummary 갱신
|
||||
```
|
||||
|
||||
### 4.4 테스트 모드에서의 과금
|
||||
|
||||
```
|
||||
✅ 테스트 모드: 바로빌 API 호출에 대한 바로빌 측 과금 없음
|
||||
✅ SAM 내부 과금 시스템은 모드와 무관하게 기록 가능 (테스트용)
|
||||
❌ 운영 모드: 바로빌 측 실제 과금 발생 (충전잔액 차감)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 멀티테넌트 처리
|
||||
|
||||
### 5.1 데이터 격리
|
||||
|
||||
모든 바로빌 테이블은 `tenant_id` 컬럼으로 데이터를 격리한다.
|
||||
|
||||
```
|
||||
tenant_id=1 (코드브릿지엑스) → 본사 실무 데이터
|
||||
tenant_id=N (고객사) → 해당 고객사 데이터만 접근
|
||||
```
|
||||
|
||||
### 5.2 회원사별 설정
|
||||
|
||||
각 테넌트는 `barobill_members` 테이블에 독립된 바로빌 회원사 정보를 가진다:
|
||||
|
||||
| 컬럼 | 설명 |
|
||||
|------|------|
|
||||
| `tenant_id` | 테넌트 FK |
|
||||
| `biz_no` | 사업자번호 (UNIQUE with tenant_id) |
|
||||
| `barobill_id` | 바로빌 로그인 ID |
|
||||
| `barobill_pwd` | 바로빌 비밀번호 (Laravel Encryption) |
|
||||
| `server_mode` | `test` 또는 `production` (회원사별 전환) |
|
||||
| `status` | `active` / `inactive` / `pending` |
|
||||
|
||||
### 5.3 서비스 이관 시 고려사항
|
||||
|
||||
```
|
||||
🔴 필수: 테넌트별 CERTKEY 관리 방안 (현재는 전역 1개)
|
||||
🔴 필수: 테넌트 온보딩 시 바로빌 회원 자동 등록 플로우
|
||||
🟡 중요: 테스트→운영 모드 전환 프로세스 정의
|
||||
🟡 중요: 과금 정책을 테넌트별로 다르게 적용 가능하도록 확장
|
||||
🟢 권장: 바로빌 API 호출 로그/모니터링
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 프로젝트별 코드 위치
|
||||
|
||||
### 6.1 MNG (`/home/aweso/sam/mng`)
|
||||
|
||||
| 유형 | 경로 |
|
||||
|------|------|
|
||||
| 서비스 | `app/Services/Barobill/BarobillService.php` (1,761줄, 핵심) |
|
||||
| 서비스 | `app/Services/Barobill/HometaxSyncService.php` |
|
||||
| 서비스 | `app/Services/Barobill/BarobillBillingService.php` |
|
||||
| 서비스 | `app/Services/Barobill/BarobillUsageService.php` |
|
||||
| 서비스 | `app/Services/Barobill/BarobillBankSyncService.php` |
|
||||
| 모델 | `app/Models/Barobill/` (18개 모델) |
|
||||
| 컨트롤러 | `app/Http/Controllers/Barobill/` (7개) |
|
||||
| Admin API | `app/Http/Controllers/Api/Admin/Barobill/` (7개) |
|
||||
| 뷰 | `resources/views/barobill/` (10개 페이지) |
|
||||
|
||||
### 6.2 API (`/home/aweso/sam/api`)
|
||||
|
||||
| 유형 | 경로 |
|
||||
|------|------|
|
||||
| 서비스 | `app/Services/BarobillService.php` (기본 설정만) |
|
||||
| 모델 | `app/Models/Barobill/` (15개) |
|
||||
| 모델 | `app/Models/Tenants/BarobillSetting.php` |
|
||||
| 컨트롤러 | `app/Http/Controllers/Api/V1/Barobill*Controller.php` |
|
||||
| 마이그레이션 | `database/migrations/` (19개 바로빌 관련) |
|
||||
|
||||
### 6.3 React (`/home/aweso/sam/react`)
|
||||
|
||||
| 유형 | 경로 |
|
||||
|------|------|
|
||||
| 컴포넌트 | `src/components/settings/BarobillIntegration/` |
|
||||
| 페이지 | `/settings/barobill-integration` |
|
||||
|
||||
---
|
||||
|
||||
## 7. DB 테이블 구조
|
||||
|
||||
### 7.1 테이블 목록
|
||||
|
||||
| 테이블 | 용도 | 마이그레이션 위치 |
|
||||
|--------|------|-----------------|
|
||||
| `barobill_members` | 회원사 정보 | API |
|
||||
| `barobill_configs` | API 설정 (test/prod 분리) | API |
|
||||
| `barobill_settings` | 테넌트별 서비스 설정 | API |
|
||||
| `barobill_subscriptions` | 월정액 구독 | API |
|
||||
| `barobill_billing_records` | 과금 기록 | API |
|
||||
| `barobill_monthly_summaries` | 월별 과금 요약 | API |
|
||||
| `barobill_pricing_policies` | 요금 정책 | API |
|
||||
| `hometax_invoices` | 홈택스 세금계산서 | API |
|
||||
| `hometax_invoice_journals` | 세금계산서 분개 | API |
|
||||
| `barobill_bank_transactions` | 은행 거래 내역 | API |
|
||||
| `barobill_bank_transaction_overrides` | 은행 적요 수정 | API |
|
||||
| `barobill_bank_transaction_splits` | 은행 거래 분할 | API |
|
||||
| `barobill_bank_sync_status` | 은행 동기화 상태 | API |
|
||||
| `barobill_card_transactions` | 카드 거래 내역 | API |
|
||||
| `barobill_card_transaction_splits` | 카드 거래 분할 | API |
|
||||
| `barobill_card_transaction_amount_logs` | 카드 금액 수정 로그 | API |
|
||||
| `barobill_card_transaction_hides` | 카드 거래 숨김 | API |
|
||||
| `account_codes` | 계정과목 마스터 | API |
|
||||
|
||||
### 7.2 핵심 테이블 스키마
|
||||
|
||||
**barobill_members**:
|
||||
- `tenant_id` + `biz_no` UNIQUE
|
||||
- `server_mode`: `test` | `production`
|
||||
- `barobill_pwd`: Laravel Encryption (복호화 가능, API 호출 시 필요)
|
||||
|
||||
**hometax_invoices**:
|
||||
- `tenant_id` + `nts_confirm_num` + `invoice_type` UNIQUE
|
||||
- `invoice_type`: `sales` | `purchase`
|
||||
- `tax_type`: 1=과세, 2=영세, 3=면세
|
||||
- `issue_type`: 1=정발행, 2=역발행
|
||||
|
||||
---
|
||||
|
||||
## 8. 에러 코드 매핑
|
||||
|
||||
| 코드 | 의미 | 대응 |
|
||||
|------|------|------|
|
||||
| -11101 | 사업자번호 미설정/유효하지 않음 | 회원사 정보 확인 |
|
||||
| -11102 | CERTKEY 유효하지 않음 | 테스트/운영 키 확인 |
|
||||
| -11103 | 인증서 만료/유효하지 않음 | 공동인증서 갱신 |
|
||||
| -11104 | 미등록 사업자 | 회원사 등록 먼저 |
|
||||
| -11105 | 이미 등록된 사업자 | 중복 등록 방지 |
|
||||
| -26001 | 공동인증서 미등록 | 인증서 등록 안내 |
|
||||
| -32001 | 사업자번호 형식 오류 | 10자리 숫자 확인 |
|
||||
| -32010 | 이미 등록된 사업자번호 | 기존 회원 확인 |
|
||||
| -32011 | 이미 등록된 아이디 | 다른 아이디 사용 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 서비스 이관 계획
|
||||
|
||||
### 9.1 이관 범위
|
||||
|
||||
| 기능 | MNG (현재) | API 이관 | React 이관 | 우선순위 |
|
||||
|------|:---------:|:-------:|:---------:|:-------:|
|
||||
| SOAP 연동 서비스 | ✅ | 🔴 필수 | — | P1 |
|
||||
| 회원사 등록/관리 | ✅ | 🔴 필수 | 🔴 필수 | P1 |
|
||||
| 테스트/운영 모드 전환 | ✅ | 🔴 필수 | 🟡 관리자 | P1 |
|
||||
| 카드 거래 동기화 | ✅ | 🟡 중요 | ✅ 완료 | P2 |
|
||||
| 은행 거래 동기화 | ✅ | 🟡 중요 | — | P2 |
|
||||
| 홈택스 동기화 | ✅ | 🟡 중요 | — | P2 |
|
||||
| 세금계산서 발행 | ✅ | 🟡 중요 | 🟡 중요 | P2 |
|
||||
| 과금 시스템 | ✅ | 🟢 권장 | 🟢 권장 | P3 |
|
||||
| 카카오톡/SMS | ✅ | 🟢 권장 | — | P3 |
|
||||
|
||||
### 9.2 이관 시 핵심 과제
|
||||
|
||||
1. **SOAP 서비스 이관**: MNG의 `BarobillService` (1,761줄)를 API로 이동
|
||||
2. **멀티테넌트 CERTKEY**: 테넌트별로 바로빌 파트너 계약이 필요한지, 공용 CERTKEY로 처리 가능한지 확인
|
||||
3. **테스트 모드 관리**: 신규 테넌트는 테스트 모드로 시작 → 관리자가 운영 모드로 전환
|
||||
4. **동기화 스케줄러**: MNG에서 실행 중인 은행/카드/홈택스 동기화를 API Queue로 이관
|
||||
5. **인증서 관리**: 공동인증서 등록 URL을 테넌트 사용자에게 제공하는 플로우
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
| 문서 | 설명 |
|
||||
|------|------|
|
||||
| [테넌트 온보딩](./tenant-onboarding.md) | 온보딩 개념 정의, 테스트→운영 전환 프로세스 |
|
||||
| [바로빌 API 명세](../../frontend/api-specs/barobill-api.md) | 카드/은행/홈택스 REST API 42개 엔드포인트 |
|
||||
| [바로빌 회원 마이그레이션](../../dev/guides/barobill-members-migration.md) | 회원 데이터 이관 가이드 |
|
||||
| [바로빌 카카오톡](../barobill-kakaotalk/README.md) | 카카오톡 알림톡 연동 |
|
||||
| [재무관리](../finance/README.md) | 재무/자금관리 전체 개요 |
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-17
|
||||
190
features/barobill/tenant-onboarding.md
Normal file
190
features/barobill/tenant-onboarding.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# 바로빌 테넌트 온보딩 프로세스
|
||||
|
||||
> **작성일**: 2026-03-17
|
||||
> **상태**: 설계 중 (서비스 이관 준비)
|
||||
|
||||
---
|
||||
|
||||
## 1. 온보딩(Onboarding)이란
|
||||
|
||||
### 1.1 정의
|
||||
|
||||
**온보딩**: 새로운 고객(테넌트)이 서비스에 가입하여 실제 사용을 시작하기까지의 초기 설정 과정.
|
||||
|
||||
SAM 바로빌 맥락에서는 **정식 계약 고객이 바로빌 연동 기능(계좌조회, 카드내역, 세금계산서 등)을 실무에서 사용할 수 있도록 초기 세팅하는 일련의 절차**를 의미한다.
|
||||
|
||||
### 1.2 온보딩 vs 베타테스트
|
||||
|
||||
| 구분 | 온보딩 | 베타테스트 |
|
||||
|------|--------|----------|
|
||||
| **대상** | 정식 계약 고객 | 서비스 출시 전 검증 참여자 |
|
||||
| **목적** | 고객이 기능을 쓸 수 있게 초기 세팅 | 서비스 안정성/기능 검증 |
|
||||
| **시점** | 고객 가입할 때마다 반복 발생 | 서비스 출시 전 1회성 |
|
||||
| **테스트 모드** | 초기 세팅 확인용으로 잠깐 사용 가능 | 전체 기간 테스트 모드로 운영 |
|
||||
| **데이터** | 실제 업무 데이터 | 검증용 테스트 데이터 |
|
||||
| **과금** | 정식 과금 (운영 모드 전환 후) | 무과금 |
|
||||
|
||||
### 1.3 단계별 관계
|
||||
|
||||
서비스 이관 완료 후 다음 순서로 진행한다:
|
||||
|
||||
```
|
||||
서비스 이관 (개발)
|
||||
└─ 베타테스트 (출시 전 검증)
|
||||
└─ 정식 출시
|
||||
└─ 테넌트 온보딩 (고객 가입 시마다 반복)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 바로빌 온보딩 전체 흐름
|
||||
|
||||
### 2.1 단계별 프로세스
|
||||
|
||||
```
|
||||
Phase 1: 테넌트 계약
|
||||
┌──────────────────────────────────────────┐
|
||||
│ 고객사 SAM 서비스 계약 체결 │
|
||||
│ └─ SAM 테넌트 생성 (tenant_id 발급) │
|
||||
│ └─ 바로빌 서비스 이용 여부 확인 │
|
||||
└──────────────────────┬───────────────────┘
|
||||
▼
|
||||
Phase 2: 바로빌 회원 등록 (테스트 모드)
|
||||
┌──────────────────────────────────────────┐
|
||||
│ 바로빌 회원사 등록 (BarobillService) │
|
||||
│ ├─ 사업자번호, 상호, 대표자 등록 │
|
||||
│ ├─ 바로빌 ID/PW 생성 │
|
||||
│ ├─ server_mode = 'test' (기본값) │
|
||||
│ └─ 테스트 서버에서 연동 확인 │
|
||||
└──────────────────────┬───────────────────┘
|
||||
▼
|
||||
Phase 3: 인증서 및 계좌/카드 연결
|
||||
┌──────────────────────────────────────────┐
|
||||
│ 공동인증서 등록 │
|
||||
│ ├─ getCertificateRegistUrl() → 고객 직접│
|
||||
│ ├─ 인증서 유효성 확인 │
|
||||
│ └─ 인증서 만료일 모니터링 설정 │
|
||||
│ │
|
||||
│ 계좌 연결 │
|
||||
│ ├─ getBankAccountScrapRequestUrl() │
|
||||
│ └─ 고객이 직접 계좌 등록 │
|
||||
│ │
|
||||
│ 카드 연결 │
|
||||
│ ├─ registCard() │
|
||||
│ └─ 카드사별 등록 │
|
||||
└──────────────────────┬───────────────────┘
|
||||
▼
|
||||
Phase 4: 연동 검증
|
||||
┌──────────────────────────────────────────┐
|
||||
│ 테스트 모드에서 기능 확인 │
|
||||
│ ├─ 계좌 입출금 내역 조회 확인 │
|
||||
│ ├─ 카드 사용내역 조회 확인 │
|
||||
│ ├─ 홈택스 세금계산서 수집 확인 │
|
||||
│ └─ 문제 없으면 다음 단계 │
|
||||
└──────────────────────┬───────────────────┘
|
||||
▼
|
||||
Phase 5: 운영 모드 전환
|
||||
┌──────────────────────────────────────────┐
|
||||
│ 관리자가 server_mode → 'production' 전환 │
|
||||
│ ├─ 운영 CERTKEY로 SOAP 재연결 │
|
||||
│ ├─ 실제 데이터 수집 시작 │
|
||||
│ └─ 과금 시작 (구독 등록) │
|
||||
└──────────────────────┬───────────────────┘
|
||||
▼
|
||||
Phase 6: 실무 사용 시작
|
||||
┌──────────────────────────────────────────┐
|
||||
│ 정기 동기화 스케줄러 활성화 │
|
||||
│ ├─ 은행 거래 자동 수집 │
|
||||
│ ├─ 카드 내역 자동 수집 │
|
||||
│ ├─ 홈택스 세금계산서 자동 수집 │
|
||||
│ └─ 월정액 과금 자동 처리 │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 역할 분담
|
||||
|
||||
| 단계 | 수행 주체 | 설명 |
|
||||
|------|----------|------|
|
||||
| 테넌트 생성 | SAM 관리자 | MNG에서 테넌트 생성 |
|
||||
| 회원사 등록 | SAM 관리자 또는 고객 | 사업자 정보 입력 |
|
||||
| 인증서 등록 | **고객 직접** | 바로빌 제공 URL에서 직접 등록 |
|
||||
| 계좌/카드 등록 | **고객 직접** | 바로빌 제공 URL에서 직접 등록 |
|
||||
| 연동 검증 | SAM 관리자 | 테스트 모드에서 데이터 수집 확인 |
|
||||
| 운영 전환 | SAM 관리자 | `server_mode` 변경 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 테스트 모드 활용
|
||||
|
||||
### 3.1 온보딩에서의 테스트 모드 역할
|
||||
|
||||
테스트 모드는 **온보딩 Phase 2~4에서 연동을 검증**하기 위해 사용한다.
|
||||
|
||||
```
|
||||
✅ 바로빌 회원 등록이 정상적으로 되는지 확인
|
||||
✅ 인증서/계좌/카드 연결이 작동하는지 확인
|
||||
✅ API 호출이 정상 응답하는지 확인
|
||||
❌ 실제 세금계산서 발행 (국세청 미전송)
|
||||
❌ 실제 거래 데이터 수집 (테스트 데이터만)
|
||||
```
|
||||
|
||||
### 3.2 테스트 모드 체크리스트
|
||||
|
||||
Phase 4 (연동 검증) 완료 기준:
|
||||
|
||||
- [ ] 바로빌 회원 상태: `active`
|
||||
- [ ] 공동인증서: 등록됨 + 유효기간 확인
|
||||
- [ ] 계좌: 1개 이상 등록, 입출금 조회 응답 정상
|
||||
- [ ] 카드: 1개 이상 등록, 사용내역 조회 응답 정상
|
||||
- [ ] 홈택스: 매출/매입 세금계산서 수집 응답 정상
|
||||
- [ ] 에러 없이 모든 API 호출 성공
|
||||
|
||||
### 3.3 운영 전환 체크리스트
|
||||
|
||||
Phase 5 (운영 모드 전환) 전 확인:
|
||||
|
||||
- [ ] 테스트 모드 검증 완료
|
||||
- [ ] 고객 동의 (실제 과금 시작 안내)
|
||||
- [ ] 운영 CERTKEY 설정 확인
|
||||
- [ ] 구독 등록 (월정액 과금 설정)
|
||||
- [ ] `server_mode` → `production` 전환
|
||||
- [ ] 운영 모드에서 첫 데이터 수집 성공 확인
|
||||
|
||||
---
|
||||
|
||||
## 4. 개발 시 주의사항
|
||||
|
||||
### 4.1 개발 단계에서의 테스트 모드
|
||||
|
||||
온보딩 프로세스와 별개로, **서비스 이관 개발 중에는 항상 테스트 모드를 사용**한다.
|
||||
|
||||
| 단계 | 모드 | 이유 |
|
||||
|------|------|------|
|
||||
| 서비스 이관 개발 | 테스트 | 코드 검증, 무과금 |
|
||||
| 베타테스트 | 테스트 | 실사용 시나리오 검증, 무과금 |
|
||||
| 고객 온보딩 Phase 2~4 | 테스트 | 연동 설정 확인, 무과금 |
|
||||
| 고객 온보딩 Phase 5~ | **운영** | 실무 사용, 과금 시작 |
|
||||
|
||||
### 4.2 서비스 이관 완료 후 출시 순서
|
||||
|
||||
```
|
||||
1. 서비스 이관 개발 완료 (테스트 모드)
|
||||
2. 내부 베타테스트 (tenant_id=1, 코드브릿지엑스, 테스트 모드)
|
||||
3. 외부 베타테스트 (선별 고객 2~3곳, 테스트 모드)
|
||||
4. 정식 출시
|
||||
5. 신규 고객 온보딩 프로세스 가동 (반복)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
| 문서 | 설명 |
|
||||
|------|------|
|
||||
| [바로빌 연동 시스템](./README.md) | 전체 구조, 테스트/운영 모드, 과금 정책 |
|
||||
| [바로빌 API 명세](../../frontend/api-specs/barobill-api.md) | REST API 42개 엔드포인트 |
|
||||
| [데모 테넌트 정책](../sales/demo-tenant-policy.md) | 영업파트너 데모 테넌트 3-Tier 전략 |
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-17
|
||||
@@ -20,6 +20,7 @@ R&D 메뉴는 SAM 플랫폼의 **연구개발 및 내부 도구** 모음이다.
|
||||
| **README.md** (이 문서) | 전체 개요, 메뉴 구조, 컨트롤러 매핑 |
|
||||
| [planning-design.md](planning-design.md) | 기획디자인 스토리보드 에디터 기술 명세 |
|
||||
| [design-insight.md](design-insight.md) | 디자인 인사이트 UI/UX 연구 도구 (100종 패턴, AI 프롬프트) |
|
||||
| [fire-shutter-drawing-guide-rail.md](fire-shutter-drawing-guide-rail.md) | 방화셔터 도면 가이드레일 SVG/3D 렌더링 |
|
||||
|
||||
### 1.3 하위 메뉴 구조
|
||||
|
||||
@@ -35,7 +36,8 @@ R&D
|
||||
│ ├── 편집 /rd/ai-quotation/{id}/edit
|
||||
│ └── 문서 /rd/ai-quotation/{id}/document
|
||||
├── 기획디자인 /rd/planning-design
|
||||
└── 디자인 인사이트 /rd/design-insight
|
||||
├── 디자인 인사이트 /rd/design-insight
|
||||
└── 방화셔터 도면 /rd/fire-shutter-drawing
|
||||
```
|
||||
|
||||
---
|
||||
@@ -96,6 +98,7 @@ if ($request->header('HX-Request')) {
|
||||
| AI 견적 | Blade + Alpine.js | AiQuotationService | ai_quotations | 운영 중 |
|
||||
| **기획디자인** | **Blade + Alpine.js (SPA)** | **없음 (localStorage)** | **없음** | **운영 중** |
|
||||
| **디자인 인사이트** | **Blade + Alpine.js (SPA)** | **없음 (localStorage)** | **없음** | **운영 중** |
|
||||
| **방화셔터 도면** | **Blade + JS (SVG/Three.js)** | **RdController** | **없음** | **운영 중** |
|
||||
|
||||
---
|
||||
|
||||
@@ -103,6 +106,7 @@ if ($request->header('HX-Request')) {
|
||||
|
||||
- [기획디자인 스토리보드 에디터](planning-design.md) — 블록 에디터, 서식, 인쇄, 내보내기
|
||||
- [디자인 인사이트](design-insight.md) — UI/UX 연구 도구 (100종 패턴, AI 프롬프트 복사)
|
||||
- [방화셔터 도면 가이드레일](fire-shutter-drawing-guide-rail.md) — 가이드레일 SVG/3D 렌더링 기술 명세
|
||||
- [조직도 관리 기술문서](../../projects/org-chart/) — 조직도 시스템 상세 (별도 프로젝트 문서)
|
||||
|
||||
---
|
||||
|
||||
203
features/rd/fire-shutter-drawing-guide-rail.md
Normal file
203
features/rd/fire-shutter-drawing-guide-rail.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# 방화셔터 도면 — 가이드레일 렌더링
|
||||
|
||||
> **작성일**: 2026-03-16
|
||||
> **상태**: 운영 중
|
||||
> **파일**: `mng/resources/views/rd/fire-shutter-drawing/index.blade.php`
|
||||
> **라우트**: `GET /rd/fire-shutter-drawing`
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
|
||||
방화셔터 가이드레일의 **2D 평면도(SVG)**와 **3D 렌더링(Three.js)**을 구현한다.
|
||||
제품 유형(스크린형/철재스라트)에 따라 다른 프로파일을 렌더링하며, 각 부재(마감재, 본체, C형, 벽연형)의 절곡 치수를 시각화한다.
|
||||
|
||||
### 1.2 제품 유형별 차이
|
||||
|
||||
| 항목 | 스크린형 | 철재스라트 |
|
||||
|------|---------|-----------|
|
||||
| 본체 형상 | C채널 (lip-flange-sideWall-backWall) | 15세그먼트 절곡 프로파일 |
|
||||
| 마감재 절곡 | 10-11-110-30-15-15-15 (J-hook) | 10-13-120-25-15 (상단) / +19-14-15 (하단) |
|
||||
| 벽연결 부재 | ③ C형 30-45-30 + ④ D형 11-23-40-23-11 | ④ 벽연형 30-45-30 |
|
||||
| 전체 치수 | depth × width (가변) | 130mm × 75mm |
|
||||
|
||||
---
|
||||
|
||||
## 2. 철재스라트 가이드레일
|
||||
|
||||
### 2.1 부재 구성
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ ① 마감재 SUS 1.2T (빨간색, 상/하 2장) │
|
||||
│ ┌────────────────────────────────────────────┐ │
|
||||
│ │ ② 본체 EGI 1.55T (회색, 15세그먼트 절곡) │ │
|
||||
│ │ ┌──────────────────────────────────────┐ │ │
|
||||
│ │ │ 개구부 (슬랫 통과 공간) │ │ │
|
||||
│ │ └──────────────────────────────────────┘ │ │
|
||||
│ └────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ④ 벽연형 EGI 1.55T (갈색, ㄷ자 30-45-30) │
|
||||
│ ■■■■■ ← 방화벽 │
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 ② 본체 절곡 프로파일 (15세그먼트)
|
||||
|
||||
정석 도면 기준, 시작점 `(0, 60)`:
|
||||
|
||||
| Seg | 방향 | 치수(mm) | 좌표 | 설명 |
|
||||
|-----|------|---------|------|------|
|
||||
| 1 | 10→ | 10 | (0,60)→(10,60) | 좌측 립 |
|
||||
| 2 | 60↑ | 60 | (0,60)→(0,0) | 좌측벽 상부 |
|
||||
| 3 | 90→ | 90 | (0,0)→(90,0) | 상단 플랜지 |
|
||||
| 4 | 21↓ | 21 | (90,0)→(90,21) | 상부 립 |
|
||||
| 5 | 78← | 78 | (90,21)→(12,21) | **상부 내부 선반 (넓은)** |
|
||||
| 6 | 30↓ | 30 | (12,21)→(12,51) | 내부 벽 |
|
||||
| 7 | 43→ | 43 | (12,51)→(55,51) | **하부 내부 선반** |
|
||||
| 8 | 15↓ | 15 | (55,51)→(55,66) | 스텝 하강 |
|
||||
| 9 | 20→ | 20 | (55,66)→(75,66) | 스텝 수평 |
|
||||
| 10 | 15↑ | 15 | (75,66)→(75,51) | 스텝 상승 |
|
||||
| 11 | 15→ | 15 | (75,51)→(90,51) | 스텝 수평 |
|
||||
| 12 | 21↓ | 21 | (90,51)→(90,72) | 하부 립 |
|
||||
| 13 | 90← | 90 | (90,72)→(0,72) | 하단 플랜지 |
|
||||
| 14 | 12↑ | 12 | (0,72)→(0,60) | 좌측벽 하부 |
|
||||
| 15 | 10→ | 10 | (0,60)→(10,60) | 립 (Seg1과 겹침) |
|
||||
|
||||
> **핵심**: 내부 개구부(스텝 구조)가 **하부**(y=51~66)에 위치한다. 상부(y=21)에는 넓은 78mm 선반, 하부에는 43mm 선반 + 15-20-15-15 스텝이 배치된다.
|
||||
|
||||
### 2.3 ① 마감재 절곡 (SUS 1.2T)
|
||||
|
||||
**상단**: `10←lip + 13↓tab + 120→body + 25↓ + 15←`
|
||||
**하단**: `10←lip + 13↑tab + 120→body + 25↑ + 19← + 14↓ + 15←`
|
||||
|
||||
### 2.4 ④ 벽연형 (EGI 1.55T)
|
||||
|
||||
ㄷ자 형태: `30(깊이) × 45(높이)`, 우측 열림. 본체 좌측에 위치, 세로 중앙 정렬.
|
||||
|
||||
---
|
||||
|
||||
## 3. 2D 평면도 (SVG) 구현
|
||||
|
||||
### 3.1 좌표계
|
||||
|
||||
```
|
||||
X축: 깊이 (LEFT=벽/방화벽 → RIGHT=개구부/실내)
|
||||
Y축: 높이 (TOP → BOTTOM)
|
||||
스케일: sc = 4 (1mm = 4px)
|
||||
```
|
||||
|
||||
### 3.2 본체 위치 계산
|
||||
|
||||
```javascript
|
||||
const ox2 = w4x + w4depth + (7 + 0.75) * sc;
|
||||
// ④ 벽연형 끝에서 7mm + 반두께(0.75mm) 간격
|
||||
```
|
||||
|
||||
### 3.3 색상 체계
|
||||
|
||||
| 부재 | 색상 | HEX |
|
||||
|------|------|-----|
|
||||
| ② 본체 EGI | 회색 | `#4b5563` (fill) / `#94a3b8` (stroke) |
|
||||
| ① 마감재 SUS | 빨간색 | `#ef4444` |
|
||||
| ④ 벽연형 EGI | 갈색 | `#8b6c5c` |
|
||||
|
||||
### 3.4 치수 라벨
|
||||
|
||||
각 부재의 절곡 치수를 **해당 부재 색상**으로 표시한다:
|
||||
- ② 본체: 회색(`#94a3b8`)으로 14개 세그먼트 치수
|
||||
- ① 마감재: 빨간색(`#ef4444`)으로 상/하단 각 7개 치수
|
||||
- ④ 벽연형: 갈색(`#8b6c5c`)으로 30 × 45
|
||||
|
||||
---
|
||||
|
||||
## 4. 3D 렌더링 (Three.js) 구현
|
||||
|
||||
### 4.1 좌표계 매핑
|
||||
|
||||
```
|
||||
2D 평면도 → 3D Shape (ExtrudeGeometry)
|
||||
──────────────────────────────────────────────
|
||||
plan_y (높이 0→72) → X (0 → rw=75, 중앙 정렬)
|
||||
plan_x (깊이 0→90) → Y (반전: Y = bYO + 90 - plan_x)
|
||||
Y=0: 개구부/실내, Y=rd: 벽
|
||||
```
|
||||
|
||||
### 4.2 본체 세그먼트 변환 헬퍼
|
||||
|
||||
```javascript
|
||||
function bSeg(px, py, pw, ph) {
|
||||
// 평면도 좌표 (px, py, pw, ph) → THREE.Shape 좌표
|
||||
const x1 = bXO + py, x2 = bXO + py + ph;
|
||||
const y1 = bYO + 90 - px - pw, y2 = bYO + 90 - px;
|
||||
const s = new THREE.Shape();
|
||||
s.moveTo(x1,y1); s.lineTo(x2,y1);
|
||||
s.lineTo(x2,y2); s.lineTo(x1,y2); s.lineTo(x1,y1);
|
||||
return s;
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 재질
|
||||
|
||||
| 부재 | Material | 속성 |
|
||||
|------|----------|------|
|
||||
| ② 본체 / ④ 벽연형 | `MeshStandardMaterial` | color: `0x64748b`, metalness: 0.5, roughness: 0.4 |
|
||||
| ① 마감재 SUS | `MeshStandardMaterial` | color: `0x9ca3af`, metalness: 0.7, roughness: 0.25 |
|
||||
|
||||
### 4.4 배치
|
||||
|
||||
```javascript
|
||||
// 좌측 레일: 셔터 중심에서 -hw 위치
|
||||
railGroupL.position.set(-hw - rw/2, 0, rd/2);
|
||||
// 우측 레일: scale.x = -1 (좌우 반전)
|
||||
railGroupR.position.set(hw + rw/2, 0, rd/2);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 스크린형 가이드레일
|
||||
|
||||
### 5.1 부재 구성
|
||||
|
||||
| 부재 | 색상 | 절곡 치수 |
|
||||
|------|------|----------|
|
||||
| ② 가이드레일 EGI | 파란색 `#3b82f6` | lip-flange-sideWall-backWall (가변) |
|
||||
| ① 마감재 SUS | 빨간색 `#ef4444` | 10-11-110-30-15-15-15 (J-hook) |
|
||||
| ③ C형 EGI | 초록색 `#22c55e` | 30-45-30 |
|
||||
| ④ D형 EGI | 주황색 `#f97316` | 11-23-40-23-11 |
|
||||
|
||||
### 5.2 치수 라벨
|
||||
|
||||
각 부재 색상에 맞춰 모든 절곡 치수를 `font-size="7"` 라벨로 표시한다.
|
||||
|
||||
---
|
||||
|
||||
## 6. 소스 코드 위치
|
||||
|
||||
| 함수/섹션 | 줄 번호 (대략) | 설명 |
|
||||
|----------|-------------|------|
|
||||
| 스크린형 2D 평면도 | ~830~1055 | SVG 렌더링 (bodySvg, bk3Svg, bk4Svg, trim1Svg) |
|
||||
| 철재스라트 2D 평면도 | ~1058~1320 | SVG 렌더링 (② 본체 15세그먼트, ①, ④) |
|
||||
| `renderGrFront()` | ~1330 | 정면도 SVG |
|
||||
| `createRailGroup()` | ~2639 | 3D 가이드레일 생성 (스크린/철재 분기) |
|
||||
| 철재 3D 프로파일 | ~2795~2816 | `bSeg()` 헬퍼로 15세그먼트 + ④ + ① |
|
||||
|
||||
---
|
||||
|
||||
## 7. 참조 자료
|
||||
|
||||
- 정석 도면: 가이드레일 본체 (EGI 1.55mm) 절곡도
|
||||
- 치수: 90(상단) - 21(상부립) - 78(선반) - 30(내부벽) - 43(선반) - 15-20-15-15(스텝) - 21(하부립) - 90(하단) - 12(좌측하) - 10(립) - 60(좌측상)
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [R&D 메뉴 README](README.md) — R&D 전체 메뉴 구조
|
||||
- [기획디자인 스토리보드](planning-design.md) — 블록 에디터
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-16
|
||||
@@ -101,7 +101,6 @@
|
||||
| 사용자 초대 | ✅ | 최대 5명 |
|
||||
| 리포트/통계 | ✅ | 제한 없음 |
|
||||
| 바로빌 연동 | ❌ | 실제 금융 연동 차단 |
|
||||
| 이카운트 연동 | ❌ | 외부 시스템 연동 차단 |
|
||||
| 파일 저장 | ✅ | 최대 1GB |
|
||||
| AI 토큰 | ✅ | 월 10만 토큰 |
|
||||
|
||||
@@ -184,7 +183,7 @@ class DemoLimitMiddleware
|
||||
// 2. 수량 제한 체크
|
||||
$limits = $tenant->demo_limits;
|
||||
|
||||
// 3. 금지 기능 체크 (바로빌, 이카운트 등)
|
||||
// 3. 금지 기능 체크 (바로빌 등 외부 연동)
|
||||
if ($this->isBlockedFeature($request)) {
|
||||
return response()->json(['error' => '데모에서 사용할 수 없는 기능입니다.'], 403);
|
||||
}
|
||||
@@ -226,7 +225,7 @@ class DemoDataSeeder
|
||||
3. demo_expires_at = NULL
|
||||
4. subscription → status='active', plan='starter'/'business'
|
||||
5. 기존 데이터 유지 (마이그레이션 불필요)
|
||||
6. 추가 기능 활성화 (바로빌, 이카운트 등)
|
||||
6. 추가 기능 활성화 (바로빌 등 외부 연동)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -141,7 +141,7 @@ POST /api/v1/demo-tenants/{id}/convert
|
||||
|------|---------|---------|
|
||||
| 테넌트 유형 | `DEMO_TRIAL` | `STD` (정식) |
|
||||
| 만료일 | 30일 제한 | 제한 없음 |
|
||||
| 기능 제한 | 바로빌/이카운트 차단 | 전체 기능 사용 |
|
||||
| 기능 제한 | 바로빌 등 외부 연동 차단 | 전체 기능 사용 |
|
||||
| 데이터 | 그대로 유지 | 그대로 유지 |
|
||||
|
||||
> 고객이 체험 중 입력한 데이터가 정식 환경에 그대로 이어진다. 데이터 재입력이 불필요하다.
|
||||
@@ -290,7 +290,7 @@ php artisan demo:check-inactive --days=3
|
||||
```
|
||||
1. POST /{id}/convert 로 정식 전환
|
||||
2. 고객 데이터는 그대로 유지됨 (재입력 불필요)
|
||||
3. 바로빌, 이카운트 등 외부 연동 기능 활성화
|
||||
3. 바로빌 등 외부 연동 기능 활성화
|
||||
```
|
||||
|
||||
### 7.4 체험 기간 부족 시
|
||||
|
||||
168
features/sales/stock-production.md
Normal file
168
features/sales/stock-production.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# 재고생산관리
|
||||
|
||||
> **작성일**: 2026-03-16
|
||||
> **상태**: 설계 확정
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
|
||||
수주 없이 **재고 목적으로 생산**하는 경우를 관리하는 기능이다.
|
||||
|
||||
SAM 시스템은 `수주 → 작업지시 → 생산`의 흐름으로 동작하므로, 수주가 없으면 작업지시를 생성할 수 없다. 재고생산관리는 **내부 오더(Internal Order)** 개념으로, 재고생산도 일종의 수주로 취급하여 기존 생산 흐름을 그대로 활용한다.
|
||||
|
||||
### 1.2 핵심 원칙
|
||||
|
||||
- 기존 `orders` 테이블을 **공유**한다 (별도 테이블 없음)
|
||||
- `order_type_code = 'STOCK'`으로 일반 수주(`ORDER`)와 구분한다
|
||||
- 하류 시스템(작업지시, 생산, 출하, 품질검사)은 **변경 없이 동작**한다
|
||||
- 화면은 수주관리를 **단순화**한 형태이다
|
||||
|
||||
---
|
||||
|
||||
## 2. 수주관리와의 관계
|
||||
|
||||
### 2.1 테이블 공유 구조
|
||||
|
||||
```
|
||||
orders 테이블
|
||||
├── order_type_code = 'ORDER' → 수주관리 (거래처 주문)
|
||||
├── order_type_code = 'PURCHASE' → 발주관리
|
||||
└── order_type_code = 'STOCK' → 재고생산관리 (내부 오더)
|
||||
```
|
||||
|
||||
### 2.2 기능 비교
|
||||
|
||||
| 항목 | 수주관리 (ORDER) | 재고생산관리 (STOCK) |
|
||||
|------|-----------------|---------------------|
|
||||
| 거래처 | ✅ 필수 | ❌ 불필요 |
|
||||
| 견적 연결 | ✅ 가능 | ❌ 불필요 |
|
||||
| 현장/납기/배송 | ✅ 사용 | ❌ 불필요 |
|
||||
| 할인 | ✅ 적용 | ❌ 불필요 |
|
||||
| 금액 계산 | ✅ 자동 | ❌ 불필요 (단가 0 가능) |
|
||||
| 매출 인식 | ✅ 자동/수동 | ❌ 생성 안 함 |
|
||||
| 개소/구역 (OrderNode) | ✅ N-depth 트리 | ❌ 불필요 |
|
||||
| 품목 등록 | ✅ 상세 | ✅ 품목 + 수량만 |
|
||||
| 작업지시 생성 | ✅ 동일 | ✅ 동일 |
|
||||
| 생산/출하/품질검사 | ✅ 동일 | ✅ 동일 |
|
||||
| 채번 접두사 | `ORD` | `STK` |
|
||||
|
||||
### 2.3 재고생산 전용 필드
|
||||
|
||||
`orders.options` JSON에 재고생산 전용 속성을 저장한다:
|
||||
|
||||
| 필드 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| `production_reason` | string | 생산 사유 (예: "시즌 대비", "안전재고 확보") |
|
||||
| `target_stock_qty` | number | 목표 재고 수량 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 업무 흐름
|
||||
|
||||
```
|
||||
재고생산 등록 (DRAFT)
|
||||
│ order_type_code = 'STOCK'
|
||||
│ 품목 + 수량만 입력
|
||||
↓
|
||||
재고생산 확정 (CONFIRMED)
|
||||
│ ※ 매출 생성 안 함 (일반 수주와 차이)
|
||||
↓
|
||||
생산지시 생성 (WorkOrder)
|
||||
│ 기존 수주→생산지시 흐름 동일
|
||||
↓
|
||||
생산 실행 → 품질검사 → 출하
|
||||
│ 기존 생산관리 흐름 동일
|
||||
↓
|
||||
완료 (COMPLETED)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 메뉴 위치
|
||||
|
||||
```
|
||||
판매관리
|
||||
├── 거래처관리
|
||||
├── 견적관리
|
||||
├── 수주관리
|
||||
├── 재고생산관리 ← 신규
|
||||
└── 단가관리
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 재공품(WIP) 개념
|
||||
|
||||
재고생산의 대상 품목은 **재공품(Work-In-Process)**이다.
|
||||
|
||||
- 수주를 받지 않았지만, 회사 내에서 **이미 정해진 절곡품**을 미리 생산
|
||||
- 작업자들의 **유휴시간에 앞으로 나갈 물건을 미리 제작**하는 행위
|
||||
- 실제 수주가 들어오면 이미 만들어둔 재공품을 사용하여 **납기 단축**
|
||||
|
||||
```
|
||||
유휴시간 → 재공품 미리 생산 → 재고 적재
|
||||
↓
|
||||
실제 수주 → 재고에서 재공품 사용 → 납기 단축
|
||||
```
|
||||
|
||||
### 5.1 현재 구현 범위 (Phase 1)
|
||||
|
||||
- ✅ 재고생산 등록/목록/상세/수정/삭제
|
||||
- ✅ 생산지시 생성 (절곡 공정 자동 선택)
|
||||
- ✅ 생산지시 목록에 표시
|
||||
- ✅ 작업지시 목록에 표시
|
||||
- ✅ 생산현황판에 표시
|
||||
- ✅ 작업실적 조회에 표시
|
||||
|
||||
### 5.2 향후 과제 (Phase 2)
|
||||
|
||||
> **작업자 화면 절곡 탭 — 재공품 사양 정보 연동**
|
||||
|
||||
현재 STOCK 건은 OrderNode(개소)가 없어 BendingInfoBuilder가 동작하지 않는다.
|
||||
절곡 작업자 화면에서 다음 정보가 누락된다:
|
||||
|
||||
| 누락 정보 | 원인 | 해결 방향 |
|
||||
|----------|------|----------|
|
||||
| W/H (가로/세로) | OrderNode.options 없음 | 품목 마스터에 규격 정보 보유 → 등록 시 가져오기 |
|
||||
| bending_info | BendingInfoBuilder 실패 (rootNodes 없음) | 품목별 표준 BOM 활용 또는 수동 입력 |
|
||||
| 동적 자재 목록 | dynamic_bom 미생성 | 품목별 표준 BOM에서 자재 목록 생성 |
|
||||
| 제품코드 | nodeOptions 없음 | 품목 마스터의 item_code 활용 |
|
||||
|
||||
**해결 전략**: 재공품은 이미 정해진 규격품이므로, 품목관리의 품목 정보(규격, BOM)를
|
||||
재고생산 등록 시 `work_order_item.options`에 채워넣는 방식으로 해결 가능.
|
||||
|
||||
---
|
||||
|
||||
## 6. API
|
||||
|
||||
기존 수주관리 API를 그대로 사용한다. `order_type=STOCK` 파라미터로 필터링한다.
|
||||
|
||||
> **상세 API 명세**: `frontend/api-specs/stock-production-api.md`
|
||||
|
||||
---
|
||||
|
||||
## 7. 영향범위 검토 결과
|
||||
|
||||
| 메뉴 | 수정 필요 | 비고 |
|
||||
|------|:--------:|------|
|
||||
| 재고생산관리 (신규) | ✅ React 구현 | 수주 화면 단순화 |
|
||||
| 생산지시 목록 | ⚠️ 소규모 | 납기/거래처 `-` 표시 (프론트) |
|
||||
| 생산현황판 | ❌ 없음 | project_name='재고생산' 정상 표시 |
|
||||
| 작업지시 목록 | ❌ 없음 | null fallback 처리 완비 |
|
||||
| 작업실적 조회 | ❌ 없음 | Order 정보 미참조 |
|
||||
| 작업자 화면 (절곡) | ⚠️ Phase 2 | bending_info/W/H 누락 (향후 과제) |
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [재고생산관리 API 명세](../../frontend/api-specs/stock-production-api.md)
|
||||
- [수주 DB 스키마](../../system/database/sales.md)
|
||||
- [생산 DB 스키마](../../system/database/production.md)
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-16
|
||||
369
frontend/api-specs/stock-production-api.md
Normal file
369
frontend/api-specs/stock-production-api.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# 재고생산관리 API 명세
|
||||
|
||||
> **작성일**: 2026-03-16
|
||||
> **상태**: 설계 확정
|
||||
> **대상**: React 프론트엔드 개발자
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
|
||||
재고생산관리는 **수주 없이 재고 목적으로 생산**하는 경우를 위한 기능이다.
|
||||
기존 수주관리(Order) API를 **그대로 사용**하되, `order_type_code: 'STOCK'`으로 구분한다.
|
||||
|
||||
### 1.2 핵심 원칙
|
||||
|
||||
- 별도 API 엔드포인트 없음 — 기존 `/api/v1/orders` 사용
|
||||
- `order_type_code` 필터로 수주(`ORDER`)와 재고생산(`STOCK`)을 분리
|
||||
- 화면은 수주관리를 **단순화**한 형태 (거래처, 견적, 배송, 할인 등 불필요)
|
||||
- 하류 시스템(작업지시, 생산, 출하)은 **동일하게 동작**
|
||||
|
||||
---
|
||||
|
||||
## 2. API 엔드포인트
|
||||
|
||||
> **기본 URL**: `/api/v1/orders`
|
||||
> **인증**: `Bearer Token` (Sanctum) + `API Key`
|
||||
|
||||
### 2.1 목록 조회
|
||||
|
||||
```
|
||||
GET /api/v1/orders?order_type=STOCK
|
||||
```
|
||||
|
||||
| 파라미터 | 타입 | 필수 | 설명 |
|
||||
|----------|------|:----:|------|
|
||||
| `order_type` | string | ✅ | `STOCK` 고정 |
|
||||
| `page` | int | - | 페이지 (기본: 1) |
|
||||
| `size` | int | - | 페이지 크기 (기본: 20) |
|
||||
| `q` | string | - | 검색어 (생산번호, 메모) |
|
||||
| `status` | string | - | 상태 필터 (`DRAFT`, `CONFIRMED` 등) |
|
||||
| `date_from` | date | - | 등록일 시작 |
|
||||
| `date_to` | date | - | 등록일 종료 |
|
||||
|
||||
**응답 예시**:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "message.order.fetched",
|
||||
"data": {
|
||||
"data": [
|
||||
{
|
||||
"id": 42,
|
||||
"order_no": "STK202603160001",
|
||||
"order_type_code": "STOCK",
|
||||
"status_code": "DRAFT",
|
||||
"quantity": "100.0000",
|
||||
"memo": "봄 시즌 대비 재고 확보",
|
||||
"options": {
|
||||
"production_reason": "시즌 대비",
|
||||
"target_stock_qty": 500
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"item_name": "25mm 알루미늄 블라인드",
|
||||
"specification": "W1000 x H2000",
|
||||
"quantity": "100.0000",
|
||||
"unit_price": "15000.00"
|
||||
}
|
||||
],
|
||||
"created_at": "2026-03-16T10:30:00Z"
|
||||
}
|
||||
],
|
||||
"current_page": 1,
|
||||
"last_page": 1,
|
||||
"total": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.2 통계 조회
|
||||
|
||||
```
|
||||
GET /api/v1/orders/stats?order_type=STOCK
|
||||
```
|
||||
|
||||
| 파라미터 | 타입 | 필수 | 설명 |
|
||||
|----------|------|:----:|------|
|
||||
| `order_type` | string | ✅ | `STOCK` 고정 |
|
||||
|
||||
**응답 예시**:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"total": 15,
|
||||
"draft": 3,
|
||||
"confirmed": 5,
|
||||
"in_progress": 4,
|
||||
"completed": 2,
|
||||
"cancelled": 1,
|
||||
"total_amount": 0,
|
||||
"confirmed_amount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.3 생성
|
||||
|
||||
```
|
||||
POST /api/v1/orders
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
|
||||
```json
|
||||
{
|
||||
"order_type_code": "STOCK",
|
||||
"memo": "봄 시즌 대비 재고 확보",
|
||||
"options": {
|
||||
"production_reason": "시즌 대비",
|
||||
"target_stock_qty": 500
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"item_id": 10,
|
||||
"item_name": "25mm 알루미늄 블라인드",
|
||||
"specification": "W1000 x H2000",
|
||||
"quantity": 100,
|
||||
"unit_price": 0,
|
||||
"unit": "EA"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**필수 필드**:
|
||||
|
||||
| 필드 | 타입 | 필수 | 설명 |
|
||||
|------|------|:----:|------|
|
||||
| `order_type_code` | string | ✅ | `STOCK` 고정 |
|
||||
| `items` | array | ✅ | 생산할 품목 목록 |
|
||||
| `items[].item_name` | string | ✅ | 품목명 |
|
||||
| `items[].quantity` | number | ✅ | 수량 |
|
||||
| `items[].unit_price` | number | ✅ | 단가 (재고생산은 `0` 가능) |
|
||||
|
||||
**선택 필드**:
|
||||
|
||||
| 필드 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| `memo` | string | 비고 |
|
||||
| `options.production_reason` | string | 생산 사유 |
|
||||
| `options.target_stock_qty` | number | 목표 재고 수량 |
|
||||
| `items[].item_id` | int | 품목 마스터 ID |
|
||||
| `items[].specification` | string | 규격 |
|
||||
| `items[].unit` | string | 단위 |
|
||||
|
||||
**사용하지 않는 필드** (수주 전용):
|
||||
|
||||
```
|
||||
❌ client_id, client_name, client_contact → 거래처 없음
|
||||
❌ site_name → API가 '재고생산'으로 자동 설정
|
||||
❌ quote_id → 견적 없음
|
||||
❌ delivery_date, delivery_method_code → 납기/배송 불필요
|
||||
❌ discount_rate, discount_amount → 할인 없음
|
||||
❌ sales_recognition → 매출 인식 불필요
|
||||
❌ options.shipping_cost_code → 운임비용 불필요
|
||||
❌ options.receiver, receiver_contact → 수신자 불필요
|
||||
❌ options.shipping_address → 배송지 불필요
|
||||
```
|
||||
|
||||
> **자동 생성**: `order_no`는 `STK{YYYYMMDD}{NNNN}` 형식으로 서버에서 자동 생성
|
||||
|
||||
---
|
||||
|
||||
### 2.4 단건 조회
|
||||
|
||||
```
|
||||
GET /api/v1/orders/{id}
|
||||
```
|
||||
|
||||
기존 수주 조회와 동일. `order_type_code`가 `STOCK`인지 프론트에서 확인.
|
||||
|
||||
---
|
||||
|
||||
### 2.5 수정
|
||||
|
||||
```
|
||||
PUT /api/v1/orders/{id}
|
||||
```
|
||||
|
||||
생성과 동일한 필드 사용. `order_type_code`는 변경하지 않는다.
|
||||
|
||||
---
|
||||
|
||||
### 2.6 삭제
|
||||
|
||||
```
|
||||
DELETE /api/v1/orders/{id}
|
||||
```
|
||||
|
||||
기존 수주 삭제와 동일.
|
||||
|
||||
---
|
||||
|
||||
### 2.7 상태 변경
|
||||
|
||||
```
|
||||
PATCH /api/v1/orders/{id}/status
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "CONFIRMED"
|
||||
}
|
||||
```
|
||||
|
||||
**상태 흐름** (수주와 동일):
|
||||
|
||||
```
|
||||
DRAFT → CONFIRMED → IN_PROGRESS → COMPLETED
|
||||
└─────→ CANCELLED ──→ DRAFT (복구)
|
||||
```
|
||||
|
||||
> **재고생산 특수**: `CONFIRMED` 상태 진입 시 매출 자동 생성이 **발생하지 않음**
|
||||
|
||||
---
|
||||
|
||||
### 2.8 생산지시 생성
|
||||
|
||||
```
|
||||
POST /api/v1/orders/{id}/production-order
|
||||
```
|
||||
|
||||
재고생산은 **절곡 공정이 자동 선택**된다 (API에서 처리). `process_ids` 전달 불필요.
|
||||
|
||||
```json
|
||||
{
|
||||
"priority": "normal",
|
||||
"memo": "재고생산 작업"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**API 자동 처리 항목** (STOCK 타입):
|
||||
|
||||
| 항목 | 일반 수주 | 재고생산 (자동) |
|
||||
|------|----------|---------------|
|
||||
| 현장명 (`project_name`) | `site_name` 또는 `client_name` | `'재고생산'` 고정 |
|
||||
| 공정 | BOM item_id → process_items 매칭 | **절곡 공정 자동 선택** |
|
||||
| 작업예정일 (`scheduled_date`) | `delivery_date` | **생성일 (now())** |
|
||||
| 매출 생성 | `sales_recognition` 정책 적용 | **생성 안 함** |
|
||||
|
||||
> 프론트에서 `process_ids`, `scheduled_date`를 전달하지 않아도 API가 자동 처리
|
||||
|
||||
---
|
||||
|
||||
## 3. 채번 규칙
|
||||
|
||||
| 주문 유형 | 접두사 | 예시 |
|
||||
|----------|--------|------|
|
||||
| 수주 (ORDER) | `ORD` | `ORD202603160001` |
|
||||
| 재고생산 (STOCK) | `STK` | `STK202603160001` |
|
||||
|
||||
---
|
||||
|
||||
## 4. 화면 설계 가이드
|
||||
|
||||
### 4.1 수주관리 화면 vs 재고생산관리 화면
|
||||
|
||||
```
|
||||
┌─ 수주관리 ──────────────────┐ ┌─ 재고생산관리 ───────────────┐
|
||||
│ │ │ │
|
||||
│ [거래처 정보] │ │ [생산 정보] │
|
||||
│ - 거래처 선택 │ │ - 생산 사유 (텍스트) │
|
||||
│ - 현장명 │ │ - 목표 재고 수량 │
|
||||
│ - 배송/납기일 │ │ - 비고 │
|
||||
│ - 운임비용 │ │ │
|
||||
│ - 견적 연결 │ ├──────────────────────────────┤
|
||||
│ - 할인 │ │ [품목 목록] │
|
||||
│ - 매출 인식 방식 │ │ - 품목 선택 │
|
||||
│ │ │ - 수량 │
|
||||
│ [개소/구역 (OrderNode)] │ │ - 규격 │
|
||||
│ - N-depth 트리 구조 │ │ │
|
||||
│ │ │ (단가/금액/할인 불필요) │
|
||||
│ [품목 목록] │ │ (개소/구역 불필요) │
|
||||
│ - 품목, 수량, 단가, 할인 │ │ │
|
||||
│ - floor_code, symbol_code │ └──────────────────────────────┘
|
||||
│ - 금액 계산 │
|
||||
│ │
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.2 목록 페이지 표시 컬럼
|
||||
|
||||
| 컬럼 | 설명 |
|
||||
|------|------|
|
||||
| 생산번호 | `order_no` (STK...) |
|
||||
| 상태 | `status_code` (상태 배지) |
|
||||
| 품목 | 대표 품목명 + (외 N건) |
|
||||
| 수량 | 총 수량 |
|
||||
| 생산 사유 | `options.production_reason` |
|
||||
| 등록일 | `created_at` |
|
||||
|
||||
### 4.3 상태 배지 색상 (수주와 동일)
|
||||
|
||||
| 상태 | 라벨 | 색상 |
|
||||
|------|------|------|
|
||||
| `DRAFT` | 등록 | gray |
|
||||
| `CONFIRMED` | 확정 | blue |
|
||||
| `IN_PROGRESS` | 진행중 | yellow |
|
||||
| `IN_PRODUCTION` | 생산중 | orange |
|
||||
| `PRODUCED` | 생산완료 | green |
|
||||
| `COMPLETED` | 완료 | green |
|
||||
| `CANCELLED` | 취소 | red |
|
||||
|
||||
---
|
||||
|
||||
## 5. 구현 체크리스트
|
||||
|
||||
### 프론트엔드 (React)
|
||||
|
||||
- [ ] 재고생산관리 메뉴/라우트 추가
|
||||
- [ ] 목록 페이지: `GET /api/v1/orders?order_type=STOCK`
|
||||
- [ ] 통계 카드: `GET /api/v1/orders/stats?order_type=STOCK`
|
||||
- [ ] 생성 폼: `order_type_code: 'STOCK'` 필수 전송
|
||||
- [ ] 상세/수정 페이지: 수주 화면 단순화 (거래처/견적/배송/할인 제거)
|
||||
- [ ] 생산지시 생성 버튼: `POST /api/v1/orders/{id}/production-order`
|
||||
- [ ] 상태 변경: `PATCH /api/v1/orders/{id}/status`
|
||||
|
||||
### 프론트엔드 — 생산지시 목록 수정
|
||||
|
||||
- [ ] 생산지시 목록에서 `order_type_code`가 `STOCK`인 건: 납기 컬럼 `-` 표시
|
||||
- [ ] 생산지시 생성 UI: STOCK 수주는 공정 선택 불필요 (API가 절곡 자동 선택)
|
||||
|
||||
### 백엔드 (API) — 완료
|
||||
|
||||
- [x] `Order::TYPE_STOCK = 'STOCK'` 상수 추가
|
||||
- [x] StoreOrderRequest에 `STOCK` validation 추가
|
||||
- [x] UpdateOrderRequest에 `STOCK` validation 추가
|
||||
- [x] 재고생산 채번: `STK{YYYYMMDD}{NNNN}`
|
||||
- [x] stats()에 `order_type` 필터 추가
|
||||
- [x] STOCK 타입 확정 시 매출 자동 생성 스킵
|
||||
- [x] options에 `production_reason`, `target_stock_qty` 필드 추가
|
||||
- [x] store()에서 STOCK 타입 `site_name = '재고생산'` 자동 설정
|
||||
- [x] createProductionOrder()에서 STOCK: `project_name = '재고생산'` 고정
|
||||
- [x] createProductionOrder()에서 STOCK: 절곡 공정 자동 선택
|
||||
- [x] createProductionOrder()에서 STOCK: `scheduled_date = now()` 자동 설정
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- 수주관리: 기존 수주 API는 동일 엔드포인트 (`/api/v1/orders`)
|
||||
- 작업지시: `POST /api/v1/orders/{id}/production-order`
|
||||
- 품목관리: `rules/item-policy.md`
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-16
|
||||
@@ -172,7 +172,6 @@ async function main() {
|
||||
['QR코드 관리', '1,020만원', '5만원'],
|
||||
['사진/출하 관리', '1,920만원', '10만원'],
|
||||
['검사/토큰 적용', '1,020만원', '5만원'],
|
||||
['이카운트 연동', '1,920만원', '10만원'],
|
||||
];
|
||||
|
||||
// 테이블 헤더
|
||||
@@ -291,7 +290,6 @@ async function main() {
|
||||
s5.addText('단체 가입', { x: 5.2, y: 2.85, w: 4.3, h: 0.45, fontSize: 14, bold: true, color: C.orange, align: 'center', valign: 'middle', fontFace: 'Arial' });
|
||||
const groupItems = [
|
||||
['단체 수당', '30%', C.orange],
|
||||
['유치 파트너 수당', '3%', C.blue],
|
||||
];
|
||||
groupItems.forEach((item, i) => {
|
||||
const iy = 3.4 + i * 0.45;
|
||||
@@ -307,7 +305,7 @@ async function main() {
|
||||
s5.addShape(pres.ShapeType.roundRect, { x: 1.5, y: 4.75, w: 2, h: 0.35, rectRadius: 0.06, fill: { color: C.green } });
|
||||
s5.addText('합계 25%', { x: 1.5, y: 4.75, w: 2, h: 0.35, fontSize: 11, bold: true, color: C.white, align: 'center', valign: 'middle', fontFace: 'Arial' });
|
||||
s5.addShape(pres.ShapeType.roundRect, { x: 6.2, y: 4.75, w: 2, h: 0.35, rectRadius: 0.06, fill: { color: C.orange } });
|
||||
s5.addText('합계 33%', { x: 6.2, y: 4.75, w: 2, h: 0.35, fontSize: 11, bold: true, color: C.white, align: 'center', valign: 'middle', fontFace: 'Arial' });
|
||||
s5.addText('합계 30%', { x: 6.2, y: 4.75, w: 2, h: 0.35, fontSize: 11, bold: true, color: C.white, align: 'center', valign: 'middle', fontFace: 'Arial' });
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// 슬라이드 6: 수당 계산 예시
|
||||
@@ -442,14 +440,13 @@ async function main() {
|
||||
const s8 = pres.addSlide();
|
||||
s8.background = { fill: C.white };
|
||||
addFooter(s8);
|
||||
addPageTitle(s8, '고객에게 제안할 수 있는 할인 4가지');
|
||||
addPageTitle(s8, '고객에게 제안할 수 있는 할인 3가지');
|
||||
addSlideNumber(s8, 8, TOTAL);
|
||||
|
||||
const discounts = [
|
||||
{ title: '개발비 할인', desc: '%, 정액, 전액면제', impact: '수당 영향 있음', impactColor: C.red, bg: C.redBg, border: 'FFCDD2', color: C.red, icon: '1' },
|
||||
{ title: '구독료 할인', desc: '최대 50%까지', impact: '수당 영향 없음', impactColor: C.green, bg: C.greenBg, border: C.greenBorder, color: C.green, icon: '2' },
|
||||
{ title: '무료 체험', desc: '1주일(7일)', impact: '수당 영향 없음', impactColor: C.green, bg: C.blueBg, border: C.blueBorder, color: C.blue, icon: '3' },
|
||||
{ title: '개발비-구독료 연동', desc: 'ON/OFF 선택', impact: '개발비 변동 시 영향', impactColor: 'F57F17', bg: C.orangeBg, border: C.orangeBorder, color: C.orange, icon: '4' },
|
||||
{ title: '개발비-구독료 연동', desc: 'ON/OFF 선택', impact: '개발비 변동 시 영향', impactColor: 'F57F17', bg: C.orangeBg, border: C.orangeBorder, color: C.orange, icon: '3' },
|
||||
];
|
||||
|
||||
discounts.forEach((d, i) => {
|
||||
@@ -473,7 +470,7 @@ async function main() {
|
||||
s8.addShape(pres.ShapeType.roundRect, { x: 0.5, y: 4.3, w: 9, h: 0.6, rectRadius: 0.08, fill: { color: 'E8F5E9' }, line: { color: 'A5D6A7', width: 0.5 } });
|
||||
s8.addText([
|
||||
{ text: '💡 영업 팁: ', options: { fontSize: 11, bold: true, color: C.green } },
|
||||
{ text: '구독료 할인 + 무료 체험은 고객에게 혜택을 주면서 내 수당은 안 줄어드는 좋은 전략!', options: { fontSize: 11, color: '1B5E20' } },
|
||||
{ text: '구독료 할인은 고객에게 혜택을 주면서 내 수당은 안 줄어드는 좋은 전략!', options: { fontSize: 11, color: '1B5E20' } },
|
||||
], { x: 0.7, y: 4.3, w: 8.6, h: 0.6, valign: 'middle', fontFace: 'Arial' });
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
@@ -499,7 +496,7 @@ async function main() {
|
||||
], { x: 0.5, y: 1.2, w: 9, h: 0.7, align: 'center', valign: 'middle', fontFace: 'Arial' });
|
||||
|
||||
// 실전 예시
|
||||
s9.addText('실전 예시: 제조업 기본 패키지, 10% 할인, 무료 체험 1주일', {
|
||||
s9.addText('실전 예시: 제조업 기본 패키지, 10% 할인', {
|
||||
x: 0.5, y: 2.1, w: 9, h: 0.35, fontSize: 11, bold: true, color: C.text, fontFace: 'Arial'
|
||||
});
|
||||
|
||||
@@ -508,9 +505,9 @@ async function main() {
|
||||
['개발비 할인 10%', '2,000 × 10%', '-200만원', C.red],
|
||||
['최종 개발비', '', '1,800만원', C.green],
|
||||
['월 구독료', '', '50만원', C.blue],
|
||||
['유료 개월수', '12 - 7일(무료)', '약 11.77개월', 'CE93D8'],
|
||||
['연간 구독료', '50 × 11.77', '약 588만원', C.blue],
|
||||
['1년차 총 비용', '1,800 + 588', '2,388만원', C.orange],
|
||||
['유료 개월수', '12개월', '12개월', 'CE93D8'],
|
||||
['연간 구독료', '50 × 12', '600만원', C.blue],
|
||||
['1년차 총 비용', '1,800 + 600', '2,400만원', C.orange],
|
||||
];
|
||||
|
||||
calcData.forEach((row, i) => {
|
||||
@@ -602,7 +599,7 @@ async function main() {
|
||||
// 4 Steps
|
||||
const steps = [
|
||||
{ num: '1', title: '상품 고르기', desc: '필수 상품 자동체크\n추가 상품 선택', color: C.green, bg: C.greenBg },
|
||||
{ num: '2', title: '할인 설정', desc: '개발비/구독료 할인\n무료 체험 기간', color: C.blue, bg: C.blueBg },
|
||||
{ num: '2', title: '할인 설정', desc: '개발비/구독료 할인\n연동 ON/OFF', color: C.blue, bg: C.blueBg },
|
||||
{ num: '3', title: '가입유형 선택', desc: '개인 가입\n단체 가입', color: C.orange, bg: C.orangeBg },
|
||||
{ num: '4', title: '결과 확인!', desc: '최종 비용\n내 수당', color: '7B1FA2', bg: 'F3E5F5' },
|
||||
];
|
||||
@@ -654,9 +651,9 @@ async function main() {
|
||||
addSlideNumber(s12, 12, TOTAL);
|
||||
|
||||
const tips = [
|
||||
{ situation: '초기 비용 부담이 클 때', strategy: '개발비 할인 + 무료 체험 1주일', color: C.green, bg: C.greenBg },
|
||||
{ situation: '초기 비용 부담이 클 때', strategy: '개발비 할인 + 구독료 할인 조합', color: C.green, bg: C.greenBg },
|
||||
{ situation: '매달 비용이 부담될 때', strategy: '구독료 할인 (최대 50%)', color: C.blue, bg: C.blueBg },
|
||||
{ situation: '기존 시스템이 있을 때', strategy: '이카운트 연동 모듈 추천', color: C.orange, bg: C.orangeBg },
|
||||
{ situation: '세금계산서·카드 관리 필요', strategy: '바로빌 부가 서비스 안내 (기본 포함)', color: C.orange, bg: C.orangeBg },
|
||||
{ situation: '대형 제조업체', strategy: '기본 패키지 + 공정관리 + 품질관리', color: '7B1FA2', bg: 'F3E5F5' },
|
||||
{ situation: '여러 업체를 묶을 수 있을 때', strategy: '단체 가입 (수당률 30%로 UP!)', color: C.red, bg: C.redBg },
|
||||
];
|
||||
@@ -675,7 +672,7 @@ async function main() {
|
||||
const faqs = [
|
||||
['"왜 비싸요?"', '기존 ERP 5천만~1억 vs SAM 2천만원 + AI 포함'],
|
||||
['"구독료가 아까운데?"', '자체 서버 월 200만+ vs SAM 월 50만원'],
|
||||
['"무료 체험 안 돼요?"', '1주일(7일) 무료 체험 가능!'],
|
||||
['"추가 할인 안 돼요?"', '구독료 최대 50%까지 할인 가능!'],
|
||||
];
|
||||
faqs.forEach((f, i) => {
|
||||
const fy = 4.5 + i * 0.3;
|
||||
@@ -710,7 +707,7 @@ async function main() {
|
||||
const keyPoints = [
|
||||
'개발비 = 한 번 | 구독료 = 매달',
|
||||
'수당 = 최종 개발비 × 수당률',
|
||||
'구독료 할인/무료 체험 → 수당 영향 없음',
|
||||
'구독료 할인 → 수당 영향 없음',
|
||||
];
|
||||
keyPoints.forEach((kp, i) => {
|
||||
s13.addShape(pres.ShapeType.roundRect, { x: 2, y: 3.85 + i * 0.42, w: 6, h: 0.35, rectRadius: 0.06, fill: { color: '1B2838' }, line: { color: '2A3A4A', width: 0.5 } });
|
||||
|
||||
@@ -60,7 +60,7 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
| QR코드 관리 | 1,020만원 | 5만원 | 제품에 QR코드 부착, 이력 추적 |
|
||||
| 사진/출하 관리 | 1,920만원 | 10만원 | 출하 사진 촬영·등록, 배송 관리 |
|
||||
| 검사/토큰 적용 | 1,020만원 | 5만원 | 품질 검사, AI 토큰 활용 |
|
||||
| 이카운트 연동 | 1,920만원 | 10만원 | 기존 이카운트 ERP와 데이터 연동 |
|
||||
|
||||
|
||||
### 3.3 통합 패키지 (대형 프로젝트용)
|
||||
|
||||
@@ -84,7 +84,7 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
|
||||
## 4. 할인/프로모션 (고객에게 제안할 수 있는 것들)
|
||||
|
||||
가격 시뮬레이터에서 **4가지 할인**을 조합할 수 있다.
|
||||
가격 시뮬레이터에서 **3가지 할인**을 조합할 수 있다.
|
||||
|
||||
### 4.1 개발비 할인
|
||||
|
||||
@@ -102,18 +102,7 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
예) 구독료 50만원/월 → 20% 할인 → 40만원/월
|
||||
```
|
||||
|
||||
### 4.3 무료 체험 기간
|
||||
|
||||
서비스 시작 후 1주일(7일) 동안 구독료를 면제한다.
|
||||
|
||||
| 무료 기간 | 1년 중 실제 내는 개월 |
|
||||
|----------|:------------------:|
|
||||
| 없음 | 12개월 |
|
||||
| 1주일(7일) | 거의 12개월 |
|
||||
|
||||
> **참고**: 1주일(7일) 무료 체험은 연간 비용에 미미한 영향을 주므로, 유료 개월수는 거의 12개월로 계산한다.
|
||||
|
||||
### 4.4 개발비-구독료 연동 (선택)
|
||||
### 4.3 개발비-구독료 연동 (선택)
|
||||
|
||||
개발비를 깎아주면 구독료도 같은 비율로 자동 조정하는 기능이다.
|
||||
|
||||
@@ -141,7 +130,7 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 예시: 제조업 기본 패키지, 10% 할인, 무료 체험 1주일
|
||||
### 예시: 제조업 기본 패키지, 10% 할인
|
||||
|
||||
| 항목 | 계산 | 금액 |
|
||||
|------|------|-----:|
|
||||
@@ -149,9 +138,9 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
| 개발비 할인 | 2,000 × 10% | -200만원 |
|
||||
| **최종 개발비** | - | **1,800만원** |
|
||||
| 월 구독료 | - | 50만원 |
|
||||
| 유료 개월수 | 거의 12개월 (1주일 무료) | 약 12개월 |
|
||||
| 연 구독료 | 50 × 약 12 | 약 600만원 |
|
||||
| **1년차 총 비용** | 1,800 + 약 600 | **약 2,400만원** |
|
||||
| 유료 개월수 | 12개월 | 12개월 |
|
||||
| 연 구독료 | 50 × 12 | 600만원 |
|
||||
| **1년차 총 비용** | 1,800 + 600 | **2,400만원** |
|
||||
|
||||
> 2년차부터는 구독료만 내면 된다: 50만원 × 12 = **600만원/년**
|
||||
|
||||
@@ -177,12 +166,11 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
| | 개인 가입 | 단체 가입 |
|
||||
|---|:---:|:---:|
|
||||
| **파트너 수당** | **20%** | **30%** |
|
||||
| **유치 파트너 수당** | 5% | 3% |
|
||||
| **합계** | **25%** | **33%** |
|
||||
| **유치 파트너 수당** | 5% | - |
|
||||
| **매니저 수당** | 첫달 구독료 | - |
|
||||
|
||||
- **개인 가입**: 개별 고객이 직접 계약
|
||||
- **단체 가입**: 여러 고객을 묶어서 한꺼번에 계약
|
||||
- **매니저 수당**: 개발비 요율이 아닌, 첫달 구독료를 별도 지급
|
||||
- **개인 가입**: 개별 고객이 직접 계약 (파트너 20% + 유치 파트너 5% + 매니저 수당)
|
||||
- **단체 가입**: 여러 고객을 묶어서 한꺼번에 계약 (단체 수당 30%)
|
||||
|
||||
### 6.3 수당 계산 예시 (제조업 기본 패키지)
|
||||
|
||||
@@ -297,7 +285,6 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
**Step 3: 할인 설정**
|
||||
- 개발비 할인: % 또는 정액
|
||||
- 구독료 할인: 0~50%
|
||||
- 무료 체험 기간: 없음 / 1주일(7일)
|
||||
- 개발비-구독료 연동: ON/OFF
|
||||
|
||||
**Step 4: 가입 유형 선택**
|
||||
@@ -326,11 +313,11 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
|
||||
### Q2. 구독료를 깎아줘도 수당이 줄어드나?
|
||||
|
||||
**아니다.** 수당은 개발비에서만 계산한다. 구독료 할인, 무료 체험은 수당에 영향 없다.
|
||||
**아니다.** 수당은 개발비에서만 계산한다. 구독료 할인은 수당에 영향 없다.
|
||||
|
||||
### Q3. 단체 가입이 수당률이 더 높은가?
|
||||
|
||||
**그렇다.** 단체 가입은 단체 수당 30% + 유치 파트너 3% = 33%이다. 개인 가입은 파트너 20% + 유치 파트너 5% = 25%이므로 단체가 더 높다.
|
||||
**그렇다.** 단체 가입은 수당률 30%, 개인 가입은 파트너 20% + 유치 파트너 5% = 25%이므로 단체가 더 높다.
|
||||
|
||||
### Q4. 수당은 한 번에 받나?
|
||||
|
||||
@@ -340,11 +327,7 @@ SAM의 요금은 **딱 두 가지**로 구성된다.
|
||||
|
||||
**0원이다.** 개발비가 0원이면 수당도 0원이다. 전액 면제는 최저 개발비가 0원인 상품에서만 가능하다.
|
||||
|
||||
### Q6. 무료 체험 기간을 주면 나한테 손해인가?
|
||||
|
||||
**아니다.** 무료 체험은 구독료에만 영향을 주고, 수당은 개발비 기준이므로 파트너 수당에는 영향이 없다. 오히려 고객 유치가 쉬워질 수 있다.
|
||||
|
||||
### Q7. 2년차부터는 고객이 얼마를 내나?
|
||||
### Q6. 2년차부터는 고객이 얼마를 내나?
|
||||
|
||||
2년차부터는 **구독료만** 낸다. 예를 들어 월 구독료 50만원이면 연 600만원이다.
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
| QR코드 관리 | 1,020만원 | 5만원 | 제품 이력 추적이 필요한 곳 |
|
||||
| 사진/출하 관리 | 1,920만원 | 10만원 | 출하·배송 기록이 중요한 곳 |
|
||||
| 검사/토큰 적용 | 1,020만원 | 5만원 | 품질검사 + AI 활용이 필요한 곳 |
|
||||
| 이카운트 연동 | 1,920만원 | 10만원 | 기존에 이카운트를 쓰는 곳 |
|
||||
|
||||
|
||||
### 대형 패키지 (큰 프로젝트용)
|
||||
|
||||
@@ -103,14 +103,14 @@
|
||||
┌─ 개인 가입 ─────────────────┐ ┌─ 단체 가입 ─────────────────┐
|
||||
│ │ │ │
|
||||
│ 파트너 수당: 20% │ │ 단체 수당: 30% │
|
||||
│ 유치 파트너 수당: 5% │ │ 유치 파트너 수당: 3% │
|
||||
│ ───────────── │ │ ───────────── │
|
||||
│ 합계: 25% │ │ 합계: 33% │
|
||||
│ 유치 파트너 수당: 5% │ │ │
|
||||
│ ───────────── │ │ (여러 고객 묶어서 계약) │
|
||||
│ 합계: 25% │ │ │
|
||||
│ │ │ │
|
||||
│ (개별 고객이 직접 계약) │ │ (여러 고객 묶어서 계약) │
|
||||
│ (개별 고객이 직접 계약) │ │ │
|
||||
│ │ │ │
|
||||
│ + 매니저 수당: 첫달 구독료 │ │ + 매니저 수당: 첫달 구독료 │
|
||||
│ (별도 지급) │ │ (별도 지급) │
|
||||
│ + 매니저 수당: 첫달 구독료 │ │ │
|
||||
│ (별도 지급) │ │ │
|
||||
└──────────────────────────────┘ └──────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -121,18 +121,18 @@
|
||||
| | 개인 가입 | 단체 가입 |
|
||||
|---|---:|---:|
|
||||
| 파트너/단체 수당 | **400만원** | **600만원** |
|
||||
| 유치 파트너 수당 | 100만원 | 60만원 |
|
||||
| **합계** | **500만원** | **660만원** |
|
||||
| + 매니저 수당 (별도) | 첫달 구독료 50만원 | 첫달 구독료 50만원 |
|
||||
| 유치 파트너 수당 | 100만원 | - |
|
||||
| **합계** | **500만원** | **600만원** |
|
||||
| + 매니저 수당 (별도) | 첫달 구독료 50만원 | - |
|
||||
|
||||
**10% 할인(1,800만원)으로 판매한 경우:**
|
||||
|
||||
| | 개인 가입 | 단체 가입 |
|
||||
|---|---:|---:|
|
||||
| 파트너/단체 수당 | **360만원** | **540만원** |
|
||||
| 유치 파트너 수당 | 90만원 | 54만원 |
|
||||
| **합계** | **450만원** | **594만원** |
|
||||
| + 매니저 수당 (별도) | 첫달 구독료 50만원 | 첫달 구독료 50만원 |
|
||||
| 유치 파트너 수당 | 90만원 | - |
|
||||
| **합계** | **450만원** | **540만원** |
|
||||
| + 매니저 수당 (별도) | 첫달 구독료 50만원 | - |
|
||||
|
||||
> 할인하면 내 수당도 줄어든다. **정가에 가깝게 팔수록 수당이 크다!**
|
||||
> 매니저 수당은 개발비 요율이 아니라, 첫달 구독료를 별도 지급하는 형태이다.
|
||||
@@ -354,9 +354,9 @@ Step 1 Step 2 Step 3 Step 4
|
||||
|----------|-----------|
|
||||
| 초기 비용 부담이 클 때 | 개발비 할인 + 구독료 할인 |
|
||||
| 매달 비용이 부담될 때 | 구독료 할인 (최대 50%) |
|
||||
| 기존 시스템(이카운트)이 있을 때 | 이카운트 연동 모듈 추천 |
|
||||
| 세금계산서·카드 관리가 필요할 때 | 바로빌 부가 서비스 안내 (기본 포함) |
|
||||
| 대형 제조업체 | 기본 패키지 + 공정관리 + 품질관리 |
|
||||
| 여러 업체를 묶을 수 있을 때 | 단체 가입 (수당률 33%로 UP!) |
|
||||
| 여러 업체를 묶을 수 있을 때 | 단체 가입 (수당률 30%로 UP!) |
|
||||
|
||||
### 고객이 자주 하는 질문과 답변
|
||||
|
||||
@@ -394,11 +394,11 @@ Step 1 Step 2 Step 3 Step 4
|
||||
|
||||
### Q3. 단체 가입이 뭔가?
|
||||
|
||||
여러 고객을 묶어서 한꺼번에 계약하는 것이다. 단체 수당 30% + 유치 파트너 3% = **합계 33%**를 받는다.
|
||||
여러 고객을 묶어서 한꺼번에 계약하는 것이다. **단체 수당 30%**를 받는다.
|
||||
|
||||
### Q4. 유치 파트너 수당이 뭔가?
|
||||
|
||||
나를 유치한 상위 파트너에게 지급되는 수당이다. 개인 가입 시 개발비의 **5%**, 단체 가입 시 **3%**가 지급된다.
|
||||
나를 유치한 상위 파트너에게 지급되는 수당이다. 개인 가입 시 개발비의 **5%**가 지급된다.
|
||||
|
||||
### Q5. 매니저 수당이 뭔가?
|
||||
|
||||
|
||||
Binary file not shown.
341
plans/stock-production-react-request.md
Normal file
341
plans/stock-production-react-request.md
Normal file
@@ -0,0 +1,341 @@
|
||||
# 재고생산관리 React 구현 요청서
|
||||
|
||||
> **작성일**: 2026-03-16
|
||||
> **요청자**: R&D 실장
|
||||
> **대상**: 프론트엔드 개발자
|
||||
> **우선순위**: 🟡 중요
|
||||
> **API 상태**: ✅ 구현 완료 (개발서버 배포됨)
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
수주 없이 **재고 목적으로 생산**하는 경우를 관리하는 메뉴를 추가한다.
|
||||
기존 수주관리 API를 그대로 사용하며, `order_type_code = 'STOCK'`으로 구분한다.
|
||||
|
||||
### 1.1 구현 대상
|
||||
|
||||
| 메뉴 | 위치 | 설명 | 난이도 |
|
||||
|------|------|------|:------:|
|
||||
| **재고생산관리** | 판매관리 > 재고생산관리 | 재고생산 등록/목록/상세/수정/삭제 | **낮음** (수주 화면 복제 후 단순화) |
|
||||
|
||||
### 1.2 참고 문서
|
||||
|
||||
| 문서 | 경로 | 용도 |
|
||||
|------|------|------|
|
||||
| **API 명세** (필독) | `docs/frontend/api-specs/stock-production-api.md` | 전체 엔드포인트, 요청/응답 형식 |
|
||||
| 기능 설명 | `docs/features/sales/stock-production.md` | 비즈니스 개념, 수주와의 관계 |
|
||||
|
||||
### 1.3 핵심 원칙
|
||||
|
||||
```
|
||||
✅ 수주관리 화면을 복제한 뒤 불필요한 필드 제거
|
||||
✅ API는 기존 /api/v1/orders 그대로 사용 (order_type=STOCK 필터)
|
||||
✅ 생성 시 order_type_code: 'STOCK' 필수 전송
|
||||
❌ 별도 API 엔드포인트 없음
|
||||
❌ 거래처, 견적, 배송, 할인, 개소(Node) 관련 UI 불필요
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 파일 구조 (제안)
|
||||
|
||||
기존 수주관리 구조를 따른다.
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/[locale]/(protected)/sales/order-management-sales/
|
||||
│ └── stocks/ # 재고생산관리 (신규)
|
||||
│ ├── page.tsx # 목록 페이지
|
||||
│ └── [id]/
|
||||
│ ├── page.tsx # 상세 페이지
|
||||
│ └── production-order/
|
||||
│ └── page.tsx # 생산지시 생성 페이지
|
||||
│
|
||||
├── components/orders/
|
||||
│ └── StockProductionRegistration.tsx # 재고생산 등록/수정 폼 (신규)
|
||||
│ └── (기존 actions.ts에 함수 추가 또는 별도 stockActions.ts)
|
||||
```
|
||||
|
||||
> **대안**: `stocks/` 대신 기존 수주관리 페이지에서 `order_type` 탭으로 분리하는 방식도 가능. 실장 판단에 따름.
|
||||
|
||||
---
|
||||
|
||||
## 3. 화면별 구현 가이드
|
||||
|
||||
### 3.1 재고생산 목록 페이지
|
||||
|
||||
**경로**: `/sales/order-management-sales/stocks`
|
||||
|
||||
**수주관리 목록 페이지를 복제**한 뒤 다음을 변경:
|
||||
|
||||
| 항목 | 수주관리 (현재) | 재고생산 (변경) |
|
||||
|------|---------------|---------------|
|
||||
| 페이지 제목 | 수주관리 | **재고생산관리** |
|
||||
| API 호출 | `getOrders()` | `getOrders({ order_type: 'STOCK' })` |
|
||||
| 통계 API | `getOrderStats()` | `getOrderStats({ order_type: 'STOCK' })` → `GET /api/v1/orders/stats?order_type=STOCK` |
|
||||
| 표시 컬럼 | 수주번호, 거래처, 현장명, 수량, 납기, 금액... | **생산번호, 품목, 수량, 생산사유, 등록일, 상태** |
|
||||
| 통계 카드 | 이번달 수주금액, 분할대기... | 전체, 등록, 확정, 진행중, 완료 (또는 간소화) |
|
||||
|
||||
**목록 테이블 컬럼**:
|
||||
|
||||
| 컬럼 | 데이터 | 비고 |
|
||||
|------|--------|------|
|
||||
| 번호 | 글로벌 인덱스 | |
|
||||
| 생산번호 | `order_no` (STK...) | 배지 스타일 |
|
||||
| 품목 | 대표 `items[0].item_name` + (외 N건) | |
|
||||
| 수량 | 총 수량 | |
|
||||
| 생산 사유 | `options.production_reason` | 없으면 `-` |
|
||||
| 등록일 | `created_at` | YYYY-MM-DD |
|
||||
| 상태 | `status_code` | 배지 (수주와 동일 색상) |
|
||||
| 작업 | 상세보기, 삭제 | |
|
||||
|
||||
**제거할 컬럼**: 거래처, 현장명, 납기, 금액
|
||||
|
||||
### 3.2 재고생산 등록/수정 폼
|
||||
|
||||
**수주 등록 폼(`OrderRegistration.tsx`)을 복제**한 뒤 다음을 변경:
|
||||
|
||||
#### 제거할 섹션
|
||||
|
||||
```
|
||||
❌ 거래처 선택 (client_id, client_name, client_contact)
|
||||
❌ 현장명 (site_name) — API가 '재고생산'으로 자동 설정
|
||||
❌ 견적 선택 (quote_id) / 견적에서 가져오기
|
||||
❌ 배송 정보 (delivery_date, delivery_method_code)
|
||||
❌ 운임비용 (options.shipping_cost_code)
|
||||
❌ 수신자 정보 (options.receiver, receiver_contact, shipping_address)
|
||||
❌ 할인 (discount_rate, discount_amount)
|
||||
❌ 금액 계산 (supply_amount, tax_amount, total_amount)
|
||||
❌ 매출 인식 (sales_recognition)
|
||||
❌ 개소/구역 (OrderNode) 트리 구조
|
||||
```
|
||||
|
||||
#### 유지할 섹션
|
||||
|
||||
```
|
||||
✅ 생산 사유 (options.production_reason) — 텍스트 입력
|
||||
✅ 목표 재고 수량 (options.target_stock_qty) — 숫자 입력
|
||||
✅ 비고 (memo) — 텍스트 입력
|
||||
✅ 품목 목록 (items[]) — 품목 선택 + 수량 입력
|
||||
```
|
||||
|
||||
#### 품목 입력 테이블
|
||||
|
||||
| 필드 | 타입 | 필수 | 비고 |
|
||||
|------|------|:----:|------|
|
||||
| 품목 | 품목 선택 (ItemAddDialog) | ✅ | item_id, item_name, item_code |
|
||||
| 규격 | 텍스트 | - | specification |
|
||||
| 수량 | 숫자 | ✅ | quantity |
|
||||
| 단위 | 텍스트 | - | unit (기본: EA) |
|
||||
|
||||
> **단가/금액은 불필요**하지만, API validation에서 `unit_price`가 required이므로 `0`을 전송
|
||||
|
||||
#### API 요청 예시
|
||||
|
||||
```json
|
||||
{
|
||||
"order_type_code": "STOCK",
|
||||
"memo": "봄 시즌 대비 재고 확보",
|
||||
"options": {
|
||||
"production_reason": "시즌 대비",
|
||||
"target_stock_qty": 500
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"item_id": 10,
|
||||
"item_name": "25mm 알루미늄 블라인드",
|
||||
"specification": "W1000 x H2000",
|
||||
"quantity": 100,
|
||||
"unit_price": 0,
|
||||
"unit": "EA"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 재고생산 상세 페이지
|
||||
|
||||
**수주 상세(`OrderSalesDetailView.tsx`)를 복제**한 뒤 단순화:
|
||||
|
||||
| 섹션 | 표시 |
|
||||
|------|------|
|
||||
| 생산번호 (order_no) | ✅ |
|
||||
| 상태 (status_code) | ✅ 배지 |
|
||||
| 생산 사유 | ✅ `options.production_reason` |
|
||||
| 목표 재고 수량 | ✅ `options.target_stock_qty` |
|
||||
| 비고 | ✅ `memo` |
|
||||
| 품목 목록 | ✅ 테이블 (품목명, 규격, 수량) |
|
||||
| 거래처/현장/납기/금액 | ❌ 제거 |
|
||||
| 개소/구역 트리 | ❌ 제거 |
|
||||
|
||||
**액션 버튼**:
|
||||
- 수정 (DRAFT 상태만)
|
||||
- 삭제 (DRAFT 상태만)
|
||||
- 확정 (`PATCH /api/v1/orders/{id}/status` → `{ "status": "CONFIRMED" }`)
|
||||
- 생산지시 생성 (CONFIRMED 상태만) → 기존 생산지시 생성 페이지 재사용
|
||||
|
||||
### 3.4 생산지시 생성 페이지
|
||||
|
||||
**기존 `[id]/production-order/page.tsx`를 재사용** 가능.
|
||||
|
||||
STOCK 수주의 생산지시는 API가 자동 처리하므로 프론트에서 특별한 분기 불필요:
|
||||
|
||||
| 항목 | API 자동 처리 |
|
||||
|------|-------------|
|
||||
| 공정 선택 | 절곡 공정 자동 선택 (process_ids 전달 불필요) |
|
||||
| 현장명 | `'재고생산'` 고정 |
|
||||
| 작업예정일 | `now()` 자동 (scheduled_date 전달 불필요) |
|
||||
|
||||
> 단, 공정 매칭 미리보기 UI에서 STOCK 수주가 BOM 없이도 "절곡" 공정으로 표시되도록 조건 분기 필요할 수 있음.
|
||||
|
||||
### 3.5 생산지시 목록 — STOCK 건 표시 (기존 페이지 수정)
|
||||
|
||||
**경로**: `/sales/order-management-sales/production-orders/page.tsx`
|
||||
|
||||
STOCK 타입 재고생산의 생산지시도 이 목록에 표시된다. 변경 필요 사항:
|
||||
|
||||
| 컬럼 | 현재 | STOCK 건 표시 |
|
||||
|------|------|-------------|
|
||||
| 현장명 | `siteName` | `'재고생산'` (API가 자동 설정하므로 변경 불필요) |
|
||||
| 거래처 | `clientName` | 빈 값 또는 `-` |
|
||||
| 납기 | `deliveryDate` | `-` 표시 (STOCK은 delivery_date 없음) |
|
||||
| 생산지시일 | `productionOrderedAt` | 정상 표시 |
|
||||
|
||||
**구현 방법**: API 응답에 `order_type_code`가 이미 포함됨. 프론트 types에 추가:
|
||||
|
||||
```typescript
|
||||
// types.ts 수정
|
||||
interface ApiProductionOrder {
|
||||
// ... 기존 필드
|
||||
order_type_code?: string; // 추가
|
||||
}
|
||||
|
||||
// transform 함수에서
|
||||
orderTypeCode: data.order_type_code || 'ORDER',
|
||||
```
|
||||
|
||||
테이블 렌더링에서:
|
||||
|
||||
```typescript
|
||||
// 납기 컬럼
|
||||
{item.orderTypeCode === 'STOCK' ? '-' : item.deliveryDate}
|
||||
|
||||
// 거래처 컬럼
|
||||
{item.orderTypeCode === 'STOCK' ? '-' : item.clientName}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 메뉴 등록
|
||||
|
||||
메뉴 위치:
|
||||
|
||||
```
|
||||
판매관리
|
||||
├── 거래처관리
|
||||
├── 견적관리
|
||||
├── 수주관리
|
||||
├── 재고생산관리 ← 신규 (수주관리 아래)
|
||||
└── 단가관리
|
||||
```
|
||||
|
||||
> 메뉴 등록은 MNG 메뉴 동기화 기능으로 별도 처리. 프론트에서는 라우트만 구현.
|
||||
|
||||
---
|
||||
|
||||
## 5. 수주관리와의 차이 요약
|
||||
|
||||
```
|
||||
┌─ 수주관리 ──────────────────┐ ┌─ 재고생산관리 ───────────────┐
|
||||
│ │ │ │
|
||||
│ 거래처 선택 │ │ 생산 사유 (텍스트) │
|
||||
│ 현장명 │ │ 목표 재고 수량 │
|
||||
│ 견적 연결 │ │ 비고 │
|
||||
│ 배송/납기/운임 │ │ │
|
||||
│ 할인/금액 계산 │ ├──────────────────────────────┤
|
||||
│ 매출 인식 방식 │ │ 품목 목록 │
|
||||
│ │ │ - 품목 선택 │
|
||||
│ 개소/구역 트리 (OrderNode) │ │ - 수량만 입력 │
|
||||
│ 품목 목록 (상세) │ │ (단가/금액/할인 불필요) │
|
||||
│ - 단가, 할인, 금액 계산 │ │ (개소/구역 불필요) │
|
||||
│ - floor_code, symbol_code │ │ │
|
||||
│ │ └──────────────────────────────┘
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. API 빠른 참조
|
||||
|
||||
### 6.1 목록 조회
|
||||
|
||||
```
|
||||
GET /api/v1/orders?order_type=STOCK&page=1&size=20
|
||||
```
|
||||
|
||||
### 6.2 통계
|
||||
|
||||
```
|
||||
GET /api/v1/orders/stats?order_type=STOCK
|
||||
```
|
||||
|
||||
### 6.3 생성
|
||||
|
||||
```
|
||||
POST /api/v1/orders
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"order_type_code": "STOCK",
|
||||
"memo": "...",
|
||||
"options": { "production_reason": "...", "target_stock_qty": 500 },
|
||||
"items": [{ "item_name": "...", "quantity": 100, "unit_price": 0 }]
|
||||
}
|
||||
```
|
||||
|
||||
### 6.4 상태 변경
|
||||
|
||||
```
|
||||
PATCH /api/v1/orders/{id}/status
|
||||
{ "status": "CONFIRMED" }
|
||||
```
|
||||
|
||||
### 6.5 생산지시 생성
|
||||
|
||||
```
|
||||
POST /api/v1/orders/{id}/production-order
|
||||
{ "priority": "normal" }
|
||||
```
|
||||
|
||||
> 공정/예정일은 API가 자동 처리 (절곡 공정, scheduled_date=now())
|
||||
|
||||
### 6.6 수정/삭제
|
||||
|
||||
```
|
||||
PUT /api/v1/orders/{id} — 수정
|
||||
DELETE /api/v1/orders/{id} — 삭제
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 구현 체크리스트
|
||||
|
||||
- [ ] `stocks/page.tsx` — 재고생산 목록 페이지
|
||||
- [ ] `stocks/[id]/page.tsx` — 재고생산 상세 페이지
|
||||
- [ ] `StockProductionRegistration.tsx` — 등록/수정 폼 (수주 폼 단순화)
|
||||
- [ ] Server Actions — `getOrders({ order_type: 'STOCK' })` 등 (기존 actions.ts 활용)
|
||||
- [ ] 생산지시 목록 — STOCK 건 납기 `-` 표시, `order_type_code` 타입 추가
|
||||
- [ ] 메뉴 라우트 등록
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [API 명세 (상세)](../frontend/api-specs/stock-production-api.md)
|
||||
- [기능 설명](../features/sales/stock-production.md)
|
||||
- [개발 변경이력](../dev/changes/20260316_stock_production_order.md)
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-16
|
||||
@@ -36,7 +36,7 @@ SAM 서비스 도입 시 고객에게 안내하는 요금 체계를 정리한다
|
||||
| QR코드 관리 | 1,020만원 | 5만원 |
|
||||
| 사진/출하 관리 | 1,920만원 | 10만원 |
|
||||
| 검사/토큰 적용 | 1,020만원 | 5만원 |
|
||||
| 이카운트 연동 | 1,920만원 | 10만원 |
|
||||
|
||||
|
||||
### 2.3 통합 패키지
|
||||
|
||||
|
||||
Binary file not shown.
27
rules/slides/customer-pricing/convert.cjs
Normal file
27
rules/slides/customer-pricing/convert.cjs
Normal file
@@ -0,0 +1,27 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
module.paths.unshift(path.join(require('os').homedir(), '.claude/skills/pptx-skill/scripts/node_modules'));
|
||||
|
||||
const PptxGenJS = require('pptxgenjs');
|
||||
const html2pptx = require(path.join(require('os').homedir(), '.claude/skills/pptx-skill/scripts/html2pptx.js'));
|
||||
|
||||
async function main() {
|
||||
const pres = new PptxGenJS();
|
||||
pres.defineLayout({ name: 'CUSTOM_16x9', width: 10, height: 5.625 });
|
||||
pres.layout = 'CUSTOM_16x9';
|
||||
|
||||
const dir = __dirname;
|
||||
const slides = fs.readdirSync(dir)
|
||||
.filter(f => f.startsWith('slide-') && f.endsWith('.html'))
|
||||
.sort();
|
||||
|
||||
for (const file of slides) {
|
||||
await html2pptx(path.join(dir, file), pres);
|
||||
}
|
||||
|
||||
const output = path.join(dir, '..', '..', 'customer-pricing.pptx');
|
||||
await pres.writeFile({ fileName: output });
|
||||
console.log('PPTX created:', output);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -92,12 +92,7 @@
|
||||
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #1e2a3a;">1,020만원</p></div>
|
||||
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">5만원</p></div>
|
||||
</div>
|
||||
<!-- 행4 -->
|
||||
<div style="display: flex; background: #ffffff; padding: 5pt 10pt; margin-top: -10pt; border-radius: 0 0 5pt 5pt;">
|
||||
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #1e2a3a;">이카운트 연동</p></div>
|
||||
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #1e2a3a;">1,920만원</p></div>
|
||||
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">10만원</p></div>
|
||||
</div>
|
||||
<!-- 행4: 이카운트 연동 제거 (바로빌은 기본 포함) -->
|
||||
|
||||
<!-- 통합 패키지 타이틀 -->
|
||||
<p style="font-size: 9pt; font-weight: 600; color: #5a6b7d; letter-spacing: 0.03em; margin-top: 4pt;">통합 패키지</p>
|
||||
|
||||
326
rules/wip-production-policy.md
Normal file
326
rules/wip-production-policy.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# 재공품(WIP) 생산 정책
|
||||
|
||||
> **작성일**: 2026-03-16
|
||||
> **상태**: 설계 확정
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
|
||||
제조업에서 **재공품(WIP, Work-In-Process)** 생산이 왜 필요하고, SAM 시스템에서 어떻게 처리하는지 정의한다.
|
||||
|
||||
### 1.2 대상 독자
|
||||
|
||||
- SAM을 도입하는 모든 제조업체
|
||||
- 시스템 운영자 및 생산관리 담당자
|
||||
- 개발팀 (기능 설계 시 참고)
|
||||
|
||||
---
|
||||
|
||||
## 2. 재공품이란
|
||||
|
||||
### 2.1 정의
|
||||
|
||||
재공품(WIP)은 **완성품이 되기 전 단계의 중간 생산물**이다.
|
||||
|
||||
블라인드/스크린 제조업에서는 절곡 가공된 **가이드레일, 케이스, 마구리, 바텀바** 등이 대표적인 재공품이다. 이 부품들은 최종 제품(블라인드)에 조립되기 전까지는 재공품 상태로 재고에 보관된다.
|
||||
|
||||
```
|
||||
원자재 (알루미늄 코일, 철판 등)
|
||||
↓ 절곡 가공
|
||||
재공품 (가이드레일, 케이스, 바텀바 등) ← 이 단계
|
||||
↓ 조립
|
||||
완성품 (블라인드, 스크린)
|
||||
↓ 출하
|
||||
고객 납품
|
||||
```
|
||||
|
||||
### 2.2 재공품 vs 완성품 vs 원자재
|
||||
|
||||
| 구분 | 설명 | 예시 |
|
||||
|------|------|------|
|
||||
| **원자재** | 가공 전 소재 | 알루미늄 코일, 철판, SUS판 |
|
||||
| **재공품 (WIP)** | 가공 완료, 조립 전 | 가이드레일, 케이스, 바텀바, 마구리 |
|
||||
| **완성품** | 출하 가능 상태 | 완성된 블라인드, 스크린 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 왜 재공품을 미리 만드는가
|
||||
|
||||
### 3.1 제조업의 현실
|
||||
|
||||
모든 제조업에는 **수주가 몰리는 성수기**와 **한가한 비수기**가 존재한다.
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────┐
|
||||
│ 수주량 │
|
||||
│ ▲ │
|
||||
│ │ ╱╲ ╱╲ │
|
||||
│ │ ╱╲ ╱ ╲ ╱ ╲ ╱╲ │
|
||||
│ │╱ ╲╱ ╲╱ ╲╱ ╲ │
|
||||
│ └──────────────────────────── ▶ 시간 │
|
||||
│ 비수기 성수기 비수기 성수기 │
|
||||
│ │
|
||||
│ ✕ 비수기: 작업자 유휴 → 인건비 낭비 │
|
||||
│ ✕ 성수기: 작업 폭주 → 납기 지연 │
|
||||
└────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.2 재공품 미리 생산의 효과
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ ① 유휴시간 활용 │
|
||||
│ 비수기에 작업자들이 놀지 않고 재공품 생산 │
|
||||
│ → 인건비 대비 생산성 향상 │
|
||||
│ │
|
||||
│ ② 납기 단축 │
|
||||
│ 수주가 들어오면 이미 만들어둔 재공품 사용 │
|
||||
│ → 절곡 가공 시간 절약 → 납기 3~5일 단축 │
|
||||
│ │
|
||||
│ ③ 생산 평준화 │
|
||||
│ 성수기 작업 부하를 비수기로 분산 │
|
||||
│ → 잔업/야근 감소 → 품질 안정 │
|
||||
│ │
|
||||
│ ④ 긴급 수주 대응 │
|
||||
│ 재고가 있으면 긴급 주문도 즉시 대응 가능 │
|
||||
│ → 고객 만족도 향상 → 수주 확보 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.3 어떤 품목을 미리 만드는가
|
||||
|
||||
모든 재공품을 무작정 만들지는 않는다. **다음 조건에 해당하는 품목**만 미리 생산한다:
|
||||
|
||||
| 조건 | 설명 | 예시 |
|
||||
|------|------|------|
|
||||
| **규격 표준화** | 사이즈/재질이 정해져 있음 | 가이드레일 2438mm, 3000mm |
|
||||
| **수요 빈도 높음** | 자주 출고되는 품목 | 주력 제품의 핵심 부품 |
|
||||
| **가공 시간 김** | 만들기 시간이 오래 걸림 | 절곡 가공 (절단→벤딩→용접) |
|
||||
| **보관 용이** | 장기 보관해도 품질 저하 없음 | 금속 부품 (부식 방지 처리 완료) |
|
||||
|
||||
> **주의**: 주문 제작품(고객 맞춤 사이즈)은 재공품 대상이 아니다. 표준 규격품만 해당한다.
|
||||
|
||||
---
|
||||
|
||||
## 4. SAM 시스템에서의 처리 방식
|
||||
|
||||
### 4.1 설계 원칙
|
||||
|
||||
SAM은 **수주 → 생산지시 → 작업지시 → 생산**의 흐름으로 동작한다. 수주가 없으면 생산지시를 생성할 수 없는 구조이다.
|
||||
|
||||
재공품 생산은 수주가 없지만 생산이 필요한 경우이므로, **내부 오더(Internal Order)** 개념을 도입하여 해결한다.
|
||||
|
||||
```
|
||||
일반 수주: 고객 주문 → 수주 등록 → 생산지시 → 작업지시 → 생산
|
||||
재공품 생산: (주문 없음) → 재고생산 등록 → 생산지시 → 작업지시 → 생산
|
||||
↑
|
||||
내부 오더 (order_type_code = 'STOCK')
|
||||
```
|
||||
|
||||
### 4.2 기존 테이블 공유
|
||||
|
||||
재공품 생산을 위해 별도 테이블을 만들지 않는다. 기존 `orders` 테이블에 `order_type_code = 'STOCK'`을 추가하여 구분한다.
|
||||
|
||||
```
|
||||
orders 테이블
|
||||
├── ORDER → 고객 수주 (거래처 주문)
|
||||
├── PURCHASE → 발주 (자재 구매)
|
||||
└── STOCK → 재고생산 (내부 오더, 재공품)
|
||||
```
|
||||
|
||||
**이유**:
|
||||
- 하류 시스템(작업지시, 생산, 품질검사, 출하)을 **변경 없이** 재활용
|
||||
- 생산 통계에 재공품 생산량도 **자동 포함**
|
||||
- 이력 관리(누가, 언제, 얼마나 재공품을 생산했는지) **기존 구조로 추적**
|
||||
|
||||
### 4.3 재공품 생산 흐름
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ 1. 재고생산 등록 │
|
||||
│ ├─ 품목 선택 (이미 정해진 재공품) │
|
||||
│ ├─ 수량 입력 │
|
||||
│ ├─ 생산 사유 입력 (선택) │
|
||||
│ └─ order_type_code = 'STOCK' 자동 설정 │
|
||||
│ │
|
||||
│ 2. 재고생산 확정 │
|
||||
│ ├─ 상태: DRAFT → CONFIRMED │
|
||||
│ └─ ※ 매출 생성 안 함 (내부 오더이므로) │
|
||||
│ │
|
||||
│ 3. 생산지시 생성 │
|
||||
│ ├─ 절곡 공정 자동 선택 │
|
||||
│ ├─ 현장명 = '재고생산' 자동 설정 │
|
||||
│ ├─ 작업예정일 = 오늘 날짜 │
|
||||
│ └─ 작업지시(WorkOrder) 생성 │
|
||||
│ │
|
||||
│ 4. 절곡 작업 수행 │
|
||||
│ ├─ 작업자가 절곡 공정 수행 │
|
||||
│ ├─ 자재 투입 기록 │
|
||||
│ ├─ 중간검사 │
|
||||
│ └─ 작업 완료 처리 │
|
||||
│ │
|
||||
│ 5. 재고 입고 │
|
||||
│ ├─ 완성된 재공품 → 재고(Stock Lot) 등록 │
|
||||
│ └─ 향후 수주 시 재고에서 출고 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.4 일반 수주와의 차이
|
||||
|
||||
| 항목 | 일반 수주 | 재공품 생산 |
|
||||
|------|----------|-----------|
|
||||
| 트리거 | 고객 주문 | 생산 계획 (유휴시간 활용) |
|
||||
| 거래처 | 있음 | 없음 (내부 오더) |
|
||||
| 견적 | 있음 (선택) | 없음 |
|
||||
| 납기 | 고객 요청일 | 없음 (가능한 빨리) |
|
||||
| 공정 선택 | BOM 기반 자동 매칭 | 절곡 공정 고정 |
|
||||
| 금액/매출 | 계산 + 매출 인식 | 없음 |
|
||||
| 현장명 | 고객 현장 | '재고생산' 고정 |
|
||||
| 채번 | `ORD20260316xxxx` | `STK20260316xxxx` |
|
||||
| 생산 결과 | 고객 출하 | 재고 입고 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 재공품 재고 관리
|
||||
|
||||
### 5.1 재공품 재고의 생명주기
|
||||
|
||||
```
|
||||
재공품 생산 완료
|
||||
↓
|
||||
재고 입고 (Stock Lot 생성)
|
||||
↓
|
||||
재고 보관 (창고/적재대)
|
||||
↓
|
||||
수주 접수 → 재고 확인
|
||||
↓
|
||||
재고에서 출고 → 조립 → 완성품
|
||||
↓
|
||||
고객 출하
|
||||
```
|
||||
|
||||
### 5.2 재고 확인 시점
|
||||
|
||||
수주가 들어오면 시스템에서 **해당 재공품이 재고에 있는지 자동 확인**한다:
|
||||
|
||||
- **재고 있음** → 절곡 공정 스킵, 바로 조립 단계로 이동 → 납기 단축
|
||||
- **재고 없음** → 일반 생산 흐름 (절곡 공정부터 시작)
|
||||
|
||||
### 5.3 안전재고와 목표 수량
|
||||
|
||||
재고생산 등록 시 `목표 재고 수량(target_stock_qty)`을 설정할 수 있다.
|
||||
|
||||
| 항목 | 설명 |
|
||||
|------|------|
|
||||
| 목표 재고 수량 | 이 수량만큼 재고를 유지하고 싶은 목표 |
|
||||
| 현재 재고 수량 | Stock Lot에서 조회 |
|
||||
| 생산 필요 수량 | 목표 - 현재 = 부족분 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 제조업 공통 패턴
|
||||
|
||||
### 6.1 Make-to-Stock (MTS) vs Make-to-Order (MTO)
|
||||
|
||||
SAM 시스템은 기본적으로 **MTO(주문생산)** 방식이다. 재공품 생산은 **MTS(재고생산)** 방식을 부분적으로 도입한 것이다.
|
||||
|
||||
| 전략 | 설명 | SAM 적용 |
|
||||
|------|------|----------|
|
||||
| **MTO** (주문생산) | 수주 → 생산 | 일반 수주 (`ORDER`) |
|
||||
| **MTS** (재고생산) | 예측 → 생산 → 재고 | 재고생산 (`STOCK`) |
|
||||
| **ATO** (주문조립) | 재공품 재고 + 수주 → 조립 | MTS + MTO 결합 |
|
||||
|
||||
블라인드/스크린 제조에서는 **ATO 패턴**이 가장 효율적이다:
|
||||
|
||||
```
|
||||
MTS: 표준 재공품 미리 생산 (절곡)
|
||||
↓
|
||||
ATO: 수주 → 재공품 + 맞춤 부품 → 조립 → 출하
|
||||
↓
|
||||
납기 단축 + 유휴시간 활용
|
||||
```
|
||||
|
||||
### 6.2 다른 제조업 적용 사례
|
||||
|
||||
재공품 생산은 블라인드/스크린에 국한되지 않는다. **모든 제조업**에서 동일한 패턴이 적용된다:
|
||||
|
||||
| 업종 | 원자재 | 재공품 (WIP) | 완성품 |
|
||||
|------|--------|-------------|--------|
|
||||
| **블라인드/스크린** | 알루미늄 코일, 철판 | 가이드레일, 케이스, 바텀바 | 블라인드, 스크린 |
|
||||
| **가구** | 목재, MDF | 재단된 판재, 엣지밴딩 부품 | 책상, 의자, 캐비닛 |
|
||||
| **자동차** | 철강, 플라스틱 | 프레스 부품, 엔진 블록 | 자동차 |
|
||||
| **전자제품** | PCB 원판, 칩 | 조립된 PCB, 하우징 | 스마트폰, TV |
|
||||
| **식품** | 밀가루, 설탕 | 반죽, 소스 | 빵, 과자 |
|
||||
| **의류** | 원단, 실 | 재단 원단, 염색 원단 | 완성 의류 |
|
||||
|
||||
### 6.3 재공품 생산의 핵심 가치
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ 💰 비용 절감 │
|
||||
│ 유휴 인건비를 생산으로 전환 │
|
||||
│ → 작업자가 놀지 않고 가치를 창출 │
|
||||
│ │
|
||||
│ ⏱️ 납기 단축 │
|
||||
│ 수주 → 즉시 조립 가능 (절곡 공정 스킵) │
|
||||
│ → 고객 만족도 향상 │
|
||||
│ │
|
||||
│ 📊 생산 평준화 │
|
||||
│ 성수기/비수기 작업량 균등화 │
|
||||
│ → 잔업 감소, 품질 안정 │
|
||||
│ │
|
||||
│ 🚀 경쟁력 확보 │
|
||||
│ 빠른 납기 = 수주 확보 │
|
||||
│ → 매출 증대 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 주의사항
|
||||
|
||||
### 7.1 과잉 생산 방지
|
||||
|
||||
재공품을 너무 많이 만들면 **재고 비용 증가**와 **사장 재고(불용 재고)** 문제가 발생한다.
|
||||
|
||||
| 위험 | 설명 | 대응 |
|
||||
|------|------|------|
|
||||
| 과잉 재고 | 수요보다 많이 생산 | 목표 수량 설정, 주기적 재고 점검 |
|
||||
| 사장 재고 | 규격 변경/단종으로 사용 불가 | 표준 규격품만 대상, 수요 예측 기반 |
|
||||
| 보관 비용 | 창고 공간 점유 | 적정 재고 수준 유지 |
|
||||
| 품질 저하 | 장기 보관 시 녹/변색 | 보관 환경 관리, 선입선출(FIFO) |
|
||||
|
||||
### 7.2 생산 대상 품목 선정 기준
|
||||
|
||||
```
|
||||
❌ 주문 맞춤 제작품 (고객 사이즈)
|
||||
❌ 수요 불확실 품목
|
||||
❌ 원자재 가격 변동이 큰 품목
|
||||
❌ 보관이 어려운 품목
|
||||
|
||||
✅ 표준 규격품 (정해진 사이즈)
|
||||
✅ 출고 빈도 높은 품목
|
||||
✅ 가공 시간이 긴 품목
|
||||
✅ 장기 보관 가능 품목
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [재고생산관리 기능 설명](../features/sales/stock-production.md)
|
||||
- [재고생산관리 API 명세](../frontend/api-specs/stock-production-api.md)
|
||||
- [품목 정책](item-policy.md)
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-16
|
||||
Reference in New Issue
Block a user