diff --git a/src/main/java/koreatech/in/controller/OwnerShopController.java b/src/main/java/koreatech/in/controller/OwnerShopController.java index d40ec377..c0c53eeb 100644 --- a/src/main/java/koreatech/in/controller/OwnerShopController.java +++ b/src/main/java/koreatech/in/controller/OwnerShopController.java @@ -1,6 +1,25 @@ package koreatech.in.controller; -import io.swagger.annotations.*; +import javax.validation.Valid; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; import koreatech.in.annotation.Auth; import koreatech.in.annotation.ParamValid; import koreatech.in.dto.EmptyResponse; @@ -8,18 +27,18 @@ import koreatech.in.dto.RequestDataInvalidResponse; import koreatech.in.dto.normal.shop.request.CreateMenuCategoryRequest; import koreatech.in.dto.normal.shop.request.CreateMenuRequest; +import koreatech.in.dto.normal.shop.request.CreateShopRequest; import koreatech.in.dto.normal.shop.request.UpdateMenuRequest; import koreatech.in.dto.normal.shop.request.UpdateShopRequest; -import koreatech.in.dto.normal.shop.response.*; +import koreatech.in.dto.normal.shop.response.AllMenuCategoriesOfShopResponse; +import koreatech.in.dto.normal.shop.response.AllMenusOfShopResponse; +import koreatech.in.dto.normal.shop.response.AllShopsOfOwnerResponse; +import koreatech.in.dto.normal.shop.response.MenuResponse; +import koreatech.in.dto.normal.shop.response.ShopResponse; +import koreatech.in.exception.BaseException; +import koreatech.in.exception.ExceptionInformation; import koreatech.in.service.OwnerShopService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; +import koreatech.in.util.StringXssChecker; @Auth(role = Auth.Role.OWNER, authority = Auth.Authority.SHOP) @Api(tags = "(Normal) Owner Shop", description = "상점 (점주 전용)") @@ -31,6 +50,30 @@ public class OwnerShopController { // =============================================== 상점 ================================================= + @ApiOperation(value = "상점 생성", notes = "- 사장님 권한만 허용", authorizations = {@Authorization("Authorization")}) + @ApiResponses({ + @ApiResponse(code = 401, message = "- 잘못된 접근일 때 (code: 100001) \n" + + "- 액세스 토큰이 만료되었을 때 (code: 100004) \n" + + "- 액세스 토큰이 변경되었을 때 (code: 100005)", response = ExceptionResponse.class), + @ApiResponse(code = 403, message = "- 권한이 없을 때 (code: 100003)", response = ExceptionResponse.class) + }) + @ParamValid + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = "", method = RequestMethod.POST) + public @ResponseBody + ResponseEntity createShop(@ApiParam(name = "상점 정보 JSON", required = true) @RequestBody @Valid CreateShopRequest request, BindingResult bindingResult) { + try { + request = StringXssChecker.xssCheck(request, request.getClass().newInstance()); + } catch (Exception exception) { + throw new BaseException(ExceptionInformation.REQUEST_DATA_INVALID); + } + + request.checkDataConstraintViolation(); // javax validation으로 판단할 수 없는 제약조건 검사 + + ownerShopService.createShop(request); + return new ResponseEntity<>(HttpStatus.CREATED); + } + @ApiOperation(value = "상점 조회", notes = "- 사장님 권한만 허용\n- 인증 정보에 대한 신원이 해당 상점의 점주가 아니라면 403(Forbidden) 응답", authorizations = {@Authorization("Authorization")}) @ApiResponses({ @ApiResponse(code = 401, message = "- 잘못된 접근일 때 (code: 100001) \n" + diff --git a/src/main/java/koreatech/in/domain/Shop/Shop.java b/src/main/java/koreatech/in/domain/Shop/Shop.java index 5dadc039..e2613713 100644 --- a/src/main/java/koreatech/in/domain/Shop/Shop.java +++ b/src/main/java/koreatech/in/domain/Shop/Shop.java @@ -1,13 +1,14 @@ package koreatech.in.domain.Shop; +import java.util.Date; +import java.util.Objects; + import koreatech.in.dto.admin.shop.request.UpdateShopRequest; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.*; - @Getter @Builder @NoArgsConstructor @AllArgsConstructor @@ -79,6 +80,11 @@ public void update(koreatech.in.dto.normal.shop.request.UpdateShopRequest reques this.chosung = this.internal_name.substring(0, 1); } + public void nameUpdate() { + this.internal_name = this.name.replace(" ", "").toLowerCase(); + this.chosung = this.internal_name.substring(0, 1); + } + public boolean hasSameOwnerId(Integer ownerId) { if (this.owner_id == null) { return false; diff --git a/src/main/java/koreatech/in/dto/admin/shop/request/CreateShopRequest.java b/src/main/java/koreatech/in/dto/admin/shop/request/CreateShopRequest.java index bd35d128..d8727950 100644 --- a/src/main/java/koreatech/in/dto/admin/shop/request/CreateShopRequest.java +++ b/src/main/java/koreatech/in/dto/admin/shop/request/CreateShopRequest.java @@ -14,6 +14,7 @@ import static koreatech.in.exception.ExceptionInformation.*; @Getter @Setter +@ApiModel("AdminCreateShopRequest") public class CreateShopRequest { @Size(min = 1, max = 15, message = "가게명의 길이는 1자 이상 15자 이하입니다.") @NotNull(message = "가게명은 필수입니다.") diff --git a/src/main/java/koreatech/in/dto/normal/shop/request/CreateShopRequest.java b/src/main/java/koreatech/in/dto/normal/shop/request/CreateShopRequest.java new file mode 100644 index 00000000..c5dfc882 --- /dev/null +++ b/src/main/java/koreatech/in/dto/normal/shop/request/CreateShopRequest.java @@ -0,0 +1,153 @@ +package koreatech.in.dto.normal.shop.request; + +import static koreatech.in.exception.ExceptionInformation.DUPLICATE_DAY_OF_WEEK_INFORMATION_EXISTS; +import static koreatech.in.exception.ExceptionInformation.LENGTH_OF_OPENS_MUST_BE_7; +import static koreatech.in.exception.ExceptionInformation.TIME_INFORMATION_IS_REQUIRED_UNLESS_CLOSED; + +import java.time.DayOfWeek; +import java.util.ArrayList; +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.PositiveOrZero; +import javax.validation.constraints.Size; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import koreatech.in.exception.BaseException; +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +@ApiModel("CreateShopRequest") +public class CreateShopRequest { + @Size(min = 1, max = 15, message = "가게명의 길이는 1자 이상 15자 이하입니다.") + @NotNull(message = "가게명은 필수입니다.") + @ApiModelProperty(notes = "가게명 \n" + + "- not null \n" + + "- 1자 이상 15자 이하", example = "써니 숯불 도시락", required = true) + private String name; + + @Pattern(regexp = "^[0-9]{3}-[0-9]{3,4}-[0-9]{4}$", message = "전화번호의 형식이 올바르지 않습니다.") + @NotNull(message = "전화번호는 필수입니다.") + @ApiModelProperty(notes = "전화번호 \n" + + "- not null \n" + + "- 정규식 `^[0-9]{3}-[0-9]{3,4}-[0-9]{4}$`을 만족해야함", example = "041-123-4567", required = true) + private String phone; + + @Valid + @NotNull(message = "운영 시간 정보는 필수입니다.") + @ApiModelProperty(notes = "요일별 운영 시간과 휴무 여부 \n" + + "- not null \n" + + "- 리스트의 길이는 7(1주일 요일 개수) 이어야 함 \n" + + "- day_of_week은 각각 `MONDAY`, `TUESDAY`, `WEDNESDAY`, `THURSDAY`, `FRIDAY`, `SATURDAY`, `SUNDAY` 이어야 함", required = true) + private List open = new ArrayList<>(); + + @Size(min = 1, max = 100, message = "주소의 길이는 1자 이상 100자 이하입니다.") + @NotNull(message = "주소는 필수입니다.") + @ApiModelProperty(notes = "주소 \n" + + "- not null \n" + + "- 1자 이상 100자 이하", example = "충청남도 천안시 동남구 병천면 충절로 1600", required = true) + private String address; + + @PositiveOrZero(message = "배달 금액은 0원 이상이어야 합니다.") + @ApiModelProperty(notes = "배달 금액 \n" + + "- 0 이상 2147483647 이하 \n" + + "- null일 경우 0으로 저장됨", example = "1000") + private Integer delivery_price = 0; + + @Size(min = 1, max = 50, message = "기타정보의 길이는 1자 이상 50자 이하입니다.") + @ApiModelProperty(notes = "기타정보 \n" + + "- 1자 이상 50자 이하", example = "이번주 전 메뉴 10% 할인 이벤트합니다.") + private String description; + + @NotNull(message = "배달 가능 여부는 필수입니다.") + @ApiModelProperty(notes = "배달 가능 여부 \n" + + "- not null", example = "false", required = true) + private Boolean delivery; + + @NotNull(message = "카드 가능 여부는 필수입니다.") + @ApiModelProperty(notes = "카드 가능 여부 \n" + + "- not null", example = "true", required = true) + private Boolean pay_card; + + @NotNull(message = "계좌 이체 가능 여부는 필수입니다.") + @ApiModelProperty(notes = "계좌 이체 가능 여부 \n" + + "- not null", example = "true", required = true) + private Boolean pay_bank; + + @NotEmpty(message = "소속시킬 상점 카테고리는 최소 1개 선택하여야합니다.") + @ApiModelProperty(notes = "상점 카테고리 고유 id 리스트 \n" + + "- not null \n" + + "- 최소 1개 \n" + + "- 예시 : [1, 4]", allowableValues = "1, 2, 3, 4, 5", required = true) + private List category_ids = new ArrayList<>(); + + @Size(max = 10, message = "상점 이미지 개수 제한은 최대 10개입니다.") + @ApiModelProperty(notes = "이미지 URL 리스트 \n" + + "- 최대 10개") + private List image_urls = new ArrayList<>(); + + @Getter @Setter + @ApiModel("Open_7") + public static class Open { + @NotNull(message = "운영 시간의 요일 정보는 필수입니다.") + @ApiModelProperty(notes = "요일 \n" + + "- not null \n" + + "- `MONDAY`, `TUESDAY`, `WEDNESDAY`, `THURSDAY`, `FRIDAY`, `SATURDAY`, `SUNDAY` 중 택1 (중복되면 안됨)", example = "MONDAY", required = true) + private DayOfWeek day_of_week; + + @NotNull(message = "운영 시간의 휴무 여부는 필수입니다.") + @ApiModelProperty(notes = "휴무 여부 \n" + + "- not null", example = "false", required = true) + private Boolean closed; + + @Pattern(regexp = "^([01][0-9]|2[0-3]):([0-5][0-9])$", message = "운영 시간의 여는 시간 정보 형식이 올바르지 않습니다.") + @ApiModelProperty(notes = "여는 시간 \n" + + "- closed가 false일 때 \n" + + " - not null \n" + + " - 정규식 `^([01][0-9]|2[0-3]):([0-5][0-9])$`을 만족해야 함 \n" + + "- closed가 true일 때 \n" + + " - 어떤 값이 요청되던 null로 저장됨", example = "10:00") + private String open_time; + + @Pattern(regexp = "^([01][0-9]|2[0-3]):([0-5][0-9])$", message = "운영 시간의 닫는 시간 정보 형식이 올바르지 않습니다.") + @ApiModelProperty(notes = "닫는 시간 \n" + + "- closed가 false일때 \n" + + " - not null \n" + + " - 정규식 `^([01][0-9]|2[0-3]):([0-5][0-9])$`을 만족해야 함 \n" + + "- closed가 true일 때 \n" + + " - 어떤 값이 요청되던 null로 저장됨", example = "22:30") + private String close_time; + } + + public void checkDataConstraintViolation() { + checkOpenConstraintViolation(); + } + + private void checkOpenConstraintViolation() { + if (this.open.size() != 7) { + throw new BaseException(LENGTH_OF_OPENS_MUST_BE_7); + } + + boolean hasEmptyTimeInformation = this.open.stream() + .filter(open -> !open.getClosed()) + .anyMatch(open -> open.getOpen_time() == null || open.getClose_time() == null); + + if (hasEmptyTimeInformation) { + throw new BaseException(TIME_INFORMATION_IS_REQUIRED_UNLESS_CLOSED); + } + + boolean hasDuplicateDayOfWeek = this.open.stream() + .map(Open::getDay_of_week) + .distinct() + .count() != 7; + + if (hasDuplicateDayOfWeek) { + throw new BaseException(DUPLICATE_DAY_OF_WEEK_INFORMATION_EXISTS); + } + } +} diff --git a/src/main/java/koreatech/in/mapstruct/normal/shop/ShopConverter.java b/src/main/java/koreatech/in/mapstruct/normal/shop/ShopConverter.java index de03dcc5..0e904530 100644 --- a/src/main/java/koreatech/in/mapstruct/normal/shop/ShopConverter.java +++ b/src/main/java/koreatech/in/mapstruct/normal/shop/ShopConverter.java @@ -1,6 +1,8 @@ package koreatech.in.mapstruct.normal.shop; +import koreatech.in.domain.Shop.Shop; import koreatech.in.domain.Shop.ShopProfile; +import koreatech.in.dto.normal.shop.request.CreateShopRequest; import koreatech.in.dto.normal.shop.response.AllShopsResponse; import koreatech.in.dto.normal.shop.response.ShopResponse; import org.mapstruct.Mapper; @@ -15,4 +17,7 @@ public interface ShopConverter { @Mapping(target = "category_ids", expression = "java(shopProfile.getShopCategoryIds())") AllShopsResponse.Shop toAllShopsResponse$Shop(ShopProfile shopProfile); + + @Mapping(source = "ownerId", target = "owner_id") + Shop toShop(CreateShopRequest request, Integer ownerId); } diff --git a/src/main/java/koreatech/in/mapstruct/normal/shop/ShopOpenConverter.java b/src/main/java/koreatech/in/mapstruct/normal/shop/ShopOpenConverter.java index fe64e94d..0ac16f57 100644 --- a/src/main/java/koreatech/in/mapstruct/normal/shop/ShopOpenConverter.java +++ b/src/main/java/koreatech/in/mapstruct/normal/shop/ShopOpenConverter.java @@ -1,6 +1,7 @@ package koreatech.in.mapstruct.normal.shop; import koreatech.in.domain.Shop.ShopOpen; +import koreatech.in.dto.normal.shop.request.CreateShopRequest; import koreatech.in.dto.normal.shop.request.UpdateShopRequest; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -11,5 +12,8 @@ public interface ShopOpenConverter { ShopOpenConverter INSTANCE = Mappers.getMapper(ShopOpenConverter.class); @Mapping(source = "shopId", target = "shop_id") - ShopOpen toShopOpen(UpdateShopRequest.Open open, Integer shopId); + ShopOpen toShopOpenForCreate(CreateShopRequest.Open open, Integer shopId); + + @Mapping(source = "shopId", target = "shop_id") + ShopOpen toShopOpenForUpdate(UpdateShopRequest.Open open, Integer shopId); } diff --git a/src/main/java/koreatech/in/repository/ShopMapper.java b/src/main/java/koreatech/in/repository/ShopMapper.java index 3201a617..3ef29ea7 100644 --- a/src/main/java/koreatech/in/repository/ShopMapper.java +++ b/src/main/java/koreatech/in/repository/ShopMapper.java @@ -22,8 +22,12 @@ public interface ShopMapper { List getShopByOwnerId(@Param("ownerId") Integer ownerId); + void createShop(@Param("shop") Shop shop); + void updateShop(@Param("shop") Shop shop); + void createShopOpens(@Param("shopOpens") List shopOpens); + void updateShopOpens(@Param("shopOpens") List shopOpens); ShopCategory getShopCategoryById(@Param("id") Integer id); diff --git a/src/main/java/koreatech/in/service/OwnerShopService.java b/src/main/java/koreatech/in/service/OwnerShopService.java index 85043079..d4d67f9f 100644 --- a/src/main/java/koreatech/in/service/OwnerShopService.java +++ b/src/main/java/koreatech/in/service/OwnerShopService.java @@ -2,15 +2,22 @@ import koreatech.in.dto.normal.shop.request.CreateMenuCategoryRequest; import koreatech.in.dto.normal.shop.request.CreateMenuRequest; +import koreatech.in.dto.normal.shop.request.CreateShopRequest; import koreatech.in.dto.normal.shop.request.UpdateMenuRequest; import koreatech.in.dto.normal.shop.request.UpdateShopRequest; -import koreatech.in.dto.normal.shop.response.*; +import koreatech.in.dto.normal.shop.response.AllMenuCategoriesOfShopResponse; +import koreatech.in.dto.normal.shop.response.AllMenusOfShopResponse; +import koreatech.in.dto.normal.shop.response.AllShopsOfOwnerResponse; +import koreatech.in.dto.normal.shop.response.MenuResponse; +import koreatech.in.dto.normal.shop.response.ShopResponse; public interface OwnerShopService { ShopResponse getShop(Integer shopId); AllShopsOfOwnerResponse getAllShopsOfOwner(); + void createShop(CreateShopRequest request); + void updateShop(Integer shopId, UpdateShopRequest request); void createMenuCategory(Integer shopId, CreateMenuCategoryRequest request); diff --git a/src/main/java/koreatech/in/service/OwnerShopServiceImpl.java b/src/main/java/koreatech/in/service/OwnerShopServiceImpl.java index 9e4cad1f..1b659a6c 100644 --- a/src/main/java/koreatech/in/service/OwnerShopServiceImpl.java +++ b/src/main/java/koreatech/in/service/OwnerShopServiceImpl.java @@ -1,26 +1,50 @@ package koreatech.in.service; -import koreatech.in.domain.Shop.*; +import static koreatech.in.exception.ExceptionInformation.FORBIDDEN; +import static koreatech.in.exception.ExceptionInformation.SHOP_CATEGORY_NOT_FOUND; +import static koreatech.in.exception.ExceptionInformation.SHOP_MENU_CATEGORY_MAXIMUM_EXCEED; +import static koreatech.in.exception.ExceptionInformation.SHOP_MENU_CATEGORY_NAME_DUPLICATE; +import static koreatech.in.exception.ExceptionInformation.SHOP_MENU_CATEGORY_NOT_FOUND; +import static koreatech.in.exception.ExceptionInformation.SHOP_MENU_NOT_FOUND; +import static koreatech.in.exception.ExceptionInformation.SHOP_MENU_USING_CATEGORY_EXIST; +import static koreatech.in.exception.ExceptionInformation.SHOP_NOT_FOUND; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import koreatech.in.domain.Shop.Shop; +import koreatech.in.domain.Shop.ShopCategory; +import koreatech.in.domain.Shop.ShopCategoryMap; +import koreatech.in.domain.Shop.ShopImage; +import koreatech.in.domain.Shop.ShopMenu; +import koreatech.in.domain.Shop.ShopMenuCategory; +import koreatech.in.domain.Shop.ShopMenuCategoryMap; +import koreatech.in.domain.Shop.ShopMenuDetail; +import koreatech.in.domain.Shop.ShopMenuImage; +import koreatech.in.domain.Shop.ShopMenuProfile; +import koreatech.in.domain.Shop.ShopOpen; +import koreatech.in.domain.Shop.ShopProfile; import koreatech.in.domain.User.owner.Owner; import koreatech.in.dto.normal.shop.request.CreateMenuCategoryRequest; import koreatech.in.dto.normal.shop.request.CreateMenuRequest; +import koreatech.in.dto.normal.shop.request.CreateShopRequest; import koreatech.in.dto.normal.shop.request.UpdateMenuRequest; import koreatech.in.dto.normal.shop.request.UpdateShopRequest; -import koreatech.in.dto.normal.shop.response.*; +import koreatech.in.dto.normal.shop.response.AllMenuCategoriesOfShopResponse; +import koreatech.in.dto.normal.shop.response.AllMenusOfShopResponse; +import koreatech.in.dto.normal.shop.response.AllShopsOfOwnerResponse; +import koreatech.in.dto.normal.shop.response.MenuResponse; +import koreatech.in.dto.normal.shop.response.ShopResponse; import koreatech.in.exception.BaseException; import koreatech.in.mapstruct.normal.shop.ShopConverter; import koreatech.in.mapstruct.normal.shop.ShopMenuConverter; import koreatech.in.mapstruct.normal.shop.ShopOpenConverter; import koreatech.in.repository.ShopMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import static koreatech.in.exception.ExceptionInformation.*; @Service @Transactional @@ -48,6 +72,45 @@ public AllShopsOfOwnerResponse getAllShopsOfOwner() { return AllShopsOfOwnerResponse.from(shopMapper.getShopProfilesByOwnerId(owner.getId())); } + @Override + public void createShop(CreateShopRequest request) { + Shop shop = createShopsTable(request); + createShopOpensTable(request, shop); + createShopCategoryMapTable(request, shop); + createShopImages(request, shop); + } + + private Shop createShopsTable(CreateShopRequest request) { + Owner owner = (Owner) jwtValidator.validate(); + Shop shop = ShopConverter.INSTANCE.toShop(request, owner.getId()); + shop.nameUpdate(); + shopMapper.createShop(shop); + + return shop; + } + + private void createShopOpensTable(CreateShopRequest request, Shop shop) { + List shopOpens = generateShopOpens(request.getOpen(), shop.getId()); + shopMapper.createShopOpens(shopOpens); + } + + private void createShopCategoryMapTable(CreateShopRequest request, Shop shop) { + shopCategoriesExist(request.getCategory_ids()); + List shopCategoryMaps = generateShopCategoryMaps(shop.getId(), request.getCategory_ids()); + shopMapper.createShopCategoryMaps(shopCategoryMaps); + } + + private void createShopImages(CreateShopRequest request, Shop shop) { + List shopImages = generateShopImages(shop.getId(), request.getImage_urls()); + shopMapper.createShopImages(shopImages); + } + + private List generateShopOpens(List opens, Integer shopId) { + return opens.stream() + .map(open -> ShopOpenConverter.INSTANCE.toShopOpenForCreate(open, shopId)) + .collect(Collectors.toList()); + } + @Override public void updateShop(Integer shopId, UpdateShopRequest request) { Shop existingShop = getShopById(shopId); @@ -74,12 +137,12 @@ public void updateShop(Integer shopId, UpdateShopRequest request) { // ======= shop_category_map 테이블 ======= - checkShopCategoriesExistInDatabase(request.getCategory_ids()); + shopCategoriesExist(request.getCategory_ids()); List existingShopCategoryMaps = shopMapper.getShopCategoryMapsByShopId(existingShop.getId()); // IGNORE에 의하여 (shop_id, shop_category_id)가 중복일 경우는 insert가 무시된다. - List requestedCategoryMaps = generateShopCategoryMapsAndGet(existingShop.getId(), request.getCategory_ids()); + List requestedCategoryMaps = generateShopCategoryMaps(existingShop.getId(), request.getCategory_ids()); shopMapper.createShopCategoryMaps(requestedCategoryMaps); // 기존에 있던 관계들에서 요청된 관계들을 제거하면 삭제해야할 관계들을 알아낼 수 있다. @@ -92,7 +155,7 @@ public void updateShop(Integer shopId, UpdateShopRequest request) { // ======= shop_images 테이블 ======= List existingShopImages = shopMapper.getShopImagesByShopId(existingShop.getId()); - List requestedShopImages = generateShopImagesAndGet(existingShop.getId(), request.getImage_urls()); + List requestedShopImages = generateShopImages(existingShop.getId(), request.getImage_urls()); if (!requestedShopImages.isEmpty()) { shopMapper.createShopImages(requestedShopImages); } @@ -105,18 +168,18 @@ public void updateShop(Integer shopId, UpdateShopRequest request) { private List generateShopOpensAndGetForUpdate(List opens, Integer shopId) { return opens.stream() - .map(open -> ShopOpenConverter.INSTANCE.toShopOpen(open, shopId)) + .map(open -> ShopOpenConverter.INSTANCE.toShopOpenForUpdate(open, shopId)) .collect(Collectors.toList()); } - private void checkShopCategoriesExistInDatabase(List shopCategoryIds) { + private void shopCategoriesExist(List shopCategoryIds) { shopCategoryIds.forEach(categoryId -> { Optional.ofNullable(shopMapper.getShopCategoryById(categoryId)) .orElseThrow(() -> new BaseException(SHOP_CATEGORY_NOT_FOUND)); }); } - private List generateShopCategoryMapsAndGet(Integer shopId, List shopCategoryIds) { + private List generateShopCategoryMaps(Integer shopId, List shopCategoryIds) { return shopCategoryIds.stream() .map(shopCategoryId -> ShopCategoryMap.of(shopId, shopCategoryId)) .collect(Collectors.toList()); @@ -127,7 +190,7 @@ private List getToBeDeletedShopCategoryMaps(List generateShopImagesAndGet(Integer shopId, List imageUrls) { + private List generateShopImages(Integer shopId, List imageUrls) { return imageUrls.stream() .map(url -> ShopImage.of(shopId, url)) .collect(Collectors.toList()); diff --git a/src/main/resources/mapper/normal/ShopMapper.xml b/src/main/resources/mapper/normal/ShopMapper.xml index 7ce0009a..52189d2b 100644 --- a/src/main/resources/mapper/normal/ShopMapper.xml +++ b/src/main/resources/mapper/normal/ShopMapper.xml @@ -272,6 +272,38 @@ AND `is_deleted` = 0 + + INSERT INTO `koin`.`shops` ( + `owner_id`, + `name`, + `internal_name`, + `chosung`, + `phone`, + `address`, + `description`, + `delivery`, + `delivery_price`, + `pay_card`, + `pay_bank` + ) + VALUES ( + #{shop.owner_id}, + #{shop.name}, + #{shop.internal_name}, + #{shop.chosung}, + #{shop.phone}, + #{shop.address}, + #{shop.description}, + #{shop.delivery}, + #{shop.delivery_price}, + #{shop.pay_card}, + #{shop.pay_bank} + ) + + SELECT LAST_INSERT_ID() + + + UPDATE `koin`.`shops` SET @@ -289,6 +321,26 @@ `id` = #{shop.id} + + INSERT INTO `koin`.`shop_opens` ( + `shop_id`, + `day_of_week`, + `closed`, + `open_time`, + `close_time` + ) + VALUES + + ( + #{item.shop_id}, + #{item.day_of_week}, + #{item.closed}, + #{item.open_time}, + #{item.close_time} + ) + + + UPDATE `koin`.`shop_opens`