Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

미니 프로젝트 Step03 #18

Merged
merged 7 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.example.yeonghuns;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.time.Duration;
import java.time.LocalDate;
@SpringBootApplication
public class YeongHunsApplication {

public static void main(String[] args) {
SpringApplication.run(YeongHunsApplication.class, args);}
SpringApplication.run(YeongHunsApplication.class, args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ public enum ErrorCode {
METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "E2", "잘못된 HTTP 메서드를 호출했습니다."),
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "E3", "서버 에러가 발생했습니다."),
NOT_FOUND(HttpStatus.NOT_FOUND, "E4", "존재하지 않는 대상입니다."),
MESSAGE_NOT_READABLE(HttpStatus.BAD_REQUEST, "E5", "지원하지 않는 형식의 입력값입니다."),
MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "M1", "해당 멤버는 존재하지 않습니다."),
TEAM_NOT_FOUND(HttpStatus.NOT_FOUND, "T1", "해당 팀은 존재하지 않습니다."),
TEAM_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, "T2", "이미 동일한 이름의 팀이 존재하고 있습니다."),
CHECKOUT_NOT_PERFORMED(HttpStatus.BAD_REQUEST, "C1", "퇴근처리되지 않은 출근기록이 있습니다."),
IS_ALREADY_ATTENDANCE(HttpStatus.BAD_REQUEST, "C2", "이미 당일 출근내역이 존재합니다."),
COMMUTE_NOT_FOUND(HttpStatus.NOT_FOUND, "C3", "통근기록이 존재하지 않습니다."),
IS_ALREADY_DEPARTURE(HttpStatus.BAD_REQUEST, "C4", "출근처리를 먼저 하셔야합니다.")
IS_ALREADY_DEPARTURE(HttpStatus.BAD_REQUEST, "C4", "출근처리를 먼저 하셔야합니다."),
USING_ANNUAL_LEAVES(HttpStatus.BAD_REQUEST, "C5", "연차 사용일엔 출근할 수 없습니다."),
REQUEST_BEFORE_TODAY(HttpStatus.BAD_REQUEST, "A1", "연차요청은 과거가 될 수 없습니다."),
DECLINE_ANNUAL_LEAVE_REQUEST(HttpStatus.BAD_REQUEST, "A2", "팀에서 설정한 연차 규정에 맞지 않습니다."),
ALREADY_EXISTS_ANNUAL_LEAVE(HttpStatus.BAD_REQUEST, "A3", "이미 당일 연차 신청을 하셨습니다."),
NOT_REMAIN_ANNUAL_LEAVE(HttpStatus.BAD_REQUEST, "A4", "올해 연차를 모두 사용하셨습니다.")
;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.extern.slf4j.Slf4j;
import org.example.yeonghuns.config.Error.exception.CustomBaseException;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
Expand All @@ -25,14 +26,17 @@ protected ResponseEntity<ErrorResponse> handle(CustomBaseException e){

@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponse> handle(MethodArgumentNotValidException e){
e.getStackTrace();
log.error("MethodArgumentNotValidException", e);
return createErrorResponse(ErrorCode.INVALID_INPUT_VALUE);
}

@ExceptionHandler(HttpMessageNotReadableException.class)
protected ResponseEntity<ErrorResponse> handle(HttpMessageNotReadableException e){
log.error("HttpMessageNotReadableException", e);
return createErrorResponse(ErrorCode.MESSAGE_NOT_READABLE);
}
@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> handle(Exception e){
e.getStackTrace();
log.error("Exception", e);
return createErrorResponse(ErrorCode.INTERNAL_SERVER_ERROR);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example.yeonghuns.config.Error.exception.annualLeave;

import org.example.yeonghuns.config.Error.ErrorCode;
import org.example.yeonghuns.config.Error.exception.BadRequestException;

public class AcceptTeamPolicyException extends BadRequestException {
public AcceptTeamPolicyException() { super(ErrorCode.DECLINE_ANNUAL_LEAVE_REQUEST); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example.yeonghuns.config.Error.exception.annualLeave;

import org.example.yeonghuns.config.Error.ErrorCode;
import org.example.yeonghuns.config.Error.exception.BadRequestException;

public class AlreadyRegisteredException extends BadRequestException {
public AlreadyRegisteredException() { super(ErrorCode.ALREADY_EXISTS_ANNUAL_LEAVE); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.example.yeonghuns.config.Error.exception.annualLeave;

import org.example.yeonghuns.config.Error.ErrorCode;
import org.example.yeonghuns.config.Error.exception.BadRequestException;

/**
* packageName : org.example.yeonghuns.config.Error.exception
* fileName : AlreadyAttendanceException
* author : Yeong-Huns
* date : 2024-03-05
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-05 Yeong-Huns 최초 생성
*/
public class BeforeTodayException extends BadRequestException {
public BeforeTodayException() {
super(ErrorCode.REQUEST_BEFORE_TODAY);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example.yeonghuns.config.Error.exception.annualLeave;

import org.example.yeonghuns.config.Error.ErrorCode;
import org.example.yeonghuns.config.Error.exception.BadRequestException;

public class RemainAnnualLeavesException extends BadRequestException {
public RemainAnnualLeavesException() { super(ErrorCode.NOT_REMAIN_ANNUAL_LEAVE); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super 부분을 줄바꿈한 예외 클래스도 있고, 안 한 것도 있는데 이유가 있으신가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 확인해보니 이 부분은 인텔리제이 기능 때문에 인지하지 못한거 같습니다 .
자동으로 한줄로 보이게 하는 기능이 있더라구요 😂

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.example.yeonghuns.config.Error.exception.commute;

import org.example.yeonghuns.config.Error.ErrorCode;
import org.example.yeonghuns.config.Error.exception.BadRequestException;

/**
* packageName : org.example.yeonghuns.config.Error.exception
* fileName : AlreadyAttendanceException
* author : Yeong-Huns
* date : 2024-03-05
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-05 Yeong-Huns 최초 생성
*/
public class UsingAnnualLeavesException extends BadRequestException {
public UsingAnnualLeavesException() {
super(ErrorCode.USING_ANNUAL_LEAVES);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.example.yeonghuns.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.example.yeonghuns.dto.annualLeave.request.GetRemainAnnualLeavesRequest;
import org.example.yeonghuns.dto.annualLeave.request.RegisterAnnualLeaveRequest;
import org.example.yeonghuns.dto.annualLeave.response.GetRemainAnnualLeavesResponse;
import org.example.yeonghuns.service.annual.AnnualLeaveService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
* packageName : org.example.yeonghuns.controller
* fileName : AnnualController
* author : Yeong-Huns
* date : 2024-03-06
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-06 Yeong-Huns 최초 생성
*/
@RestController
@RequiredArgsConstructor
public class AnnualLeaveController {
private final AnnualLeaveService annualLeaveService;

@PostMapping("/annual")
public ResponseEntity<Void> registerAnnualLeave(@RequestBody @Valid RegisterAnnualLeaveRequest request) {
annualLeaveService.registerAnnualLeave(request);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@GetMapping("/annual")
public ResponseEntity<GetRemainAnnualLeavesResponse> getRemainAnnualLeaves(@Valid GetRemainAnnualLeavesRequest request) {
long remainAnnualLeaves = annualLeaveService.getRemainAnnualLeaves(request);
GetRemainAnnualLeavesResponse response = new GetRemainAnnualLeavesResponse(remainAnnualLeaves);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.example.yeonghuns.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.example.yeonghuns.dto.team.request.CreateTeamRequest;
import org.example.yeonghuns.dto.team.request.UpdateDayBeforeAnnualRequest;
import org.example.yeonghuns.dto.team.response.GetAllTeamsResponse;
import org.example.yeonghuns.service.team.TeamService;
import org.springframework.http.HttpStatus;
Expand All @@ -28,4 +30,8 @@ public ResponseEntity<List<GetAllTeamsResponse>> getAllTeams() {
return ResponseEntity.ok().body(allTeamsList);
}

@PutMapping("/team/day-before-annual")
public void updateDayBeforeAnnual(@RequestBody @Valid UpdateDayBeforeAnnualRequest request){
teamService.updateDayBeforeAnnual(request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.example.yeonghuns.domain;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDate;

/**
* packageName : org.example.yeonghuns.domain
* fileName : Annual
* author : Yeong-Huns
* date : 2024-03-06
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-06 Yeong-Huns 최초 생성
*/
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class AnnualLeave {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private LocalDate annualLeaveDate;

@ManyToOne(fetch = FetchType.LAZY)
private Member member;

@Builder
public AnnualLeave(LocalDate annualLeaveDate, Member member) {
this.annualLeaveDate = annualLeaveDate;
this.member = member;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.example.yeonghuns.domain;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
* packageName : org.example.yeonghuns.domain
* fileName : WorkStartDay
* author : Yeong-Huns
* date : 2024-03-08
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-08 Yeong-Huns 최초 생성
*/

@RequiredArgsConstructor
public enum JoinDate {
OVER_ONE_YEAR(15L),
UNDER_ONE_YEAR(11L);

private final long maxAnnualLeaves;
public long getAnnualLeaves(){return maxAnnualLeaves;}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class Member extends CreatedDateEntity {

@ManyToOne(fetch = FetchType.LAZY)
private Team team;

@Builder
public Member(String name, boolean role, LocalDate birthday, Team team) {
this.name = name;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.example.yeonghuns.domain;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -22,12 +23,15 @@ public class Team {

private String manager;

private int dayBeforeAnnual;

@OneToMany(mappedBy = "team")
private List<Member> memberList = new ArrayList<>();

@Builder
public Team(String name) {
public Team(String name, int dayBeforeAnnual) {
this.name = name;
this.dayBeforeAnnual = dayBeforeAnnual;
}

public int getMemberCount(){
Expand All @@ -38,4 +42,5 @@ public void updateManager(String manager) {
this.manager = manager;
}

public void updateDayBeforeAnnual(int dayBeforeAnnual){ this.dayBeforeAnnual = dayBeforeAnnual; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.example.yeonghuns.dto.annualLeave.request;

import jakarta.validation.constraints.NotNull;

/**
* packageName : org.example.yeonghuns.dto.annual.request
* fileName : GetRemainAnnualLeaves
* author : Yeong-Huns
* date : 2024-03-07
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-07 Yeong-Huns 최초 생성
*/
public record GetRemainAnnualLeavesRequest(@NotNull long id) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.example.yeonghuns.dto.annualLeave.request;

import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.NotNull;
import org.example.yeonghuns.domain.AnnualLeave;
import org.example.yeonghuns.domain.Member;

import java.time.LocalDate;

/**
* packageName : org.example.yeonghuns.dto.annual.request
* fileName : RegistAnnualRequest
* author : Yeong-Huns
* date : 2024-03-07
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-07 Yeong-Huns 최초 생성
*/
public record RegisterAnnualLeaveRequest(@NotNull long id, @Future LocalDate date) {
public AnnualLeave toEntity(Member member){
return AnnualLeave.builder()
.annualLeaveDate(date)
.member(member)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.example.yeonghuns.dto.annualLeave.response;

/**
* packageName : org.example.yeonghuns.dto.annual.response
* fileName : GetRemainAnnualLeavesResponse
* author : Yeong-Huns
* date : 2024-03-07
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2024-03-07 Yeong-Huns 최초 생성
*/
public record GetRemainAnnualLeavesResponse(long remainAnnualLeaves) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@
* 2024-03-05 Yeong-Huns 최초 생성
*/
public record GetCommuteRecordRequest(@NotNull long id, @DateTimeFormat(pattern = "yyyy-MM") YearMonth yearMonth) {
public int getYear(){ return this.yearMonth.getYear();}
public int getMonth(){ return this.yearMonth.getMonth().getValue(); }
}