Skip to content

Commit

Permalink
feat : 생협 운영시간 API 구현 (#643)
Browse files Browse the repository at this point in the history
* feature : CoopShop 생협 매장 조회 API 구현

* feature : AdminCoopShop 생협 매장 조회 API 구현

* feature : coop_shop, coop_opens 테이블 생성

* feature : is_deleted 속성 추가

* test : coopShop 테스트 추가

* fix : AdminCoopShop inner클래스 수정

* chore : 잘못된 참조 수정

* chore : 리뷰 반영 GetMapping -> RequestMapping

* fix : 리뷰 반영(경로명 수정, 삭제된 생협 제외 조회)

* fix : 테이블 버젼 수정

* chore : 테스트 수정

* chore : admin 경로명 수정

* chore : adminTest 수정
  • Loading branch information
Choon0414 authored Jul 14, 2024
1 parent cd29dd1 commit 9996c04
Show file tree
Hide file tree
Showing 19 changed files with 1,094 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package in.koreatech.koin.admin.coopShop.controller;

import static in.koreatech.koin.domain.user.model.UserType.ADMIN;
import static io.swagger.v3.oas.annotations.enums.ParameterIn.PATH;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import in.koreatech.koin.admin.coopShop.dto.AdminCoopShopResponse;
import in.koreatech.koin.admin.coopShop.dto.AdminCoopShopsResponse;
import in.koreatech.koin.domain.coopshop.dto.CoopShopResponse;
import in.koreatech.koin.global.auth.Auth;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

@RequestMapping("/admin/coopshop")
@Tag(name = "(ADMIN) AdminCoopShop : 생협 매장 정보", description = "생협 매장 정보 조회 페이지")
public interface AdminCoopShopApi {

@ApiResponses(
value = {
@ApiResponse(responseCode = "200"),
@ApiResponse(responseCode = "400", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true)))
}
)
@Operation(summary = "모든 생협 매장 정보 조회")
@GetMapping
ResponseEntity<AdminCoopShopsResponse> getCoopsShops(
@RequestParam(name = "page", defaultValue = "1") Integer page,
@RequestParam(name = "limit", defaultValue = "10", required = false) Integer limit,
@RequestParam(name = "is_deleted", defaultValue = "false") Boolean isDeleted,
@Auth(permit = {ADMIN}) Integer adminId
);

