Skip to content

Commit

Permalink
Merge pull request #18 from Yeong-Huns/mission03
Browse files Browse the repository at this point in the history
미니 프로젝트 Step03
  • Loading branch information
Yeong-Huns committed Mar 10, 2024
2 parents 480cf2a + bfab380 commit f8f6470
Show file tree
Hide file tree
Showing 27 changed files with 465 additions and 28 deletions.
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); }
}
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(); }
}

0 comments on commit f8f6470

Please sign in to comment.