feat: 다수 기능 개선 - 순찰, 출근, 작업분석, 모바일 UI 등
- 순찰/점검 기능 개선 (zone-detail 페이지 추가) - 출근/근태 시스템 개선 (연차 조회, 근무현황) - 작업분석 대분류 그룹화 및 마이그레이션 스크립트 - 모바일 네비게이션 UI 추가 - NAS 배포 도구 및 문서 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,9 +8,19 @@
|
||||
*/
|
||||
|
||||
const AttendanceModel = require('../models/attendanceModel');
|
||||
const vacationBalanceModel = require('../models/vacationBalanceModel');
|
||||
const { ValidationError, NotFoundError, DatabaseError } = require('../utils/errors');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
/**
|
||||
* 휴가 사용 유형 ID를 차감 일수로 변환
|
||||
* vacation_type_id: 1=연차(1일), 2=반차(0.5일), 3=반반차(0.25일)
|
||||
*/
|
||||
const getVacationDays = (vacationTypeId) => {
|
||||
const daysMap = { 1: 1, 2: 0.5, 3: 0.25 };
|
||||
return daysMap[vacationTypeId] || 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* 일일 근태 현황 조회
|
||||
*/
|
||||
@@ -63,8 +73,32 @@ const getDailyAttendanceRecordsService = async (date, workerId = null) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 기간별 근태 기록 조회 (월별 조회용)
|
||||
*/
|
||||
const getAttendanceRecordsByRangeService = async (startDate, endDate, workerId = null) => {
|
||||
if (!startDate || !endDate) {
|
||||
throw new ValidationError('시작 날짜와 종료 날짜가 필요합니다', {
|
||||
required: ['start_date', 'end_date'],
|
||||
received: { startDate, endDate }
|
||||
});
|
||||
}
|
||||
|
||||
logger.info('기간별 근태 기록 조회 요청', { startDate, endDate, workerId });
|
||||
|
||||
try {
|
||||
const records = await AttendanceModel.getDailyRecords(startDate, endDate, workerId);
|
||||
logger.info('기간별 근태 기록 조회 성공', { startDate, endDate, count: records.length });
|
||||
return records;
|
||||
} catch (error) {
|
||||
logger.error('기간별 근태 기록 조회 실패', { startDate, endDate, error: error.message });
|
||||
throw new DatabaseError('근태 기록 조회 중 데이터베이스 오류가 발생했습니다');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 근태 기록 생성/업데이트
|
||||
* - 휴가 기록 시 vacation_balance_details의 used_days 자동 연동
|
||||
*/
|
||||
const upsertAttendanceRecordService = async (recordData) => {
|
||||
const {
|
||||
@@ -88,9 +122,15 @@ const upsertAttendanceRecordService = async (recordData) => {
|
||||
});
|
||||
}
|
||||
|
||||
logger.info('근태 기록 저장 요청', { record_date, worker_id });
|
||||
logger.info('근태 기록 저장 요청', { record_date, worker_id, vacation_type_id });
|
||||
|
||||
try {
|
||||
// 1. 기존 기록 조회 (휴가 연동을 위해)
|
||||
const existingRecords = await AttendanceModel.getDailyAttendanceRecords(record_date, worker_id);
|
||||
const existingRecord = existingRecords.find(r => r.worker_id === worker_id);
|
||||
const previousVacationTypeId = existingRecord?.vacation_type_id || null;
|
||||
|
||||
// 2. 근태 기록 저장
|
||||
const result = await AttendanceModel.upsertAttendanceRecord({
|
||||
record_date,
|
||||
worker_id,
|
||||
@@ -101,6 +141,26 @@ const upsertAttendanceRecordService = async (recordData) => {
|
||||
created_by
|
||||
});
|
||||
|
||||
// 3. 휴가 잔액 연동 (vacation_balance_details.used_days 업데이트)
|
||||
const year = new Date(record_date).getFullYear();
|
||||
const previousDays = getVacationDays(previousVacationTypeId);
|
||||
const newDays = getVacationDays(vacation_type_id);
|
||||
|
||||
// 이전 휴가가 있었고 변경된 경우 → 복구 후 차감
|
||||
if (previousDays !== newDays) {
|
||||
// 이전 휴가 복구
|
||||
if (previousDays > 0) {
|
||||
await vacationBalanceModel.restoreByPriority(worker_id, year, previousDays);
|
||||
logger.info('휴가 잔액 복구', { worker_id, year, restored: previousDays });
|
||||
}
|
||||
|
||||
// 새 휴가 차감
|
||||
if (newDays > 0) {
|
||||
await vacationBalanceModel.deductByPriority(worker_id, year, newDays);
|
||||
logger.info('휴가 잔액 차감', { worker_id, year, deducted: newDays });
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('근태 기록 저장 성공', { record_date, worker_id });
|
||||
return result;
|
||||
} catch (error) {
|
||||
@@ -321,6 +381,7 @@ const saveCheckinsService = async (date, checkins) => {
|
||||
module.exports = {
|
||||
getDailyAttendanceStatusService,
|
||||
getDailyAttendanceRecordsService,
|
||||
getAttendanceRecordsByRangeService,
|
||||
upsertAttendanceRecordService,
|
||||
processVacationService,
|
||||
approveOvertimeService,
|
||||
|
||||
Reference in New Issue
Block a user