const PurchaseRequestModel = require('../models/purchaseRequestModel'); const PurchaseModel = require('../models/purchaseModel'); const { saveBase64Image } = require('../services/imageUploadService'); const logger = require('../utils/logger'); const PurchaseRequestController = { // 구매신청 목록 getAll: async (req, res) => { try { const { status, category, from_date, to_date } = req.query; const isAdmin = req.user && ['admin', 'system'].includes(req.user.access_level); const filters = { status, category, from_date, to_date }; if (!isAdmin) filters.requester_id = req.user.id; const rows = await PurchaseRequestModel.getAll(filters); res.json({ success: true, data: rows }); } catch (err) { logger.error('PurchaseRequest getAll error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } }, // 구매신청 상세 getById: async (req, res) => { try { const row = await PurchaseRequestModel.getById(req.params.id); if (!row) return res.status(404).json({ success: false, message: '신청 건을 찾을 수 없습니다.' }); res.json({ success: true, data: row }); } catch (err) { logger.error('PurchaseRequest getById error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } }, // 구매신청 생성 create: async (req, res) => { try { const { item_id, custom_item_name, custom_category, quantity, notes, photo } = req.body; // item_id 또는 custom_item_name 중 하나 필수 if (!item_id && !custom_item_name) { return res.status(400).json({ success: false, message: '소모품을 선택하거나 품목명을 입력해주세요.' }); } if (!quantity || quantity < 1) { return res.status(400).json({ success: false, message: '수량은 1 이상이어야 합니다.' }); } if (!item_id && custom_item_name && !custom_category) { return res.status(400).json({ success: false, message: '직접 입력 시 분류를 선택해주세요.' }); } // 사진 업로드 let photo_path = null; if (photo) { photo_path = await saveBase64Image(photo, 'pr', 'purchase_requests'); } const request = await PurchaseRequestModel.create({ item_id: item_id || null, custom_item_name: custom_item_name || null, custom_category: custom_category || null, quantity, requester_id: req.user.id, request_date: new Date().toISOString().substring(0, 10), notes, photo_path }); res.status(201).json({ success: true, data: request, message: '구매신청이 등록되었습니다.' }); } catch (err) { logger.error('PurchaseRequest create error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } }, // 보류 처리 (admin) hold: async (req, res) => { try { const { hold_reason } = req.body; const request = await PurchaseRequestModel.hold(req.params.id, hold_reason); if (!request) return res.status(404).json({ success: false, message: '신청 건을 찾을 수 없습니다.' }); res.json({ success: true, data: request, message: '보류 처리되었습니다.' }); } catch (err) { logger.error('PurchaseRequest hold error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } }, // pending으로 되돌리기 (admin) revert: async (req, res) => { try { const request = await PurchaseRequestModel.revertToPending(req.params.id); if (!request) return res.status(404).json({ success: false, message: '신청 건을 찾을 수 없습니다.' }); res.json({ success: true, data: request, message: '대기 상태로 되돌렸습니다.' }); } catch (err) { logger.error('PurchaseRequest revert error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } }, // 삭제 (본인 + pending만) delete: async (req, res) => { try { const existing = await PurchaseRequestModel.getById(req.params.id); if (!existing) return res.status(404).json({ success: false, message: '신청 건을 찾을 수 없습니다.' }); const isAdmin = req.user && ['admin', 'system'].includes(req.user.access_level); if (!isAdmin && existing.requester_id !== req.user.id) { return res.status(403).json({ success: false, message: '본인의 신청만 삭제할 수 있습니다.' }); } const deleted = await PurchaseRequestModel.delete(req.params.id); if (!deleted) return res.status(400).json({ success: false, message: '대기 상태의 신청만 삭제할 수 있습니다.' }); res.json({ success: true, message: '삭제되었습니다.' }); } catch (err) { logger.error('PurchaseRequest delete error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } }, // 소모품 목록 (select용) getConsumableItems: async (req, res) => { try { const items = await PurchaseModel.getConsumableItems(); res.json({ success: true, data: items }); } catch (err) { logger.error('ConsumableItems get error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } }, // 업체 목록 (select용) getVendors: async (req, res) => { try { const vendors = await PurchaseModel.getVendors(); res.json({ success: true, data: vendors }); } catch (err) { logger.error('Vendors get error:', err); res.status(500).json({ success: false, message: '서버 오류가 발생했습니다.' }); } } }; module.exports = PurchaseRequestController;