@ApiResponses(
value = {
@ApiResponse(responseCode = "200"),
@ApiResponse(responseCode = "400", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true)))
}
)
@Operation(summary = "특정 생협 매장 정보 조회")
@GetMapping("/{coopShopId}")
ResponseEntity<AdminCoopShopResponse> getCoopShop(
@Auth(permit = {ADMIN}) Integer adminId,
@Parameter(in = PATH) @PathVariable Integer coopShopId
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package in.koreatech.koin.admin.coopShop.controller;

import static in.koreatech.koin.domain.user.model.UserType.ADMIN;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import in.koreatech.koin.admin.coopShop.dto.AdminCoopShopResponse;
import in.koreatech.koin.admin.coopShop.dto.AdminCoopShopsResponse;
import in.koreatech.koin.admin.coopShop.service.AdminCoopShopService;
import in.koreatech.koin.global.auth.Auth;
import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/admin/coopshop")
@RequiredArgsConstructor
public class AdminCoopShopController implements AdminCoopShopApi {

private final AdminCoopShopService adminCoopShopService;

@GetMapping
public ResponseEntity<AdminCoopShopsResponse> getCoopsShops(
@RequestParam(name = "page", defaultValue = "1") Integer page,
@RequestParam(name = "limit", defaultValue = "10", required = false) Integer limit,
@RequestParam(name = "is_deleted", defaultValue = "false") Boolean isDeleted,
@Auth(permit = {ADMIN}) Integer adminId
) {
AdminCoopShopsResponse coopShops = adminCoopShopService.getCoopsShops(page, limit, isDeleted);
return ResponseEntity.ok(coopShops);
}

@GetMapping("/{coopShopId}")
public ResponseEntity<AdminCoopShopResponse> getCoopShop(
@Auth(permit = {ADMIN}) Integer adminId,
@PathVariable Integer coopShopId
) {
AdminCoopShopResponse coopShop = adminCoopShopService.getCoopShop(coopShopId);
return ResponseEntity.ok(coopShop);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package in.koreatech.koin.admin.coopShop.dto;

import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import java.util.List;

import com.fasterxml.jackson.databind.annotation.JsonNaming;

import in.koreatech.koin.domain.coopshop.model.CoopOpen;
import in.koreatech.koin.domain.coopshop.model.CoopShop;
import io.swagger.v3.oas.annotations.media.Schema;

@JsonNaming(value = SnakeCaseStrategy.class)
public record AdminCoopShopResponse(
@Schema(example = "1", description = "생협 매장 고유 id", requiredMode = REQUIRED)
Integer id,

@Schema(example = "세탁소", description = "생협 매장 이름", requiredMode = REQUIRED)
String name,

@Schema(description = "요일별 생협 매장 운영시간")
List<InnerCoopOpens> opens,

@Schema(example = "041-560-1234", description = "생협 매장 연락처", requiredMode = REQUIRED)
String phone,

@Schema(example = "학생식당 2층", description = "생협 매장 위치", requiredMode = REQUIRED)
String location,

@Schema(example = "공휴일 휴무", description = "생협 매장 특이사항")
String remarks
) {

public static AdminCoopShopResponse from(CoopShop coopShop) {
return new AdminCoopShopResponse(
coopShop.getId(),
coopShop.getName(),
coopShop.getCoopOpens().stream()
.map(InnerCoopOpens::from)
.toList(),
coopShop.getPhone(),
coopShop.getLocation(),
coopShop.getRemarks()
);
}

@JsonNaming(value = SnakeCaseStrategy.class)
public record InnerCoopOpens(

@Schema(example = "평일", description = "생협 매장 운영시간 요일", requiredMode = REQUIRED)
String dayOfWeek,

@Schema(example = "아침", description = "생협 매장 운영시간 타입", requiredMode = REQUIRED)
String type,

@Schema(example = "09:00", description = "생협 매장 오픈 시간", requiredMode = REQUIRED)
String openTime,

@Schema(example = "18:00", description = "생협 매장 마감 시간", requiredMode = REQUIRED)
String closeTime
) {

public static InnerCoopOpens from(CoopOpen coopOpen) {
return new InnerCoopOpens(
coopOpen.getDayOfWeek(),
coopOpen.getType(),
coopOpen.getOpenTime(),
coopOpen.getCloseTime()
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package in.koreatech.koin.admin.coopShop.dto;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import java.util.List;

import org.springframework.data.domain.Page;

import in.koreatech.koin.domain.coopshop.model.CoopShop;
import in.koreatech.koin.global.model.Criteria;
import io.swagger.v3.oas.annotations.media.Schema;

public record AdminCoopShopsResponse(

@Schema(description = "조건에 해당하는 총 생협 매장의 수", example = "20", requiredMode = REQUIRED)
Long totalCount,

@Schema(description = "조건에 해당하는 생협 매장 중 현재 페이지에서 조회된 수", example = "10", requiredMode = REQUIRED)
Integer currentCount,

@Schema(description = "조건에 해당하는 생협 매장을 조회할 수 있는 최대 페이지", example = "6", requiredMode = REQUIRED)
Integer totalPage,

@Schema(description = "현재 페이지", example = "1", requiredMode = REQUIRED)
Integer currentPage,

@Schema(description = "생협 매장 정보 리스트", requiredMode = REQUIRED)
List<AdminCoopShopResponse> coopShops
) {
public static AdminCoopShopsResponse of(Page<CoopShop> pagedResult, Criteria criteria) {
return new AdminCoopShopsResponse(
pagedResult.getTotalElements(),
pagedResult.getContent().size(),
pagedResult.getTotalPages(),
criteria.getPage() + 1,
pagedResult.getContent()
.stream()
.map(AdminCoopShopResponse::from)
.toList()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package in.koreatech.koin.admin.coopShop.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.coopshop.exception.CoopShopNotFoundException;
import in.koreatech.koin.domain.coopshop.model.CoopShop;

public interface AdminCoopShopRepository extends Repository<CoopShop, Integer> {

Page<CoopShop> findAllByIsDeleted(boolean isDeleted, Pageable pageable);

Integer countAllByIsDeleted(boolean isDeleted);

List<CoopShop> findAll();

CoopShop save(CoopShop coopShop);

Optional<CoopShop> findByName(String name);

default CoopShop getByName(String name) {
return findByName(name)
.orElseThrow(() -> CoopShopNotFoundException.withDetail("coop_name : " + name));
}

Optional<CoopShop> findById(Integer id);

default CoopShop getById(Integer id) {
return findById(id)
.orElseThrow(() -> CoopShopNotFoundException.withDetail("coop_id : " + id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package in.koreatech.koin.admin.coopShop.service;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import in.koreatech.koin.admin.coopShop.dto.AdminCoopShopResponse;
import in.koreatech.koin.admin.coopShop.dto.AdminCoopShopsResponse;
import in.koreatech.koin.admin.coopShop.repository.AdminCoopShopRepository;
import in.koreatech.koin.domain.coopshop.dto.CoopShopResponse;
import in.koreatech.koin.domain.coopshop.model.CoopShop;
import in.koreatech.koin.global.model.Criteria;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class AdminCoopShopService {

private final AdminCoopShopRepository adminCoopShopRepository;

public AdminCoopShopsResponse getCoopsShops(Integer page, Integer limit, Boolean isDeleted) {
Integer total = adminCoopShopRepository.countAllByIsDeleted(isDeleted);

Criteria criteria = Criteria.of(page, limit, total);
PageRequest pageRequest = PageRequest.of(criteria.getPage(), criteria.getLimit(),
Sort.by(Sort.Direction.ASC, "id"));

Page<CoopShop> result = adminCoopShopRepository.findAllByIsDeleted(isDeleted, pageRequest);

return AdminCoopShopsResponse.of(result, criteria);
}

public AdminCoopShopResponse getCoopShop(Integer id) {
CoopShop coopShop = adminCoopShopRepository.getById(id);
return AdminCoopShopResponse.from(coopShop);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import jakarta.validation.Valid;

@RequestMapping("/coop")
@Tag(name = "(OWNER) Coop Dining : 영양사 식단", description = "영양사 식단 페이지")
@Tag(name = "(COOP) Coop Dining : 영양사 식단", description = "영양사 식단 페이지")
public interface CoopApi {

@ApiResponses(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package in.koreatech.koin.domain.coopshop.controller;

import static io.swagger.v3.oas.annotations.enums.ParameterIn.PATH;

import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import in.koreatech.koin.domain.coopshop.dto.CoopShopResponse;
import in.koreatech.koin.domain.coopshop.model.CoopShop;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

@RequestMapping("/coopshop")
@Tag(name = "(NORMAL) CoopShop : 생협 매장 정보", description = "생협 매장 정보 조회 페이지")
public interface CoopShopApi {

@ApiResponses(
value = {
@ApiResponse(responseCode = "200"),
@ApiResponse(responseCode = "400", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true)))
}
)
@Operation(summary = "모든 생협 매장 정보 조회")
@GetMapping
ResponseEntity<List<CoopShopResponse>> getCoopsShops();

@ApiResponses(
value = {
@ApiResponse(responseCode = "200"),
@ApiResponse(responseCode = "400", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true)))
}
)
@Operation(summary = "특정 생협 매장 정보 조회")
@GetMapping("/{coopShopId}")
ResponseEntity<CoopShopResponse> getCoopShop(
@Parameter(in = PATH) @PathVariable Integer coopShopId
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package in.koreatech.koin.domain.coopshop.controller;

import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import in.koreatech.koin.domain.coopshop.dto.CoopShopResponse;
import in.koreatech.koin.domain.coopshop.service.CoopShopService;
import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/coopshop")
@RequiredArgsConstructor
public class CoopShopController implements CoopShopApi {

private final CoopShopService coopShopService;

@GetMapping
public ResponseEntity<List<CoopShopResponse>> getCoopsShops() {
List<CoopShopResponse> coopShops = coopShopService.getCoopShops();
return ResponseEntity.ok(coopShops);
}

@GetMapping("/{coopShopId}")
public ResponseEntity<CoopShopResponse> getCoopShop(
@PathVariable Integer coopShopId
) {
CoopShopResponse coopShop = coopShopService.getCoopShop(coopShopId);
return ResponseEntity.ok(coopShop);
}
}
Loading

0 comments on commit 9996c04

Please sign in to comment.