거래처 관리 정책 (Client Management Policy)
작성일: 2025-12-08
상태: 설계 확정
관련 요청: docs/front/[API-2025-12-04] client-api-analysis.md
1. 개요
1.1 목적
- 거래처 마스터 통합 관리 (매입처/매출처/매입매출)
- 고객그룹 기반 단가 정책 연계
- 세금계산서 합의 및 불량 채권 관리
- 주문/발주 연동을 위한 거래처 기반 시스템
1.2 핵심 원칙
| 원칙 |
설명 |
| 거래처 유형 분류 |
매입, 매출, 매입매출로 구분 관리 |
| 코드 유일성 |
tenant 내 client_code 중복 불가 |
| 그룹 기반 단가 |
고객그룹별 차등 판매가 적용 |
| 연관 데이터 보호 |
주문 존재 시 삭제 불가 |
2. 테이블 구조
2.1 ERD 개요
2.2 clients 테이블 (거래처 마스터)
CREATE TABLE clients (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '테넌트 ID',
client_group_id BIGINT UNSIGNED NULL COMMENT '고객그룹 ID',
-- 기본 정보 --
client_code VARCHAR(50) NOT NULL COMMENT '거래처 코드',
name VARCHAR(100) NOT NULL COMMENT '거래처명',
client_type VARCHAR(20) NULL COMMENT '거래처 유형 (매입/매출/매입매출)',
is_active TINYINT(1) DEFAULT 1 COMMENT '활성여부(1=활성,0=비활성)',
-- 사업자 정보 --
business_no VARCHAR(20) NULL COMMENT '사업자등록번호',
business_type VARCHAR(50) NULL COMMENT '업태',
business_item VARCHAR(100) NULL COMMENT '업종',
-- 연락처 정보 --
contact_person VARCHAR(50) NULL COMMENT '담당자명',
phone VARCHAR(30) NULL COMMENT '전화번호',
mobile VARCHAR(20) NULL COMMENT '휴대폰',
fax VARCHAR(20) NULL COMMENT '팩스',
email VARCHAR(80) NULL COMMENT '이메일',
address VARCHAR(255) NULL COMMENT '주소',
-- 담당자 정보 --
manager_name VARCHAR(50) NULL COMMENT '당사 담당자명',
manager_tel VARCHAR(20) NULL COMMENT '당사 담당자 연락처',
system_manager VARCHAR(50) NULL COMMENT '시스템 담당자',
-- 계정 정보 --
account_id VARCHAR(50) NULL COMMENT '계정 ID',
account_password VARCHAR(255) NULL COMMENT '계정 비밀번호 (hidden)',
-- 발주/결제 설정 --
purchase_payment_day VARCHAR(20) NULL COMMENT '매입 결제일',
sales_payment_day VARCHAR(20) NULL COMMENT '매출 결제일',
-- 세금계산서 합의 --
tax_agreement BOOLEAN DEFAULT FALSE COMMENT '세금계산서 합의 여부',
tax_amount DECIMAL(15,2) NULL COMMENT '합의 금액',
tax_start_date DATE NULL COMMENT '합의 시작일',
tax_end_date DATE NULL COMMENT '합의 종료일',
-- 불량 채권 관리 --
bad_debt BOOLEAN DEFAULT FALSE COMMENT '불량 채권 여부',
bad_debt_amount DECIMAL(15,2) NULL COMMENT '불량 채권 금액',
bad_debt_receive_date DATE NULL COMMENT '채권 발생일',
bad_debt_end_date DATE NULL COMMENT '채권 종료일',
bad_debt_progress VARCHAR(20) NULL COMMENT '진행 상태',
-- 기타 --
memo TEXT NULL COMMENT '메모',
-- 감사 컬럼 --
created_by BIGINT UNSIGNED NULL COMMENT '생성자 ID',
updated_by BIGINT UNSIGNED NULL COMMENT '수정자 ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- 인덱스 --
INDEX idx_clients_tenant (tenant_id),
INDEX idx_clients_code (tenant_id, client_code),
INDEX idx_clients_group (tenant_id, client_group_id),
INDEX idx_clients_type (tenant_id, client_type),
INDEX idx_clients_active (tenant_id, is_active),
UNIQUE idx_clients_unique (tenant_id, client_code),
FOREIGN KEY (client_group_id) REFERENCES client_groups(id) ON DELETE SET NULL
) COMMENT='거래처 마스터';
2.3 client_groups 테이블 (고객 그룹)
3. 거래처 유형 정책
3.1 거래처 유형 (client_type)
| 유형 |
설명 |
용도 |
| 매입 |
자재/상품 구매처 |
발주, 입고, 매입 관리 |
| 매출 |
제품/상품 판매처 |
주문, 출고, 매출 관리 |
| 매입매출 |
양방향 거래처 |
매입+매출 모두 가능 |
3.2 유형별 업무 흐름
4. 고객그룹과 단가 연계
4.1 단가 적용 우선순위
4.2 단가 비율 적용 (price_rate)
4.3 그룹 활용 예시
| 그룹 코드 |
그룹명 |
price_rate |
설명 |
DEFAULT |
일반 고객 |
1.0000 |
정가 적용 |
VIP |
VIP 고객 |
0.9000 |
10% 할인 |
WHOLESALE |
도매 거래처 |
0.8000 |
20% 할인 |
PARTNER |
협력 업체 |
0.8500 |
15% 할인 |
5. 세금계산서 합의 관리
5.1 합의 정보 구조
| 필드 |
설명 |
용도 |
tax_agreement |
합의 여부 |
세금계산서 발행 방식 결정 |
tax_amount |
합의 금액 |
월정액 또는 고정 금액 |
tax_start_date |
시작일 |
합의 유효 기간 시작 |
tax_end_date |
종료일 |
합의 유효 기간 종료 |
5.2 합의 유형
6. 불량 채권 관리
6.1 불량 채권 정보 구조
| 필드 |
설명 |
bad_debt |
불량 채권 여부 |
bad_debt_amount |
불량 채권 금액 |
bad_debt_receive_date |
채권 발생일 |
bad_debt_end_date |
채권 종료(해결)일 |
bad_debt_progress |
진행 상태 |
6.2 진행 상태 (bad_debt_progress)
6.3 불량 채권 상태값
| 상태 |
설명 |
후속 조치 |
협의중 |
채권 회수 협의 진행 |
정기 연락, 분할 상환 협의 |
소송중 |
법적 절차 진행 |
법무팀 연계, 소송 진행 |
회수완료 |
채권 전액 회수 |
bad_debt_end_date 기록 |
대손처리 |
회수 불가 판정 |
회계 처리, 거래 중단 검토 |
7. 상태 관리
7.1 활성 상태 (is_active)
7.2 상태별 제약
| 상태 |
주문 생성 |
발주 생성 |
조회 |
수정 |
true (활성) |
✅ |
✅ |
✅ |
✅ |
false (비활성) |
❌ |
❌ |
✅ |
✅ |
7.3 비활성화 고려 사항
- 불량 채권 거래처: bad_debt = true 시 비활성화 검토
- 장기 미거래: 12개월 이상 거래 없을 시 비활성화 검토
- 사업자 폐업: 사업자등록 말소 확인 시 비활성화
8. API 엔드포인트
8.1 엔드포인트 목록
| Method |
Endpoint |
설명 |
우선순위 |
| GET |
/api/v1/clients |
거래처 목록 조회 |
🔴 필수 |
| GET |
/api/v1/clients/{id} |
거래처 상세 조회 |
🔴 필수 |
| POST |
/api/v1/clients |
거래처 등록 |
🔴 필수 |
| PUT |
/api/v1/clients/{id} |
거래처 수정 |
🔴 필수 |
| DELETE |
/api/v1/clients/{id} |
거래처 삭제 |
🔴 필수 |
| POST |
/api/v1/clients/{id}/toggle |
활성/비활성 토글 |
🟡 중요 |
| GET |
/api/v1/client-groups |
고객그룹 목록 |
🟡 중요 |
| POST |
/api/v1/client-groups |
고객그룹 등록 |
🟢 권장 |
8.2 목록 조회 API
Query Parameters:
| 파라미터 |
타입 |
설명 |
page |
int |
페이지 번호 (기본: 1) |
size |
int |
페이지당 개수 (기본: 20) |
q |
string |
검색어 (거래처명, 코드, 담당자) |
only_active |
bool |
활성 거래처만 조회 |
Response:
9. 비즈니스 규칙
9.1 검증 규칙
| 규칙 |
설명 |
| R1 |
client_code는 tenant 내 유일해야 함 |
| R2 |
client_code, name은 필수 값 |
| R3 |
client_type은 '매입', '매출', '매입매출' 중 하나 |
| R4 |
주문이 존재하는 거래처는 삭제 불가 |
| R5 |
email 형식 검증 |
| R6 |
bad_debt_progress는 지정된 값만 허용 |
| R7 |
tax_start_date ≤ tax_end_date |
9.2 코드 중복 처리
9.3 삭제 정책
| 테이블 |
삭제 방식 |
설명 |
clients |
Hard Delete |
연관 주문이 없는 경우만 삭제 가능 |
client_groups |
Soft Delete |
deleted_at 컬럼 사용 |
- 연관 데이터 보호: orders 존재 시
error.has_orders 반환
- 주문 있는 거래처: 비활성화(
is_active = false)로 처리 권장
9.4 비밀번호 보호
account_password는 API 응답에서 자동 제외
- 저장 시 평문 저장 (필요시 암호화 적용 검토)
10. 필드 분류
10.1 기본 정보 (4개)
| 필드 |
타입 |
필수 |
설명 |
client_code |
string(50) |
✅ |
거래처 코드 |
name |
string(100) |
✅ |
거래처명 |
client_type |
enum |
❌ |
매입/매출/매입매출 |
is_active |
boolean |
❌ |
활성 상태 (기본: true) |
10.2 사업자 정보 (3개)
| 필드 |
타입 |
필수 |
설명 |
business_no |
string(20) |
❌ |
사업자등록번호 |
business_type |
string(50) |
❌ |
업태 |
business_item |
string(100) |
❌ |
업종 |
10.3 연락처 정보 (6개)
| 필드 |
타입 |
필수 |
설명 |
contact_person |
string(50) |
❌ |
담당자명 |
phone |
string(30) |
❌ |
전화번호 |
mobile |
string(20) |
❌ |
휴대폰 |
fax |
string(20) |
❌ |
팩스 |
email |
string(80) |
❌ |
이메일 |
address |
string(255) |
❌ |
주소 |
10.4 담당자 정보 (3개)
| 필드 |
타입 |
필수 |
설명 |
manager_name |
string(50) |
❌ |
당사 담당자명 |
manager_tel |
string(20) |
❌ |
당사 담당자 연락처 |
system_manager |
string(50) |
❌ |
시스템 담당자 |
10.5 계정/발주 정보 (4개)
| 필드 |
타입 |
필수 |
설명 |
account_id |
string(50) |
❌ |
계정 ID |
account_password |
string(255) |
❌ |
계정 비밀번호 (hidden) |
purchase_payment_day |
string(20) |
❌ |
매입 결제일 |
sales_payment_day |
string(20) |
❌ |
매출 결제일 |
10.6 세금계산서 합의 (4개)
| 필드 |
타입 |
필수 |
설명 |
tax_agreement |
boolean |
❌ |
합의 여부 |
tax_amount |
decimal(15,2) |
❌ |
합의 금액 |
tax_start_date |
date |
❌ |
합의 시작일 |
tax_end_date |
date |
❌ |
합의 종료일 |
10.7 불량 채권 (5개)
| 필드 |
타입 |
필수 |
설명 |
bad_debt |
boolean |
❌ |
불량 채권 여부 |
bad_debt_amount |
decimal(15,2) |
❌ |
불량 채권 금액 |
bad_debt_receive_date |
date |
❌ |
채권 발생일 |
bad_debt_end_date |
date |
❌ |
채권 종료일 |
bad_debt_progress |
enum |
❌ |
진행 상태 |
10.8 기타 (2개)
| 필드 |
타입 |
필수 |
설명 |
client_group_id |
bigint |
❌ |
고객그룹 ID |
memo |
text |
❌ |
메모 |
11. 관련 문서
최종 업데이트: 2025-12-08