feat(purchase): 생산소모품 구매 관리 시스템 구현

tkuser: 업체(공급업체) CRUD + 소모품 마스터 CRUD (사진 업로드 포함)
tkfb: 구매신청 → 구매 처리 → 월간 분석/정산 전체 워크플로
설비(equipment) 분류 구매 시 자동 등록 + 실패 시 admin 알림

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-13 21:21:59 +09:00
parent 1abdb92a71
commit 3623551a6b
29 changed files with 2581 additions and 1 deletions

View File

@@ -0,0 +1,102 @@
-- 생산소모품 구매 관리 시스템 테이블
-- 업체 (tkuser에서 CRUD)
CREATE TABLE IF NOT EXISTS vendors (
vendor_id INT AUTO_INCREMENT PRIMARY KEY,
vendor_name VARCHAR(100) NOT NULL,
business_number VARCHAR(20),
representative VARCHAR(50),
contact_name VARCHAR(50),
contact_phone VARCHAR(20),
address VARCHAR(200),
bank_name VARCHAR(50),
bank_account VARCHAR(50),
notes TEXT,
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 소모품 마스터 (tkuser에서 CRUD)
CREATE TABLE IF NOT EXISTS consumable_items (
item_id INT AUTO_INCREMENT PRIMARY KEY,
item_name VARCHAR(100) NOT NULL,
maker VARCHAR(100),
category ENUM('consumable','safety','repair','equipment') NOT NULL
COMMENT '소모품, 안전용품, 수선비, 설비',
base_price DECIMAL(12,0) DEFAULT 0,
unit VARCHAR(20) DEFAULT 'EA',
photo_path VARCHAR(255),
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uq_name_maker (item_name, maker)
);
-- 구매신청 (tkfb에서 CRUD)
CREATE TABLE IF NOT EXISTS purchase_requests (
request_id INT AUTO_INCREMENT PRIMARY KEY,
item_id INT NOT NULL,
quantity INT NOT NULL DEFAULT 1,
requester_id INT NOT NULL COMMENT 'FK → sso_users.user_id',
request_date DATE NOT NULL,
status ENUM('pending','purchased','hold') DEFAULT 'pending'
COMMENT '대기, 구매완료, 보류',
hold_reason TEXT,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (item_id) REFERENCES consumable_items(item_id),
FOREIGN KEY (requester_id) REFERENCES sso_users(user_id)
);
-- 구매 내역 (tkfb에서 CRUD)
CREATE TABLE IF NOT EXISTS purchases (
purchase_id INT AUTO_INCREMENT PRIMARY KEY,
request_id INT,
item_id INT NOT NULL,
vendor_id INT,
quantity INT NOT NULL DEFAULT 1,
unit_price DECIMAL(12,0) NOT NULL,
purchase_date DATE NOT NULL,
purchaser_id INT NOT NULL COMMENT 'FK → sso_users.user_id',
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (item_id) REFERENCES consumable_items(item_id),
FOREIGN KEY (request_id) REFERENCES purchase_requests(request_id),
FOREIGN KEY (vendor_id) REFERENCES vendors(vendor_id),
FOREIGN KEY (purchaser_id) REFERENCES sso_users(user_id)
);
-- 가격 변동 이력
CREATE TABLE IF NOT EXISTS consumable_price_history (
history_id INT AUTO_INCREMENT PRIMARY KEY,
item_id INT NOT NULL,
old_price DECIMAL(12,0),
new_price DECIMAL(12,0) NOT NULL,
changed_by INT COMMENT 'FK → sso_users.user_id',
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (item_id) REFERENCES consumable_items(item_id)
);
-- 월간 정산
CREATE TABLE IF NOT EXISTS monthly_settlements (
settlement_id INT AUTO_INCREMENT PRIMARY KEY,
year_month VARCHAR(7) NOT NULL COMMENT 'YYYY-MM',
vendor_id INT NOT NULL,
total_amount DECIMAL(12,0) DEFAULT 0,
status ENUM('pending','completed') DEFAULT 'pending',
completed_at TIMESTAMP NULL,
completed_by INT COMMENT 'FK → sso_users.user_id',
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (vendor_id) REFERENCES vendors(vendor_id),
UNIQUE KEY uq_ym_vendor (year_month, vendor_id)
);
-- 페이지 키 등록
INSERT IGNORE INTO pages (page_key, page_name, page_path, category, is_admin_only, display_order) VALUES
('purchase.request', '구매신청', '/pages/purchase/request.html', 'purchase', 0, 40),
('purchase.analysis', '구매 분석', '/pages/admin/purchase-analysis.html', 'purchase', 1, 41);