diff --git a/src/main/java/com/moddy/server/controller/designer/DesignerController.java b/src/main/java/com/moddy/server/controller/designer/DesignerController.java index 65fa72db..4f5dfc27 100644 --- a/src/main/java/com/moddy/server/controller/designer/DesignerController.java +++ b/src/main/java/com/moddy/server/controller/designer/DesignerController.java @@ -1,12 +1,10 @@ package com.moddy.server.controller.designer; import com.moddy.server.common.dto.ErrorResponse; -import com.moddy.server.common.dto.SuccessNonDataResponse; import com.moddy.server.common.dto.SuccessResponse; import com.moddy.server.common.exception.enums.SuccessCode; import com.moddy.server.config.resolver.user.UserId; import com.moddy.server.controller.designer.dto.request.DesignerCreateRequest; -import com.moddy.server.controller.designer.dto.request.OfferCreateRequest; import com.moddy.server.controller.designer.dto.request.OfferImageUrlRequestDto; import com.moddy.server.controller.designer.dto.response.ApplicationDetailInfoResponse; import com.moddy.server.controller.designer.dto.response.DownloadUrlResponseDto; @@ -14,6 +12,7 @@ import com.moddy.server.service.application.HairModelApplicationRetrieveService; import com.moddy.server.service.designer.DesignerRegisterService; import com.moddy.server.service.designer.DesignerService; +import com.moddy.server.service.offer.HairServiceOfferRegisterService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; @@ -25,7 +24,6 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -33,8 +31,6 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; - import static com.moddy.server.common.exception.enums.SuccessCode.GET_PRE_SIGNED_URL_SUCCESS; @RestController @@ -45,7 +41,6 @@ public class DesignerController { private final DesignerService designerService; private final DesignerRegisterService designerRegisterService; - private final HairModelApplicationRetrieveService hairModelApplicationRetrieveService; @Tag(name = "Auth Controller", description = "로그인 및 회원 가입 관련 API 입니다.") @Operation(summary = "[JWT] 디자이너 회원가입 API", description = "디자이너 회원가입 조회 API입니다.") @@ -62,23 +57,6 @@ SuccessResponse createDesigner( return SuccessResponse.success(SuccessCode.DESIGNER_CREATE_SUCCESS, designerRegisterService.createDesigner(designerId, designerInfo, profileImg)); } - @Operation(summary = "[JWT] 제안서 작성하기", description = "제안서 작성하기 API입니다.") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "제안서 작성 성공", content = @Content(schema = @Schema(implementation = SuccessNonDataResponse.class))), - @ApiResponse(responseCode = "401", description = "인증 오류 입니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "404", description = "제안서가 존재하지 않습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "500", description = "서버 내부 오류 입니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - }) - @SecurityRequirement(name = "JWT Auth") - @PostMapping("{applicationId}/offer") - public SuccessNonDataResponse offerCreateRequest( - @Parameter(hidden = true) @UserId Long userId, - @PathVariable(value = "applicationId") Long applicationId, - @Valid @RequestBody OfferCreateRequest offerCreateRequest) throws IOException { - designerService.postOffer(userId, applicationId, offerCreateRequest); - return SuccessNonDataResponse.success(SuccessCode.POST_OFFER_SUCCESS); - } - @Operation(summary = "[JWT] 제안서 다운로드 링크", description = "디자이너 제안서 다운로드 링크 불러오는 API") @ApiResponses({ @ApiResponse(responseCode = "200", description = "모델 지원서 상세 조회 성공", content = @Content(schema = @Schema(implementation = ApplicationDetailInfoResponse.class))), diff --git a/src/main/java/com/moddy/server/controller/offer/OfferController.java b/src/main/java/com/moddy/server/controller/offer/OfferController.java index 2b7fad49..688d7f65 100644 --- a/src/main/java/com/moddy/server/controller/offer/OfferController.java +++ b/src/main/java/com/moddy/server/controller/offer/OfferController.java @@ -5,6 +5,7 @@ import com.moddy.server.common.dto.SuccessResponse; import com.moddy.server.common.exception.enums.SuccessCode; import com.moddy.server.config.resolver.user.UserId; +import com.moddy.server.controller.designer.dto.request.OfferCreateRequest; import com.moddy.server.controller.model.dto.response.OpenChatResponse; import com.moddy.server.controller.offer.dto.response.ModelMainOfferResponse; import com.moddy.server.controller.offer.response.DetailOfferResponse; @@ -18,13 +19,18 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.io.IOException; + @RestController @RequiredArgsConstructor public class OfferController { @@ -95,4 +101,22 @@ public SuccessResponse getModelDetailOfferInfo( @Parameter(name = "offerId", description = "제안서아이디") @PathVariable(value = "offerId") Long offerId) { return SuccessResponse.success(SuccessCode.FIND_MODEL_DETAIL_OFFER_SUCCESS, hairServiceOfferRetrieveService.getOfferDetail(modelId, offerId)); } + + @Tag(name = "DesignerController") + @Operation(summary = "[JWT] 제안서 작성하기", description = "제안서 작성하기 API입니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "제안서 작성 성공", content = @Content(schema = @Schema(implementation = SuccessNonDataResponse.class))), + @ApiResponse(responseCode = "401", description = "인증 오류 입니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode = "404", description = "제안서가 존재하지 않습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode = "500", description = "서버 내부 오류 입니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + }) + @SecurityRequirement(name = "JWT Auth") + @PostMapping("/designer/{applicationId}/offer") + public SuccessNonDataResponse offerCreateRequest( + @Parameter(hidden = true) @UserId Long designerId, + @PathVariable(value = "applicationId") Long applicationId, + @Valid @RequestBody OfferCreateRequest offerCreateRequest) throws IOException { + hairServiceOfferRegisterService.postOffer(designerId, applicationId, offerCreateRequest); + return SuccessNonDataResponse.success(SuccessCode.POST_OFFER_SUCCESS); + } } \ No newline at end of file diff --git a/src/main/java/com/moddy/server/domain/hair_service_offer/HairServiceOffer.java b/src/main/java/com/moddy/server/domain/hair_service_offer/HairServiceOffer.java index 15225c24..404cef13 100644 --- a/src/main/java/com/moddy/server/domain/hair_service_offer/HairServiceOffer.java +++ b/src/main/java/com/moddy/server/domain/hair_service_offer/HairServiceOffer.java @@ -8,6 +8,8 @@ import jakarta.validation.constraints.NotNull; import lombok.*; +import java.time.LocalDateTime; + @Entity @Getter @Builder @@ -35,11 +37,18 @@ public class HairServiceOffer extends BaseTimeEntity { @NotNull private String offerDetail; - @NotNull - private Boolean isModelAgree; + private boolean isModelAgree; - @NotNull - private Boolean isClicked; + private boolean isClicked; + + public HairServiceOffer(HairModelApplication hairModelApplication, Model model, Designer designer, String offerDetail, boolean isModelAgree, boolean isClicked) { + this.hairModelApplication = hairModelApplication; + this.model = model; + this.designer = designer; + this.offerDetail = offerDetail; + this.isModelAgree = isModelAgree; + this.isClicked = isClicked; + } public void agreeOfferToModel(){ this.isModelAgree = true; @@ -47,4 +56,5 @@ public void agreeOfferToModel(){ public void updateClickStatus() { this.isClicked = true; } + } diff --git a/src/main/java/com/moddy/server/domain/prefer_offer_condition/PreferOfferCondition.java b/src/main/java/com/moddy/server/domain/prefer_offer_condition/PreferOfferCondition.java index 58f0d1d1..eda91124 100644 --- a/src/main/java/com/moddy/server/domain/prefer_offer_condition/PreferOfferCondition.java +++ b/src/main/java/com/moddy/server/domain/prefer_offer_condition/PreferOfferCondition.java @@ -11,7 +11,6 @@ @Entity @Getter -@Builder @NoArgsConstructor @AllArgsConstructor public class PreferOfferCondition extends BaseTimeEntity { @@ -28,4 +27,8 @@ public class PreferOfferCondition extends BaseTimeEntity { @NotNull private OfferCondition offerCondition; + public PreferOfferCondition(final HairServiceOffer hairServiceOffer, final OfferCondition offerCondition){ + this.hairServiceOffer = hairServiceOffer; + this.offerCondition = offerCondition; + } } diff --git a/src/main/java/com/moddy/server/service/application/HairModelApplicationRetrieveService.java b/src/main/java/com/moddy/server/service/application/HairModelApplicationRetrieveService.java index 7e3b5dca..910c51b3 100644 --- a/src/main/java/com/moddy/server/service/application/HairModelApplicationRetrieveService.java +++ b/src/main/java/com/moddy/server/service/application/HairModelApplicationRetrieveService.java @@ -133,3 +133,4 @@ private HairModelApplicationResponse getApplicationResponse(final HairModelAppli return applicationResponse; } } + diff --git a/src/main/java/com/moddy/server/service/designer/DesignerService.java b/src/main/java/com/moddy/server/service/designer/DesignerService.java index 103f7803..cc2ab35b 100644 --- a/src/main/java/com/moddy/server/service/designer/DesignerService.java +++ b/src/main/java/com/moddy/server/service/designer/DesignerService.java @@ -1,39 +1,18 @@ package com.moddy.server.service.designer; -import com.moddy.server.common.exception.enums.ErrorCode; -import com.moddy.server.common.exception.model.ConflictException; import com.moddy.server.common.exception.model.NotFoundException; import com.moddy.server.common.util.SmsUtil; import com.moddy.server.config.jwt.JwtService; -import com.moddy.server.controller.designer.dto.request.DesignerCreateRequest; -import com.moddy.server.controller.designer.dto.request.OfferCreateRequest; -import com.moddy.server.controller.designer.dto.response.ApplicationDetailInfoResponse; -import com.moddy.server.controller.designer.dto.response.ApplicationInfoResponse; import com.moddy.server.controller.designer.dto.response.DownloadUrlResponseDto; -import com.moddy.server.controller.designer.dto.response.HairRecordResponse; -import com.moddy.server.controller.designer.dto.response.ModelInfoResponse; -import com.moddy.server.controller.designer.dto.response.UserCreateResponse; -import com.moddy.server.domain.day_off.DayOff; import com.moddy.server.domain.day_off.repository.DayOffJpaRepository; import com.moddy.server.domain.designer.Designer; -import com.moddy.server.domain.designer.HairShop; -import com.moddy.server.domain.designer.Portfolio; import com.moddy.server.domain.designer.repository.DesignerJpaRepository; -import com.moddy.server.domain.hair_model_application.HairModelApplication; import com.moddy.server.domain.hair_model_application.repository.HairModelApplicationJpaRepository; -import com.moddy.server.domain.hair_service_offer.HairServiceOffer; import com.moddy.server.domain.hair_service_offer.repository.HairServiceOfferJpaRepository; -import com.moddy.server.domain.hair_service_record.HairServiceRecord; -import com.moddy.server.domain.model.Model; import com.moddy.server.domain.model.repository.ModelJpaRepository; -import com.moddy.server.domain.prefer_hair_style.PreferHairStyle; import com.moddy.server.domain.prefer_hair_style.repository.PreferHairStyleJpaRepository; -import com.moddy.server.domain.prefer_offer_condition.PreferOfferCondition; import com.moddy.server.domain.prefer_offer_condition.repository.PreferOfferConditionJpaRepository; -import com.moddy.server.domain.prefer_region.PreferRegion; import com.moddy.server.domain.prefer_region.repository.PreferRegionJpaRepository; -import com.moddy.server.domain.user.Role; -import com.moddy.server.domain.user.User; import com.moddy.server.domain.user.repository.UserRepository; import com.moddy.server.external.kakao.feign.KakaoApiClient; import com.moddy.server.external.kakao.feign.KakaoAuthApiClient; @@ -44,13 +23,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; import static com.moddy.server.common.exception.enums.ErrorCode.DESIGNER_NOT_FOUND_EXCEPTION; @@ -76,38 +48,6 @@ public class DesignerService { private final HairServiceOfferJpaRepository hairServiceOfferJpaRepository; private final SmsUtil smsUtil; - @Transactional - public void postOffer(Long userId, Long applicationId, OfferCreateRequest request) throws IOException { - Designer designer = designerJpaRepository.findById(userId).orElseThrow(() -> new NotFoundException(DESIGNER_NOT_FOUND_EXCEPTION)); - HairModelApplication hairModelApplication = hairModelApplicationJpaRepository.findById(applicationId).orElseThrow(() -> new NotFoundException(ErrorCode.NOT_FOUND_APPLICATION_EXCEPTION)); - - if (hairServiceOfferJpaRepository.existsByHairModelApplicationIdAndDesignerId(applicationId,designer.getId())) throw new ConflictException(ErrorCode.ALREADY_EXIST_OFFER_EXCEPTION); - - HairServiceOffer offer = HairServiceOffer.builder() - .model(hairModelApplication.getModel()) - .hairModelApplication(hairModelApplication) - .designer(designer) - .offerDetail(request.offerDetail()) - .isModelAgree(false) - .isClicked(false) - .build(); - hairServiceOfferJpaRepository.save(offer); - - request.preferOfferConditions().stream() - .forEach(p -> { - PreferOfferCondition preferOfferCondition = PreferOfferCondition.builder() - .offerCondition(p) - .hairServiceOffer(offer) - .build(); - preferOfferConditionJpaRepository.save(preferOfferCondition); - - }); - - final String modelName = hairModelApplication.getModel().getName(); - final String modelPhoneNumber = hairModelApplication.getModel().getPhoneNumber(); - smsUtil.sendOfferToModel(modelPhoneNumber, modelName); - } - public DownloadUrlResponseDto getOfferImageDownloadUrl(final Long userId, final String offerImageUrl) { Designer designer = designerJpaRepository.findById(userId).orElseThrow(() -> new NotFoundException(DESIGNER_NOT_FOUND_EXCEPTION)); String preSignedUrl = s3Service.getPreSignedUrlToDownload(offerImageUrl); diff --git a/src/main/java/com/moddy/server/service/offer/HairServiceOfferRegisterService.java b/src/main/java/com/moddy/server/service/offer/HairServiceOfferRegisterService.java index 03b2f33c..ce50612c 100644 --- a/src/main/java/com/moddy/server/service/offer/HairServiceOfferRegisterService.java +++ b/src/main/java/com/moddy/server/service/offer/HairServiceOfferRegisterService.java @@ -1,21 +1,36 @@ package com.moddy.server.service.offer; import com.moddy.server.common.exception.enums.ErrorCode; +import com.moddy.server.common.exception.model.ConflictException; import com.moddy.server.common.exception.model.NotFoundException; +import com.moddy.server.common.util.SmsUtil; +import com.moddy.server.controller.designer.dto.request.OfferCreateRequest; +import com.moddy.server.domain.designer.Designer; +import com.moddy.server.domain.designer.repository.DesignerJpaRepository; +import com.moddy.server.domain.hair_model_application.HairModelApplication; +import com.moddy.server.domain.hair_model_application.repository.HairModelApplicationJpaRepository; import com.moddy.server.domain.hair_service_offer.HairServiceOffer; import com.moddy.server.domain.hair_service_offer.repository.HairServiceOfferJpaRepository; +import com.moddy.server.domain.model.Model; +import com.moddy.server.domain.prefer_offer_condition.PreferOfferCondition; import com.moddy.server.domain.prefer_offer_condition.repository.PreferOfferConditionJpaRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.io.IOException; import java.util.List; +import static com.moddy.server.common.exception.enums.ErrorCode.DESIGNER_NOT_FOUND_EXCEPTION; + @Service @RequiredArgsConstructor public class HairServiceOfferRegisterService { private final PreferOfferConditionJpaRepository preferOfferConditionJpaRepository; private final HairServiceOfferJpaRepository hairServiceOfferJpaRepository; + private final DesignerJpaRepository designerJpaRepository; + private final HairModelApplicationJpaRepository hairModelApplicationJpaRepository; + private final SmsUtil smsUtil; public void deleteModelHairServiceOfferInfos(final Long modelId) { final List hairServiceOffers = hairServiceOfferJpaRepository.findAllByModelId(modelId); @@ -34,9 +49,35 @@ public void deleteDesignerHairServiceOfferInfos(final Long designerId) { } @Transactional + public void postOffer(final Long designerId, final Long applicationId, final OfferCreateRequest request) throws IOException { + Designer designer = designerJpaRepository.findById(designerId).orElseThrow(() -> new NotFoundException(DESIGNER_NOT_FOUND_EXCEPTION)); + HairModelApplication hairModelApplication = hairModelApplicationJpaRepository.findById(applicationId).orElseThrow(() -> new NotFoundException(ErrorCode.NOT_FOUND_APPLICATION_EXCEPTION)); + Model model = hairModelApplication.getModel(); + if (hairServiceOfferJpaRepository.existsByHairModelApplicationIdAndDesignerId(applicationId,designer.getId())) throw new ConflictException(ErrorCode.ALREADY_EXIST_OFFER_EXCEPTION); + + HairServiceOffer offer = new HairServiceOffer(hairModelApplication,model,designer, request.offerDetail(), false,false); + hairServiceOfferJpaRepository.save(offer); + + request.preferOfferConditions().stream() + .forEach(p -> { + PreferOfferCondition preferOfferCondition = new PreferOfferCondition(offer,p); + preferOfferConditionJpaRepository.save(preferOfferCondition); + + }); + + final String modelName = model.getName(); + final String modelPhoneNumber = model.getPhoneNumber(); + sendSms(smsUtil, modelPhoneNumber,modelName); + } + public void updateOfferAgreeStatus(final Long offerId) { HairServiceOffer hairServiceOffer = hairServiceOfferJpaRepository.findById(offerId).orElseThrow(() -> new NotFoundException(ErrorCode.NOT_FOUND_OFFER_EXCEPTION)); hairServiceOffer.agreeOfferToModel(); } + + private void sendSms(final SmsUtil smsUtil, final String modelPhoneNumber, final String modelName) throws IOException { + smsUtil.sendOfferToModel(modelPhoneNumber, modelName); + } + } diff --git a/src/main/java/com/moddy/server/service/offer/HairServiceOfferRetrieveService.java b/src/main/java/com/moddy/server/service/offer/HairServiceOfferRetrieveService.java index 93fd2df8..dc1ddf94 100644 --- a/src/main/java/com/moddy/server/service/offer/HairServiceOfferRetrieveService.java +++ b/src/main/java/com/moddy/server/service/offer/HairServiceOfferRetrieveService.java @@ -86,7 +86,7 @@ private StyleDetailResponse getStyleDetailResponse(final HairServiceOffer hairSe StyleDetailResponse styleDetailResponse = StyleDetailResponse .builder() - .isAgree(hairServiceOffer.getIsModelAgree()) + .isAgree(hairServiceOffer.isModelAgree()) .preferStyle(preferHairStyleList) .designerOfferDetail(hairServiceOffer.getOfferDetail()) .modelApplicationDetail(applicationHairDetail) @@ -110,7 +110,7 @@ public ModelMainOfferResponse getModelMainOfferInfo(final Long modelId, final in } private void handleOfferClickStatus(final HairServiceOffer hairServiceOffer) { - if (!hairServiceOffer.getIsClicked()) { + if (!hairServiceOffer.isClicked()) { hairServiceOffer.updateClickStatus(); } } @@ -133,7 +133,7 @@ private List getModelMainOfferList(final Page o return offerCondition.getOfferCondition().getValue(); }).collect(Collectors.toList()); - OfferResponse offerResponse = new OfferResponse(offer.getId(), designer.getProfileImgUrl(), designer.getName(), designer.getHairShop().getName(), offerConditionTop2List, offer.getIsClicked()); + OfferResponse offerResponse = new OfferResponse(offer.getId(), designer.getProfileImgUrl(), designer.getName(), designer.getHairShop().getName(), offerConditionTop2List, offer.isClicked()); return offerResponse; }).collect(Collectors.toList());