Search

8일차) 미니 프로젝트

<미니 프로젝트>에서 사용될 기술 스택
자바 17 버전
Spring Boot 3XX
JPA
MySQL
<미니 프로젝트>에서는 간단한 출퇴근 사내 시스템을 만들어 가게 됩니다!
화면까지 개발할 필요는 없고, 각 기능 을 담당하는 API가 있어, API의 역할을 설명할 수 있다면 충분합니다.
직원 저장 기능 ( POST/member )을 사용하면 직원이 데이터베이스에 저장되는데, 이렇게 저장된 직원은 직원 조회 기능 (GET/member )을 통해 확인할 수 있습니다.

미니 프로젝트

1단계

팀 및 직원 등록 및 조회
Team
package com.inhousecommutingsystem.inhousecommutingsystem.domain; @Entity @Setter @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Team { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String manager; @OneToMany(mappedBy = "team") @JsonIgnore private List<Employee> employees; }
Java
복사
뒤에서 직원 조회할때 무한 참조 걸려서 포스트맨 터져버림..ㅋ ㅋ ㅋ ㅋ 그래서 @JsonIgnore 추가
TeamController
package com.inhousecommutingsystem.controller; @RestController @RequestMapping("/teams") public class TeamController { private final TeamService teamService; public TeamController(TeamService teamService) { this.teamService = teamService; } @GetMapping public List<Team> getAllTeams() { return teamService.getAllTeams(); } @PostMapping public Team saveTeam(@RequestBody Team team) { return teamService.saveTeam(team); } }
Java
복사
TeamService
package com.inhousecommutingsystem.service; @Service public class TeamService { private final TeamRepository teamRepository; public TeamService(TeamRepository teamRepository) { this.teamRepository = teamRepository; } public List<Team> getAllTeams() { return teamRepository.findAll(); } public Team saveTeam(Team team) { return teamRepository.save(team); } }
Java
복사
TeamRepository
package com.inhousecommutingsystem.repository; import com.inhousecommutingsystem.domain.Team; import org.springframework.data.jpa.repository.JpaRepository; public interface TeamRepository extends JpaRepository<Team, Long> { }
Java
복사
Employee
package com.inhousecommutingsystem.domain; @Entity @Setter @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private boolean isManager; private Date birthDate; private Date workStartDate; @ManyToOne @JoinColumn(name = "team_id") private Team team; }
Java
복사
EmployeeController
package com.inhousecommutingsystem.controller; @RestController @RequestMapping("/employees") public class EmployeeController { private final EmployeeService employeeService; public EmployeeController(EmployeeService employeeService) { this.employeeService = employeeService; } @GetMapping public List<Employee> getAllEmployees() { return employeeService.getAllEmployees(); } @PostMapping public Employee saveEmployee(@RequestBody Employee employee) { return employeeService.saveEmployee(employee); } }
Java
복사
EmployeeService
package com.inhousecommutingsystem.service; @Service public class EmployeeService { private final EmployeeRepository employeeRepository; public EmployeeService(EmployeeRepository employeeRepository) { this.employeeRepository = employeeRepository; } public List<Employee> getAllEmployees() { return employeeRepository.findAll(); } public Employee saveEmployee(Employee employee) { return employeeRepository.save(employee); } }
Java
복사
EmployeeRepository
package com.inhousecommutingsystem.repository; public interface EmployeeRepository extends JpaRepository<Employee, Long> { }
Java
복사
무한 참조걸려서 수정하고 다시 찍은거라 id값이 위에 사진하고 다름…

2단계

