diff --git a/src/main/java/net/skhu/tastyinventory_be/common/advice/ControllerExceptionAdvice.java b/src/main/java/net/skhu/tastyinventory_be/common/advice/ControllerExceptionAdvice.java index b2d2f76..a362c86 100644 --- a/src/main/java/net/skhu/tastyinventory_be/common/advice/ControllerExceptionAdvice.java +++ b/src/main/java/net/skhu/tastyinventory_be/common/advice/ControllerExceptionAdvice.java @@ -84,7 +84,7 @@ public BaseResponse fileSizeLimitExceeded(final MaxUploadSizeExceededException e @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception.class) protected BaseResponse handleException(final Exception e, final HttpServletRequest request) throws IOException { - log.error("Internal Server Error: {}", e.getMessage()); + log.error("Internal Server Error: {}", e.getMessage(), e); return BaseResponse.error(ErrorCode.INTERNAL_SERVER_ERROR); } diff --git a/src/main/java/net/skhu/tastyinventory_be/config/MvcConfigurer.java b/src/main/java/net/skhu/tastyinventory_be/config/MvcConfigurer.java index bceca21..0c91abe 100644 --- a/src/main/java/net/skhu/tastyinventory_be/config/MvcConfigurer.java +++ b/src/main/java/net/skhu/tastyinventory_be/config/MvcConfigurer.java @@ -1,27 +1,27 @@ -//package net.skhu.tastyinventory_be.config; -// -//import org.springframework.beans.factory.annotation.Value; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.http.HttpMethod; -//import org.springframework.web.servlet.config.annotation.CorsRegistry; -//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -// -//@Configuration -//public class MvcConfigurer implements WebMvcConfigurer { -// @Value("${client.origins}") -// private String[] allowedOrigins; -// -// @Override -// public void addCorsMappings(CorsRegistry registry) { -// registry.addMapping("/**") -// .allowedOrigins(allowedOrigins) -// .allowedMethods( -// HttpMethod.GET.name(), -// HttpMethod.HEAD.name(), -// HttpMethod.POST.name(), -// HttpMethod.PUT.name(), -// HttpMethod.DELETE.name()) -// .maxAge(3600) -// .allowCredentials(true); -// } -//} +package net.skhu.tastyinventory_be.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class MvcConfigurer implements WebMvcConfigurer { + @Value("${client.origins}") + private String[] allowedOrigins; + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins(allowedOrigins) + .allowedMethods( + HttpMethod.GET.name(), + HttpMethod.HEAD.name(), + HttpMethod.POST.name(), + HttpMethod.PUT.name(), + HttpMethod.DELETE.name()) + .maxAge(3600) + .allowCredentials(true); + } +} diff --git a/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/InventoryRecordController.java b/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/InventoryRecordController.java index 1d206dc..796579b 100644 --- a/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/InventoryRecordController.java +++ b/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/InventoryRecordController.java @@ -4,12 +4,18 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.skhu.tastyinventory_be.common.dto.BaseResponse; +import net.skhu.tastyinventory_be.controller.inventoryRecord.dto.request.InventoryRecordDto; import net.skhu.tastyinventory_be.controller.inventoryRecord.dto.request.InventoryRecordRequestDto; +import net.skhu.tastyinventory_be.controller.inventoryRecord.dto.request.InventoryRecordUpdateRequestDto; +import net.skhu.tastyinventory_be.controller.inventoryRecord.dto.response.InventoryRecordResponseDto; +import net.skhu.tastyinventory_be.domain.inventoryRecord.InventoryRecord; import net.skhu.tastyinventory_be.exception.SuccessCode; import net.skhu.tastyinventory_be.service.InventoryRecordService; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; +import java.util.List; + @Slf4j @RequiredArgsConstructor @RequestMapping("/inventory-records") @@ -23,4 +29,21 @@ public BaseResponse createRecord(@RequestBody @Valid InventoryRecordRequestDt inventoryRecordService.createInventoryRecord(requestDto); return BaseResponse.success(SuccessCode.INVENTORY_RECORD_CREATE_SUCCESS); } + @GetMapping + public BaseResponse> getAllRecords() { + return BaseResponse.success(SuccessCode.INVENTORY_RECORD_GET_SUCCESS, inventoryRecordService.getAllInventoryRecords()); + } + @PatchMapping("/{id}") + public BaseResponse updateRecord(@PathVariable Long id, @RequestBody @Valid InventoryRecordUpdateRequestDto requestDto) { + inventoryRecordService.updateInventoryRecord(id, requestDto); + return BaseResponse.success(SuccessCode.INVENTORY_RECORD_PATCH_SUCCESS); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + public BaseResponse deleteRecord(@PathVariable Long id) { + inventoryRecordService.deleteInventoryRecord(id); + return BaseResponse.success(SuccessCode.INVENTORY_RECORD_DELETE_SUCCESS); + } + } diff --git a/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/dto/request/InventoryRecordUpdateRequestDto.java b/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/dto/request/InventoryRecordUpdateRequestDto.java new file mode 100644 index 0000000..a025340 --- /dev/null +++ b/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/dto/request/InventoryRecordUpdateRequestDto.java @@ -0,0 +1,26 @@ +package net.skhu.tastyinventory_be.controller.inventoryRecord.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class InventoryRecordUpdateRequestDto { + @NotBlank(message = "날짜를 입력하세요") + @Pattern( + regexp="^\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + message = "YYYY-MM-DD 형식으로 입력하세요" + ) + private String date; + + @NotNull(message = "현 재고량을 입력하세요") + private Long currentVolume; + + @NotNull(message = "발주량을 입력하세요") + private Long orderVolume; +} diff --git a/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/dto/response/InventoryRecordResponseDto.java b/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/dto/response/InventoryRecordResponseDto.java new file mode 100644 index 0000000..ea8fe3d --- /dev/null +++ b/src/main/java/net/skhu/tastyinventory_be/controller/inventoryRecord/dto/response/InventoryRecordResponseDto.java @@ -0,0 +1,26 @@ +package net.skhu.tastyinventory_be.controller.inventoryRecord.dto.response; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import net.skhu.tastyinventory_be.domain.inventoryRecord.InventoryRecord; + +@Getter +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class InventoryRecordResponseDto { + private Long id; + private String date; + private Long inventoryId; + private Long currentVolume; + private Long orderVolume; + + public InventoryRecordResponseDto(InventoryRecord inventoryRecord) { + this.id = inventoryRecord.getId(); + this.date = inventoryRecord.getDate().toString(); + this.inventoryId = inventoryRecord.getInventory().getId(); + this.currentVolume = inventoryRecord.getCurrentVolume(); + this.orderVolume = inventoryRecord.getOrderVolume(); + } +} diff --git a/src/main/java/net/skhu/tastyinventory_be/controller/sold/SoldController.java b/src/main/java/net/skhu/tastyinventory_be/controller/sold/SoldController.java index 9789015..fa72d62 100644 --- a/src/main/java/net/skhu/tastyinventory_be/controller/sold/SoldController.java +++ b/src/main/java/net/skhu/tastyinventory_be/controller/sold/SoldController.java @@ -1,15 +1,19 @@ package net.skhu.tastyinventory_be.controller.sold; +import com.fasterxml.jackson.databind.ser.Serializers; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.skhu.tastyinventory_be.common.dto.BaseResponse; import net.skhu.tastyinventory_be.controller.sold.dto.request.SoldRequestDto; +import net.skhu.tastyinventory_be.controller.sold.dto.response.SoldResponseDto; import net.skhu.tastyinventory_be.exception.SuccessCode; import net.skhu.tastyinventory_be.service.SoldService; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; +import java.util.List; + @Slf4j @RequiredArgsConstructor @RequestMapping("/sold") @@ -23,4 +27,20 @@ public BaseResponse registerSold(@RequestBody @Valid SoldRequestDto requestDt soldService.registerSold(requestDto); return BaseResponse.success(SuccessCode.SOLD_CREATE_SUCCESS); } + @GetMapping + public BaseResponse> findAllSold() { + List soldResponseDtoList = soldService.findAllSold(); + return BaseResponse.success(SuccessCode.GET_SUCCESS, soldResponseDtoList); + } + @PatchMapping("/{id}") + public BaseResponse updateSold(@PathVariable("id") Long id, @RequestBody @Valid SoldRequestDto requestDto) { + soldService.updateSold(id, requestDto); + return BaseResponse.success(SuccessCode.SOLD_PATCH_SUCCESSCODE); + } + + @DeleteMapping("/{id}") + public BaseResponse deleteSold(@PathVariable("id") Long id) { + soldService.deleteSold(id); + return BaseResponse.success(SuccessCode.SOLD_DELETE_SUCCESSCODE); + } } diff --git a/src/main/java/net/skhu/tastyinventory_be/controller/sold/dto/response/SoldResponseDto.java b/src/main/java/net/skhu/tastyinventory_be/controller/sold/dto/response/SoldResponseDto.java new file mode 100644 index 0000000..19b5e4f --- /dev/null +++ b/src/main/java/net/skhu/tastyinventory_be/controller/sold/dto/response/SoldResponseDto.java @@ -0,0 +1,19 @@ +package net.skhu.tastyinventory_be.controller.sold.dto.response; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class SoldResponseDto { + private Long id; + private String menuName; + private Long count; + + public static SoldResponseDto of(Long id, String menuName, Long count) { + return new SoldResponseDto(id, menuName, count); + } +} diff --git a/src/main/java/net/skhu/tastyinventory_be/domain/BaseEntity.java b/src/main/java/net/skhu/tastyinventory_be/domain/BaseEntity.java index a2ec262..4140408 100644 --- a/src/main/java/net/skhu/tastyinventory_be/domain/BaseEntity.java +++ b/src/main/java/net/skhu/tastyinventory_be/domain/BaseEntity.java @@ -26,4 +26,8 @@ public abstract class BaseEntity { @Column(name = "UPDATE_AT", nullable = false) @LastModifiedDate private LocalDateTime updateAt; + + protected void setId(Long id) { + this.id = id; + } } diff --git a/src/main/java/net/skhu/tastyinventory_be/domain/inventoryRecord/InventoryRecord.java b/src/main/java/net/skhu/tastyinventory_be/domain/inventoryRecord/InventoryRecord.java index cce0eb5..8f0f984 100644 --- a/src/main/java/net/skhu/tastyinventory_be/domain/inventoryRecord/InventoryRecord.java +++ b/src/main/java/net/skhu/tastyinventory_be/domain/inventoryRecord/InventoryRecord.java @@ -34,4 +34,9 @@ public InventoryRecord(LocalDate date, Inventory inventory, Long currentVolume, this.currentVolume = currentVolume; this.orderVolume = orderVolume; } + public void update(LocalDate date, Long currentVolume, Long orderVolume) { + this.date = date; + this.currentVolume = currentVolume; + this.orderVolume = orderVolume; + } } diff --git a/src/main/java/net/skhu/tastyinventory_be/domain/sold/Sold.java b/src/main/java/net/skhu/tastyinventory_be/domain/sold/Sold.java index 646d336..f93ac17 100644 --- a/src/main/java/net/skhu/tastyinventory_be/domain/sold/Sold.java +++ b/src/main/java/net/skhu/tastyinventory_be/domain/sold/Sold.java @@ -5,10 +5,14 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import net.skhu.tastyinventory_be.controller.sold.dto.request.SoldMenuDto; +import net.skhu.tastyinventory_be.controller.sold.dto.request.SoldRequestDto; import net.skhu.tastyinventory_be.domain.BaseEntity; import net.skhu.tastyinventory_be.domain.menu.Menu; +import org.springframework.cglib.core.Local; import java.time.LocalDate; +import java.util.List; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -26,9 +30,13 @@ public class Sold extends BaseEntity { private Long count; @Builder - public Sold(LocalDate date, Menu menu, Long count) { + public Sold(Long id, LocalDate date, Menu menu, Long count) { + this.setId(id); this.date = date; this.menu = menu; this.count = count; } + public void update(Long count) { + this.count = count; // 판매량을 업데이트 + } } diff --git a/src/main/java/net/skhu/tastyinventory_be/domain/sold/SoldRepository.java b/src/main/java/net/skhu/tastyinventory_be/domain/sold/SoldRepository.java index 5b6a873..180d119 100644 --- a/src/main/java/net/skhu/tastyinventory_be/domain/sold/SoldRepository.java +++ b/src/main/java/net/skhu/tastyinventory_be/domain/sold/SoldRepository.java @@ -1,6 +1,13 @@ package net.skhu.tastyinventory_be.domain.sold; +import net.skhu.tastyinventory_be.domain.menu.Menu; import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + public interface SoldRepository extends JpaRepository { + List findByDate(LocalDate date); + Optional findByDateAndMenu(LocalDate date, Menu menu); } diff --git a/src/main/java/net/skhu/tastyinventory_be/exception/ErrorCode.java b/src/main/java/net/skhu/tastyinventory_be/exception/ErrorCode.java index 02170d6..d332e9d 100644 --- a/src/main/java/net/skhu/tastyinventory_be/exception/ErrorCode.java +++ b/src/main/java/net/skhu/tastyinventory_be/exception/ErrorCode.java @@ -50,8 +50,9 @@ public enum ErrorCode { NOT_FOUND_INVENTORY_EXCEPTION(HttpStatus.NOT_FOUND, "존재하지 않는 재고입니다"), NOT_FOUND_MENU_EXCEPTION(HttpStatus.NOT_FOUND, "존재하지 않는 메뉴입니다"), NOT_FOUND_EMPLOYEE_EXCEPTION(HttpStatus.NOT_FOUND, "존재하지 않는 직원입니다"), + NOT_FOUND_SOLD_EXCEPTION(HttpStatus.NOT_FOUND, "재고량이 존재하지 않습니다"), + NOT_FOUND_INVENTORY_RECORD_EXCEPTION(HttpStatus.NOT_FOUND, "재고기록이 존재하지 않습니다"), NOT_FOUND_SCHEDULE_EXCEPTION(HttpStatus.NOT_FOUND, "존재하지 않는 스케줄입니다"), - /** * 500 INTERNAL SERVER ERROR */ diff --git a/src/main/java/net/skhu/tastyinventory_be/exception/SuccessCode.java b/src/main/java/net/skhu/tastyinventory_be/exception/SuccessCode.java index d979179..62abef0 100644 --- a/src/main/java/net/skhu/tastyinventory_be/exception/SuccessCode.java +++ b/src/main/java/net/skhu/tastyinventory_be/exception/SuccessCode.java @@ -21,6 +21,12 @@ public enum SuccessCode { INVENTORY_PATCH_SUCCESS(HttpStatus.OK, "재고 수정이 완료되었습니다"), MENU_PATCH_SUCCESS(HttpStatus.OK, "메뉴 수정이 완료되었습니다"), MENU_DELETE_SUCCESS(HttpStatus.OK, "메뉴 삭제에 성공했습니다"), + SOLD_DELETE_SUCCESSCODE(HttpStatus.OK, "메뉴 판매량 삭제에 성공했습니다"), + SOLD_PATCH_SUCCESSCODE(HttpStatus.NO_CONTENT, "재고량 정보 수정이 완료되었습니다"), + INVENTORY_RECORD_GET_SUCCESS(HttpStatus.OK, "재고량 정보 조회에 성공했습니다"), + INVENTORY_RECORD_PATCH_SUCCESS(HttpStatus.OK, "재고량 정보 수정이 완료되었습니다"), + INVENTORY_RECORD_DELETE_SUCCESS(HttpStatus.OK, "재고량 정보 삭제에 성공했습니다"), + /** * 201 CREATED diff --git a/src/main/java/net/skhu/tastyinventory_be/service/InventoryRecordService.java b/src/main/java/net/skhu/tastyinventory_be/service/InventoryRecordService.java index 4aecdd8..4c8e30b 100644 --- a/src/main/java/net/skhu/tastyinventory_be/service/InventoryRecordService.java +++ b/src/main/java/net/skhu/tastyinventory_be/service/InventoryRecordService.java @@ -2,6 +2,8 @@ import lombok.RequiredArgsConstructor; import net.skhu.tastyinventory_be.controller.inventoryRecord.dto.request.InventoryRecordRequestDto; +import net.skhu.tastyinventory_be.controller.inventoryRecord.dto.request.InventoryRecordUpdateRequestDto; +import net.skhu.tastyinventory_be.controller.inventoryRecord.dto.response.InventoryRecordResponseDto; import net.skhu.tastyinventory_be.domain.inventory.Inventory; import net.skhu.tastyinventory_be.domain.inventory.InventoryRepository; import net.skhu.tastyinventory_be.domain.inventoryRecord.InventoryRecord; @@ -12,6 +14,8 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; @RequiredArgsConstructor @Transactional(readOnly = true) @@ -43,4 +47,36 @@ public void createInventoryRecord(InventoryRecordRequestDto requestDto) { inventoryRecordRepository.save(inventoryRecord); } } + public List getAllInventoryRecords() { + return inventoryRecordRepository.findAll().stream() + .map(InventoryRecordResponseDto::new) + .collect(Collectors.toList()); + } + + @Transactional + public void updateInventoryRecord(Long id, InventoryRecordUpdateRequestDto requestDto) { + InventoryRecord inventoryRecord = inventoryRecordRepository.findById(id).orElseThrow( + () -> new NotFoundException( + ErrorCode.NOT_FOUND_INVENTORY_RECORD_EXCEPTION, + ErrorCode.NOT_FOUND_INVENTORY_RECORD_EXCEPTION.getMessage() + id + )); + + inventoryRecord.update( + LocalDate.parse(requestDto.getDate()), + requestDto.getCurrentVolume(), + requestDto.getOrderVolume() + ); + + inventoryRecordRepository.save(inventoryRecord); + } + + @Transactional + public void deleteInventoryRecord(Long id) { + InventoryRecord inventoryRecord = inventoryRecordRepository.findById(id).orElseThrow( + () -> new NotFoundException( + ErrorCode.NOT_FOUND_INVENTORY_RECORD_EXCEPTION, + ErrorCode.NOT_FOUND_INVENTORY_RECORD_EXCEPTION.getMessage() + id + )); + inventoryRecordRepository.delete(inventoryRecord); + } } diff --git a/src/main/java/net/skhu/tastyinventory_be/service/SoldService.java b/src/main/java/net/skhu/tastyinventory_be/service/SoldService.java index c529a34..0ed4430 100644 --- a/src/main/java/net/skhu/tastyinventory_be/service/SoldService.java +++ b/src/main/java/net/skhu/tastyinventory_be/service/SoldService.java @@ -1,7 +1,9 @@ package net.skhu.tastyinventory_be.service; import lombok.RequiredArgsConstructor; +import net.skhu.tastyinventory_be.controller.sold.dto.request.SoldMenuDto; import net.skhu.tastyinventory_be.controller.sold.dto.request.SoldRequestDto; +import net.skhu.tastyinventory_be.controller.sold.dto.response.SoldResponseDto; import net.skhu.tastyinventory_be.domain.menu.Menu; import net.skhu.tastyinventory_be.domain.menu.MenuRepository; import net.skhu.tastyinventory_be.domain.sold.Sold; @@ -12,6 +14,11 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @RequiredArgsConstructor @Transactional(readOnly = true) @@ -20,6 +27,8 @@ public class SoldService { private final SoldRepository soldRepository; private final MenuRepository menuRepository; + private static final Logger logger = LoggerFactory.getLogger(SoldService.class); + @Transactional public void registerSold(SoldRequestDto requestDto) { for (int i = 0; i < requestDto.getSoldMenuList().size(); i++) { @@ -41,4 +50,39 @@ public void registerSold(SoldRequestDto requestDto) { soldRepository.save(sold); } } + + public List findAllSold() { + List soldList = soldRepository.findAll(); + return soldList.stream() + .map(sold -> new SoldResponseDto (sold.getId(), sold.getMenu().getName(), sold.getCount())) + .collect(Collectors.toList()); + } + + @Transactional + public void updateSold(Long id, SoldRequestDto requestDto) { + Sold sold = soldRepository.findById(id).orElseThrow( + () -> new NotFoundException( + ErrorCode.NOT_FOUND_SOLD_EXCEPTION, + ErrorCode.NOT_FOUND_SOLD_EXCEPTION.getMessage() + id)); + + for (SoldMenuDto soldMenuDto : requestDto.getSoldMenuList()) { + Menu menu = menuRepository.findById(soldMenuDto.getMenuId()).orElseThrow( + () -> new NotFoundException( + ErrorCode.NOT_FOUND_MENU_EXCEPTION, + ErrorCode.NOT_FOUND_MENU_EXCEPTION.getMessage() + id)); + + sold.update(soldMenuDto.getSoldCount()); + soldRepository.save(sold); + } + } + + @Transactional + public void deleteSold(Long id) { + Sold sold = soldRepository.findById(id).orElseThrow( + () -> new NotFoundException( + ErrorCode.NOT_FOUND_SOLD_EXCEPTION, + ErrorCode.NOT_FOUND_SOLD_EXCEPTION.getMessage() + id)); + soldRepository.delete(sold); + } + }