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

feat: 공연장 기능 추가 #23

Merged
merged 8 commits into from
Dec 24, 2023
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
package com.pgms.apievent.event.service;

import static com.pgms.apievent.exception.EventErrorCode.*;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.pgms.apievent.event.dto.request.EventCreateRequest;
import com.pgms.apievent.event.dto.request.EventUpdateRequest;
import com.pgms.apievent.event.dto.response.EventResponse;
import com.pgms.apievent.exception.CustomException;
import com.pgms.coredomain.domain.event.Event;
import com.pgms.coredomain.domain.event.EventEdit;
import com.pgms.coredomain.domain.event.EventHall;
import com.pgms.coredomain.domain.event.repository.EventHallRepository;
import com.pgms.coredomain.domain.event.repository.EventRepository;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.pgms.apievent.exception.EventErrorCode.*;

@Service
@Transactional
@RequiredArgsConstructor
public class EventService {

private final EventRepository eventRepository;
// private final EventHallRepository eventHallRepository;
private final EventHallRepository eventHallRepository;

public EventResponse createEvent(EventCreateRequest request) {
validateDuplicateEvent(request.title());
/**
* TODO
* 1) 공연장 정보를 통해 공연장 가져오기
* 2) toEntity 메소드에 eventHall 넘겨주기
*/
Event event = request.toEntity(null);

EventHall eventHall = eventHallRepository.findById(request.eventHallId())
.orElseThrow(() -> new CustomException(EVENT_HALL_NOT_FOUND));

Event event = request.toEntity(eventHall);
eventRepository.save(event);
return EventResponse.of(event);
}
Expand Down Expand Up @@ -63,10 +62,9 @@ private void validateDuplicateEvent(String title) {
}

private EventEdit getEventEdit(EventUpdateRequest request) {
/**
* TODO
* eventHall 찾아서 eventHall 부분에 넣어주기
*/
EventHall eventHall = eventHallRepository.findById(request.eventHallId())
.orElseThrow(() -> new CustomException(EVENT_HALL_NOT_FOUND));

return EventEdit.builder()
.title(request.title())
.description(request.description())
Expand All @@ -76,6 +74,7 @@ private EventEdit getEventEdit(EventUpdateRequest request) {
.rating(request.rating())
.genreType(request.genreType())
.thumbnail(request.thumbnail())
.eventHall(null).build();
.eventHall(eventHall)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.pgms.apievent.eventHall.controller;

import com.pgms.apievent.eventHall.dto.request.EventHallCreateRequest;
import com.pgms.apievent.eventHall.dto.request.EventHallUpdateRequest;
import com.pgms.apievent.eventHall.dto.response.EventHallResponse;
import com.pgms.apievent.eventHall.service.EventHallService;
import com.pgms.coredomain.response.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/backoffice/event-halls")
public class EventHallController {

private final EventHallService eventHallService;

@PostMapping
public ResponseEntity<ApiResponse> createEventHall(@RequestBody EventHallCreateRequest request){
EventHallResponse eventHallResponse = eventHallService.createEventHall(request);

URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(eventHallResponse.id())
.toUri();
return ResponseEntity.created(location).body(ApiResponse.created(eventHallResponse));
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteEventHall(@PathVariable Long id){
eventHallService.deleteEventHall(id);
return ResponseEntity.noContent().build();
}

@PutMapping("/{id}")
public ResponseEntity<ApiResponse> updateEventHall(
@PathVariable Long id,
@RequestBody EventHallUpdateRequest request) {
EventHallResponse response = eventHallService.updateEventHall(id, request);
return ResponseEntity.ok(ApiResponse.ok(response));
}

@GetMapping("/{id}")
public ResponseEntity<ApiResponse> getEventHall(@PathVariable Long id){
EventHallResponse response = eventHallService.getEventHall(id);
return ResponseEntity.ok(ApiResponse.ok(response));
}

@GetMapping
public ResponseEntity<ApiResponse> getEventHall(){
List<EventHallResponse> eventHalls = eventHallService.getEventHalls();
return ResponseEntity.ok(ApiResponse.ok(eventHalls));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.pgms.apievent.eventHall.dto.request;

import java.util.List;

public record EventHallCreateRequest(String name,
String address,
List<EventHallSeatCreateRequest> eventHallSeatCreateRequests) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.pgms.apievent.eventHall.dto.request;

public record EventHallSeatCreateRequest(String name) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.pgms.apievent.eventHall.dto.request;

import java.util.List;

public record EventHallUpdateRequest(String name, String address, List<EventHallSeatCreateRequest> eventHallSeatCreateRequests) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.pgms.apievent.eventHall.dto.response;

import com.pgms.coredomain.domain.event.EventHall;
import com.pgms.coredomain.domain.event.EventHallSeat;
import lombok.Builder;

import java.util.List;

@Builder
public record EventHallResponse(Long id, String name, String address, List<EventHallSeatResponse> eventHallSeatResponses) {
static public EventHallResponse of(EventHall eventHall){
List<EventHallSeatResponse> eventHallSeatResponses = eventHall.getEventHallSeats().stream()
.map(EventHallSeatResponse::of)
.toList();

return EventHallResponse.builder()
.id(eventHall.getId())
.name(eventHall.getName())
.address(eventHall.getAddress())
.eventHallSeatResponses(eventHallSeatResponses)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.pgms.apievent.eventHall.dto.response;

import com.pgms.coredomain.domain.event.EventHallSeat;
import lombok.Builder;

@Builder
public record EventHallSeatResponse(Long id, String name) {
static public EventHallSeatResponse of(EventHallSeat eventHallSeat){
return EventHallSeatResponse.builder()
.id(eventHallSeat.getId())
.name(eventHallSeat.getName())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.pgms.apievent.eventHall.service;

import com.pgms.apievent.eventHall.dto.request.EventHallCreateRequest;
import com.pgms.apievent.eventHall.dto.request.EventHallUpdateRequest;
import com.pgms.apievent.eventHall.dto.request.EventHallSeatCreateRequest;
import com.pgms.apievent.eventHall.dto.response.EventHallResponse;
import com.pgms.apievent.exception.EventHallNotFoundException;
import com.pgms.coredomain.domain.event.EventHall;
import com.pgms.coredomain.domain.event.EventHallEdit;
import com.pgms.coredomain.domain.event.EventHallSeat;
import com.pgms.coredomain.domain.event.repository.EventHallRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@RequiredArgsConstructor
public class EventHallService {

private final EventHallRepository eventHallRepository;

public EventHallResponse createEventHall(EventHallCreateRequest eventHallCreateRequest) {
List<EventHallSeatCreateRequest> eventHallSeatCreateRequests = eventHallCreateRequest.eventHallSeatCreateRequests();

List<EventHallSeat> eventHallSeats = eventHallSeatCreateRequests.stream()
.map(this::createEventHallSeat)
.toList();

EventHall eventHall = EventHall.builder()
.name(eventHallCreateRequest.name())
.address(eventHallCreateRequest.address())
.eventHallSeats(eventHallSeats)
.build();

return EventHallResponse.of(eventHallRepository.save(eventHall));
}

public void deleteEventHall(Long id) {
EventHall eventHall = eventHallRepository.findById(id)
.orElseThrow(RuntimeException::new);

eventHallRepository.delete(eventHall);
}

public EventHallResponse updateEventHall(Long id, EventHallUpdateRequest eventHallUpdateRequest) {
EventHall eventHall = eventHallRepository.findById(id).orElseThrow(EventHallNotFoundException::new);

List<EventHallSeatCreateRequest> eventHallSeatCreateRequests = eventHallUpdateRequest.eventHallSeatCreateRequests();

List<EventHallSeat> eventHallSeats = eventHallSeatCreateRequests.stream()
.map(this::createEventHallSeat)
.toList();

EventHallEdit eventHallEdit = EventHallEdit.builder()
.name(eventHallUpdateRequest.name())
.address(eventHallUpdateRequest.address())
.eventHallSeats(eventHallSeats)
.build();

eventHall.updateEventHall(eventHallEdit);

return EventHallResponse.of(eventHall);
}

@Transactional(readOnly = true)
public EventHallResponse getEventHall(Long id) {
EventHall eventHall = eventHallRepository.findById(id).orElseThrow(EventHallNotFoundException::new);

return EventHallResponse.of(eventHall);
}

@Transactional(readOnly = true)
public List<EventHallResponse> getEventHalls() {
List<EventHall> eventHalls = eventHallRepository.findAll();
return eventHalls.stream()
.map(EventHallResponse::of)
.toList();
}

private EventHallSeat createEventHallSeat(EventHallSeatCreateRequest eventHallSeatCreateRequest) {
return new EventHallSeat(eventHallSeatCreateRequest.name());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
public enum EventErrorCode {

EVENT_NOT_FOUND("NOT FOUND", HttpStatus.NOT_FOUND, "존재하지 않는 공연입니다."),
EVENT_HALL_NOT_FOUND("EVENT HALL NOT FOUND", HttpStatus.NOT_FOUND, "존재하지 않는 공연장입니다."),
ALREADY_EXIST_EVENT("DUPLICATE EVENT", HttpStatus.CONFLICT, "이미 존재하는 공연입니다."),
VALIDATION_FAILED("VALIDATION FAILED", HttpStatus.BAD_REQUEST, "입력값에 대한 검증에 실패했습니다.");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.pgms.apievent.exception;

import static com.pgms.apievent.exception.EventErrorCode.*;

import java.util.List;
import java.util.Objects;

import com.pgms.coredomain.response.ErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
Expand All @@ -13,35 +10,36 @@
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.pgms.coredomain.response.ErrorResponse;
import java.util.List;
import java.util.Objects;

import lombok.extern.slf4j.Slf4j;
import static com.pgms.apievent.exception.EventErrorCode.VALIDATION_FAILED;

@Slf4j
@RestControllerAdvice
public class EventGlobalExceptionHandler {

@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> handleGlobalException(Exception ex) {
log.error("Internal Server Error : {}", ex.getMessage());
log.error(">>>>> Internal Server Error : {}", ex);
ErrorResponse errorResponse = new ErrorResponse("INTERNAL SERVER ERROR", ex.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}

@ExceptionHandler(CustomException.class)
protected ResponseEntity<ErrorResponse> handleEventCustomException(CustomException ex) {
log.warn("Custom Exception : {}", ex.getMessage());
log.warn(">>>>> Custom Exception : {}", ex);
EventErrorCode errorCode = ex.getErrorCode();
ErrorResponse errorResponse = new ErrorResponse(errorCode.getErrorCode(), errorCode.getMessage());
return ResponseEntity.status(errorCode.getStatus()).body(errorResponse);
}

@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
log.warn(">>>>> validation Failed : {}", ex);
BindingResult bindingResult = ex.getBindingResult();
String errorMessage = Objects.requireNonNull(bindingResult.getFieldError())
.getDefaultMessage();
log.warn("validation Failed : {}", errorMessage);

List<FieldError> fieldErrors = bindingResult.getFieldErrors();
ErrorResponse errorResponse = new ErrorResponse(VALIDATION_FAILED.getErrorCode(), errorMessage);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.pgms.apievent.exception;

import static com.pgms.apievent.exception.EventErrorCode.EVENT_HALL_NOT_FOUND;

public class EventHallNotFoundException extends CustomException{
public EventHallNotFoundException() {
super(EVENT_HALL_NOT_FOUND);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import com.pgms.coredomain.domain.common.BaseEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
Expand All @@ -24,4 +24,20 @@ public class EventHall extends BaseEntity {

@Column(name = "address")
private String address;

@OneToMany(mappedBy = "eventHall", cascade = CascadeType.ALL, orphanRemoval = true)
private List<EventHallSeat> eventHallSeats = new ArrayList<>();

@Builder
public EventHall(String name, String address, List<EventHallSeat> eventHallSeats) {
this.name = name;
this.address = address;
this.eventHallSeats = eventHallSeats;
}

public void updateEventHall(EventHallEdit eventHallEdit){
this.name = eventHallEdit.getName();
this.address = eventHallEdit.getAddress();
this.eventHallSeats = eventHallEdit.getEventHallSeats();
}
}
Loading