출퇴근 기능
Attendance
package com.inhousecommutingsystem.domain; @Entity @Setter @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Attendance { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "employee_id") private Employee employee; private LocalDateTime clockInTime; private LocalDateTime clockOutTime; }
Java
복사
AttendanceRepository
package com.inhousecommutingsystem.repository; public interface AttendanceRepository extends JpaRepository<Attendance, Long> { }
Java
복사
AttendanceController
package com.inhousecommutingsystem.controller; @RestController @RequestMapping("/attendances") public class AttendanceController { private final AttendanceService attendanceService; public AttendanceController(AttendanceService attendanceService) { this.attendanceService = attendanceService; } @GetMapping public List<Attendance> getAllAttendances() { return attendanceService.getAllAttendances(); } @PostMapping public Attendance saveAttendance(@RequestBody Attendance attendance) { return attendanceService.saveAttendance(attendance); } }
Java
복사
AttendanceService
package com.inhousecommutingsystem.service; @Service public class AttendanceService { private final AttendanceRepository attendanceRepository; public AttendanceService(AttendanceRepository attendanceRepository) { this.attendanceRepository = attendanceRepository; } public List<Attendance> getAllAttendances() { return attendanceRepository.findAll(); } public Attendance saveAttendance(Attendance attendance) { return attendanceRepository.save(attendance); } }
Java
복사
출퇴근 등록
출퇴근 조회

3단계

연차 기능
Leave
package com.inhousecommutingsystem.domain; @Entity @Setter @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Leave { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "employee_id") private Employee employee; private LocalDate date; private boolean isUsingDayOff; }
Java
복사
LeaveController
package com.inhousecommutingsystem.controller; @RestController @RequestMapping("/leaves") public class LeaveController { private final LeaveService leaveService; public LeaveController(LeaveService leaveService) { this.leaveService = leaveService; } @GetMapping public List<Leave> getAllLeaves() { return leaveService.getAllLeaves(); } @PostMapping public Leave saveLeave(@RequestBody Leave leave) { return leaveService.saveLeave(leave); } }
Java
복사
LeaveService
package com.inhousecommutingsystem.service; @Service public class LeaveService { private final LeaveRepository leaveRepository; public LeaveService(LeaveRepository leaveRepository) { this.leaveRepository = leaveRepository; } public List<Leave> getAllLeaves() { return leaveRepository.findAll(); } public Leave saveLeave(Leave leave) { return leaveRepository.save(leave); } }
Java
복사
LeaveRepository
package com.inhousecommutingsystem.repository; public interface LeaveRepository extends JpaRepository<Leave, Long> { }
Java
복사
연차 등록
연차 조회
지금 보니까 일 시작날짜랑 연차등록한 날짜 과거 미래인데..ㅋㅋㅋ
이런것도 나중에 밸리체크 로직넣으면 좋을거같음

4단계

초과 근무
Attendance
package com.inhousecommutingsystem.domain; @Entity @Setter @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Attendance { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "employee_id") private Employee employee; private LocalDateTime clockInTime; private LocalDateTime clockOutTime; private int overtimeMinutes; }
Java
복사
OvertimeController
package com.inhousecommutingsystem.controller; @RestController @RequestMapping("/overtime") public class OvertimeController { private final AttendanceService attendanceService; public OvertimeController(AttendanceService attendanceService) { this.attendanceService = attendanceService; } @GetMapping public int calculateOvertime(@RequestParam Long employeeId, @RequestParam String month) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); LocalDateTime start = LocalDateTime.parse(month + "-01T00:00:00"); LocalDateTime end = start.plusMonths(1).minusSeconds(1); return attendanceService.calculateOvertime(employeeId, start, end); } }
Java
복사
AttendanceService
public int calculateOvertime(Long employeeId, LocalDateTime start, LocalDateTime end) { List<Attendance> attendances = attendanceRepository.findByEmployeeIdAndClockInTimeBetween(employeeId, start, end); int totalOvertimeMinutes = 0; for (Attendance attendance : attendances) { if (attendance.getClockOutTime() != null) { Duration workDuration = Duration.between(attendance.getClockInTime(), attendance.getClockOutTime()); long workMinutes = workDuration.toMinutes(); if (workMinutes > 480) { // 8시간 (480분) 초과 근무 시간 계산 totalOvertimeMinutes += workMinutes - 480; } } } return totalOvertimeMinutes; }
Java
복사
Duration은 두 시간 객체사이의 간격을 알고싶을 때 사용
AttendanceRepository
package com.inhousecommutingsystem.repository; public interface AttendanceRepository extends JpaRepository<Attendance, Long> { List<Attendance> findByEmployeeIdAndClockInTimeBetween(Long employeeId, LocalDateTime start, LocalDateTime end); }
Java
복사
8시간 일해야하는데
9시에 출근해서 18시에 퇴근해서 1시간 경과해서 60분 찍힘~

참고

챗GPT