diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/controller/PerfumeController.java b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/controller/PerfumeController.java index bf4c6b3..9535a9a 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/controller/PerfumeController.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/controller/PerfumeController.java @@ -2,7 +2,10 @@ import com.perfumepedia.perfumepedia.domain.perfume.dto.PerfumeUpdateReq; import com.perfumepedia.perfumepedia.domain.perfume.service.PerfumeService; +import com.perfumepedia.perfumepedia.domain.perfume.service.RequestPerfumeService; import com.perfumepedia.perfumepedia.domain.perfumeNote.dto.PerfumeDetailResponse; +import com.perfumepedia.perfumepedia.domain.perfumeNote.dto.RequestPerfumeDetailReq; +import com.perfumepedia.perfumepedia.global.enums.NoneResponse; import com.perfumepedia.perfumepedia.global.response.Response; import com.perfumepedia.perfumepedia.global.response.SuccessResponse; import io.swagger.v3.oas.annotations.tags.Tag; @@ -17,10 +20,12 @@ public class PerfumeController { private final PerfumeService perfumeService; + private final RequestPerfumeService requestPerfumeService; @Autowired - public PerfumeController(PerfumeService perfumeService) { + public PerfumeController(PerfumeService perfumeService, RequestPerfumeService requestPerfumeService) { this.perfumeService = perfumeService; + this.requestPerfumeService = requestPerfumeService; } /** @@ -48,5 +53,33 @@ public ResponseEntity> getPerfumeDetail(@PathVar return Response.success(response); } + /** + * 향수 등록 api + */ + @PostMapping("/perfumes/admins") + public ResponseEntity> registerPerfume(@RequestBody RequestPerfumeDetailReq requestPerfumeDetailReq) { + SuccessResponse response = requestPerfumeService.registerPerfume(requestPerfumeDetailReq); + return Response.success(response); + } + + /** + * 향수 수정 api + */ + @PutMapping("/perfumes/admins/{perfumeId}") + public ResponseEntity> updatePerfume(@RequestBody RequestPerfumeDetailReq requestPerfumeDetailReq, @PathVariable Long perfumeId) { + SuccessResponse response = requestPerfumeService.updatePerfume(requestPerfumeDetailReq, perfumeId); + return Response.success(response); + } + + /** + * 향수 삭제 api + */ + @DeleteMapping("/perfumes/admins/{perfumeId}") + public ResponseEntity> deletePerfume(@PathVariable Long perfumeId) { + SuccessResponse response = requestPerfumeService.deletePerfume(perfumeId); + return Response.success(response); + } + + } diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/entity/Perfume.java b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/entity/Perfume.java index 1d1294e..76bcaed 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/entity/Perfume.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/entity/Perfume.java @@ -32,4 +32,11 @@ public Perfume(Long id, String name, int price, Brand brand) { this.price = price; this.brand = brand; } + + // 수정 메서드 + public void update(String name, int price, Brand brand) { + this.name = name; + this.price = price; + this.brand = brand; + } } \ No newline at end of file diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/PerfumeService.java b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/PerfumeService.java index 9a01fab..57aa99b 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/PerfumeService.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/PerfumeService.java @@ -225,13 +225,16 @@ public SuccessResponse acceptUpdateRequest(Request request) { .build() )); - // 기존 향수의 정보를 요청된 정보로 업데이트 - perfume = Perfume.builder() - .id(perfume.getId()) - .name(reqPerfume.getName()) - .price(reqPerfume.getPrice()) - .brand(brand) - .build(); + // 기존 향수의 정보를 요청된 정보로 업데이트 - 영속성 문제? +// perfume = Perfume.builder() +// .id(perfume.getId()) +// .name(reqPerfume.getName()) +// .price(reqPerfume.getPrice()) +// .brand(brand) +// .build(); + + perfume.update(reqPerfume.getName(), reqPerfume.getPrice(), brand); + perfumeRepository.save(perfume); @@ -267,6 +270,7 @@ public SuccessResponse acceptUpdateRequest(Request request) { } + /** * 삭제 요청 처리 */ @@ -279,12 +283,15 @@ public SuccessResponse acceptDeleteRequest(Request request) { List perfumeNotes = perfumeNoteRepository.findByPerfume(perfume); perfumeNoteRepository.deleteAll(perfumeNotes); + // 새로운 Request 객체 생성 Perfume, requestPerfume을 null로 설정 + Request updatedRequest = new Request(request.getId(), request.getRequestType(), RequestStatus.APPROVED, + request.getUserId(), null, null); + + requestRepository.save(updatedRequest); + // 향수 삭제 perfumeRepository.delete(perfume); - request.updateRequestStatus(RequestStatus.APPROVED); - requestRepository.save(request); - return new SuccessResponse<>(DELETE_COMPLETED, NoneResponse.NONE); } diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/RequestPerfumeService.java b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/RequestPerfumeService.java index e672a0e..b3d5c7f 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/RequestPerfumeService.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/perfume/service/RequestPerfumeService.java @@ -1,16 +1,23 @@ package com.perfumepedia.perfumepedia.domain.perfume.service; +import com.perfumepedia.perfumepedia.domain.brand.entity.Brand; +import com.perfumepedia.perfumepedia.domain.note.entity.Note; + import com.perfumepedia.perfumepedia.domain.brand.entity.RequestBrand; +import com.perfumepedia.perfumepedia.domain.brand.repository.BrandRepository; import com.perfumepedia.perfumepedia.domain.brand.repository.RequestBrandRepository; import com.perfumepedia.perfumepedia.domain.note.entity.NoteType; import com.perfumepedia.perfumepedia.domain.note.entity.RequestNote; +import com.perfumepedia.perfumepedia.domain.note.repository.NoteRepository; import com.perfumepedia.perfumepedia.domain.note.repository.RequestNoteRepository; import com.perfumepedia.perfumepedia.domain.perfume.entity.Perfume; import com.perfumepedia.perfumepedia.domain.perfume.entity.RequestPerfume; import com.perfumepedia.perfumepedia.domain.perfume.repository.PerfumeRepository; import com.perfumepedia.perfumepedia.domain.perfume.repository.RequestPerfumeRepository; import com.perfumepedia.perfumepedia.domain.perfumeNote.dto.RequestPerfumeDetailReq; +import com.perfumepedia.perfumepedia.domain.perfumeNote.entity.PerfumeNote; import com.perfumepedia.perfumepedia.domain.perfumeNote.entity.RequestPerfumeNote; +import com.perfumepedia.perfumepedia.domain.perfumeNote.repository.PerfumeNoteRepository; import com.perfumepedia.perfumepedia.domain.perfumeNote.repository.RequestPerfumeNoteRepository; import com.perfumepedia.perfumepedia.domain.request.entity.Request; import com.perfumepedia.perfumepedia.domain.request.entity.RequestStatus; @@ -24,8 +31,10 @@ import org.springframework.transaction.annotation.Transactional; +import java.util.List; + import static com.perfumepedia.perfumepedia.global.enums.ErrorCode.PERFUME_NOT_FOUND; -import static com.perfumepedia.perfumepedia.global.enums.SuccessCode.REQUEST_COMPLETED; +import static com.perfumepedia.perfumepedia.global.enums.SuccessCode.*; @Service public class RequestPerfumeService { @@ -36,17 +45,24 @@ public class RequestPerfumeService { private final RequestPerfumeNoteRepository reqPerfumeNoteRepository; private final RequestRepository requestRepository; private final PerfumeRepository perfumeRepository; + private final BrandRepository brandRepository; + private final NoteRepository noteRepository; + private final PerfumeNoteRepository perfumeNoteRepository; @Autowired public RequestPerfumeService(RequestPerfumeRepository requestPerfumeRepository, RequestBrandRepository requestBrandRepository, RequestNoteRepository requestNoteRepository, RequestPerfumeNoteRepository reqPerfumeNoteRepository, - RequestRepository requestRepository, PerfumeRepository perfumeRepository) { + RequestRepository requestRepository, PerfumeRepository perfumeRepository, BrandRepository brandRepository, + NoteRepository noteRepository, PerfumeNoteRepository perfumeNoteRepository) { this.requestPerfumeRepository = requestPerfumeRepository; this.requestBrandRepository = requestBrandRepository; this.requestNoteRepository = requestNoteRepository; this.reqPerfumeNoteRepository = reqPerfumeNoteRepository; this.requestRepository = requestRepository; this.perfumeRepository = perfumeRepository; + this.brandRepository = brandRepository; + this.noteRepository = noteRepository; + this.perfumeNoteRepository = perfumeNoteRepository; } @@ -57,21 +73,23 @@ public RequestPerfumeService(RequestPerfumeRepository requestPerfumeRepository, * @param userId 요청한 유저의 ID * @return perfumeDetailReq */ + public SuccessResponse registerPerfumeRequest(RequestPerfumeDetailReq reqPerfumeDetailReq, Long userId) { // 요청 브랜드에 저장 - RequestBrand reqBrand = saveReqBrand(reqPerfumeDetailReq.getBrand()); + RequestBrand reqBrand = saveReqBrand(reqPerfumeDetailReq.getBrandName()); // 요청 향수에 저장 RequestPerfume reqPerfume = saveReqPerfume(reqPerfumeDetailReq.getName(), reqPerfumeDetailReq.getPrice(), reqBrand); // 요청 노트 & 요청 퍼퓸 노트 저장 - saveNotes(reqPerfumeDetailReq, reqPerfume); + saveReqNotes(reqPerfumeDetailReq, reqPerfume); // 요청 저장 Request request = Request.builder() .requestType(RequestType.CREATE) // 등록 요청 .requestStatus(RequestStatus.PENDING) // 대기중 .userId(userId) + .perfume(null) // 등록 요청 상태인 향수 정보 .requestPerfume(reqPerfume) // 등록 요청 상태인 향수 정보 .build(); @@ -94,13 +112,13 @@ public SuccessResponse updatePerfumeRequest(RequestPerfumeDetailRe .orElseThrow(() -> new AppException(PERFUME_NOT_FOUND)); // 요청 브랜드에 저장 - RequestBrand reqBrand = saveReqBrand(reqPerfumeDetailReq.getBrand()); + RequestBrand reqBrand = saveReqBrand(reqPerfumeDetailReq.getBrandName()); // 요청 향수에 저장 RequestPerfume reqPerfume = saveReqPerfume(reqPerfumeDetailReq.getName(), reqPerfumeDetailReq.getPrice(), reqBrand); // 요청 노트 & 요청 퍼퓸 노트 저장 - saveNotes(reqPerfumeDetailReq, reqPerfume); + saveReqNotes(reqPerfumeDetailReq, reqPerfume); Request request = Request.builder() @@ -111,6 +129,8 @@ public SuccessResponse updatePerfumeRequest(RequestPerfumeDetailRe .perfume(originPerfume) // 기존 향수 .build(); + requestRepository.save(request); + return new SuccessResponse<>(REQUEST_COMPLETED, NoneResponse.NONE); @@ -130,9 +150,11 @@ public SuccessResponse deletePerfumeRequest(Long perfumeId, Long u .requestType(RequestType.DELETE) // 삭제 요청 .requestStatus(RequestStatus.PENDING) // 대기중 .userId(userId) - .perfume(perfume) // 기존 향수 + .perfume(perfume) // 기존 향수 + .requestPerfume(null) // 삭제 요청 된 향수 .build(); + requestRepository.save(request); return new SuccessResponse<>(REQUEST_COMPLETED, NoneResponse.NONE); } @@ -145,7 +167,7 @@ public SuccessResponse deletePerfumeRequest(Long perfumeId, Long u * @param requestNote 요청 노트 정보 * @param type 노트 타입 */ - private void savePerfumeNote(RequestPerfume perfume, RequestNote requestNote, NoteType type) { + private void saveReqPerfumeNote(RequestPerfume perfume, RequestNote requestNote, NoteType type) { RequestPerfumeNote perfumeNote = RequestPerfumeNote.builder() .requestPerfume(perfume) .requestNote(requestNote) @@ -161,7 +183,7 @@ private void savePerfumeNote(RequestPerfume perfume, RequestNote requestNote, No * @param dto 요청된 모든 정보 * @param Perfume 요청 향수 정보 */ - private void saveNotes(RequestPerfumeDetailReq dto, RequestPerfume Perfume) { + private void saveReqNotes(RequestPerfumeDetailReq dto, RequestPerfume Perfume) { saveNotesAndReqPerfumeNote(dto.getTopNote(), Perfume, NoteType.TOP); saveNotesAndReqPerfumeNote(dto.getMiddleNote(), Perfume, NoteType.MIDDLE); saveNotesAndReqPerfumeNote(dto.getBaseNote(), Perfume, NoteType.BASE); @@ -192,14 +214,14 @@ private void saveNotesAndReqPerfumeNote(String notes, RequestPerfume reqPerfume, .build()) ); // RequestPerfumeNote 저장 - savePerfumeNote(reqPerfume, reqNote, type); + saveReqPerfumeNote(reqPerfume, reqNote, type); } } } } // 요청 브렌드를 저장 후 반환 - @Transactional + public RequestBrand saveReqBrand(String brandName) { RequestBrand newBrand = RequestBrand.builder() @@ -211,7 +233,7 @@ public RequestBrand saveReqBrand(String brandName) { } // 요청 향수를 저장 후 반환 - @Transactional + public RequestPerfume saveReqPerfume(String name, int price, RequestBrand requestBrand) { RequestPerfume perfume = RequestPerfume.builder() @@ -224,4 +246,144 @@ public RequestPerfume saveReqPerfume(String name, int price, RequestBrand reques } + + + + + + + + + + + /** + * 향수 등록 + */ + @Transactional + public SuccessResponse registerPerfume(RequestPerfumeDetailReq reqPerfumeDetailReq) { + // 브랜드에 저장 + Brand Brand = saveBrand(reqPerfumeDetailReq.getBrandName()); + + // 향수에 저장 + Perfume perfume = savePerfume(reqPerfumeDetailReq.getName(), reqPerfumeDetailReq.getPrice(), Brand); + + // 노트 & 퍼퓸 노트 저장 + saveNotes(reqPerfumeDetailReq, perfume); + + return new SuccessResponse<>(REGISTER_COMPLETED, NoneResponse.NONE); + } + + + // 브랜드 저장 + public Brand saveBrand(String brandName) { + + Brand newBrand = Brand.builder() + .name(brandName) + .url(null) // 임시 처리 + .build(); + + return brandRepository.save(newBrand); + } + + // 향수 저장 + + public Perfume savePerfume(String name, int price, Brand brand) { + + Perfume perfume = Perfume.builder() + .name(name) + .price(price) + .brand(brand) + .build(); + + return perfumeRepository.save(perfume); + } + + // 노트를 분리후 저장 + private void saveNotesAndPerfumeNote(String notes, Perfume Perfume, NoteType type) { + + if (notes != null && !notes.isEmpty()) { + String[] noteList = notes.split(","); // ,기준으로 노트를 분리 + for (String rawNote : noteList) { + String note = rawNote.trim(); // 분리된 노트 앞뒤 공백 제거 + if (!note.isEmpty()) { + // Note 저장 + Note noteEntity = noteRepository.findByName(note) + .orElseGet(() -> noteRepository.save( + Note.builder() + .name(note) + .build()) + ); + + // PerfumeNote 저장 + savePerfumeNote(Perfume, noteEntity, type); + } + } + } + } + + // PerfumeNote 저장 + private void savePerfumeNote(Perfume perfume, Note note, NoteType type) { + PerfumeNote perfumeNote = PerfumeNote.builder() + .perfume(perfume) + .note(note) + .noteType(type) + .build(); + // PerfumeNote 저장 + perfumeNoteRepository.save(perfumeNote); + } + + // 타입별로 노트 저장 + private void saveNotes(RequestPerfumeDetailReq dto, Perfume Perfume) { + saveNotesAndPerfumeNote(dto.getTopNote(), Perfume, NoteType.TOP); + saveNotesAndPerfumeNote(dto.getMiddleNote(), Perfume, NoteType.MIDDLE); + saveNotesAndPerfumeNote(dto.getBaseNote(), Perfume, NoteType.BASE); + saveNotesAndPerfumeNote(dto.getSingleNote(), Perfume, NoteType.SINGLE); + } + + + /** + * 향수 수정 api + * */ + @Transactional + public SuccessResponse updatePerfume(RequestPerfumeDetailReq reqPerfumeDetailReq, Long perfumeId) { + // 수정할 향수 조회 + Perfume perfume = perfumeRepository.findById(perfumeId) + .orElseThrow(() -> new AppException(PERFUME_NOT_FOUND)); + + // 기존 브랜드 조회 또는 생성 + Brand brand = brandRepository.findByName(reqPerfumeDetailReq.getBrandName()) + .orElseGet(() -> brandRepository.save( + Brand.builder() + .name(reqPerfumeDetailReq.getBrandName()) + .build() + )); + + perfume.update(reqPerfumeDetailReq.getName(), reqPerfumeDetailReq.getPrice(), brand); + + perfumeRepository.save(perfume); + + perfumeNoteRepository.deleteByPerfume(perfume); + + saveNotes(reqPerfumeDetailReq, perfume); + + return new SuccessResponse<>(UPDATE_COMPLETED, NoneResponse.NONE); + } + + + /** + * 향수 삭제 api + * */ + @Transactional + public SuccessResponse deletePerfume(Long perfumeId) { + Perfume perfume = perfumeRepository.findById(perfumeId) + .orElseThrow(() -> new AppException(PERFUME_NOT_FOUND)); + + List perfumeNotes = perfumeNoteRepository.findByPerfume(perfume); + + perfumeNoteRepository.deleteAll(perfumeNotes); + perfumeRepository.delete(perfume); + + return new SuccessResponse<>(DELETE_COMPLETED, NoneResponse.NONE); + + } } diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/dto/RequestPerfumeDetailReq.java b/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/dto/RequestPerfumeDetailReq.java index daf518e..562e30d 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/dto/RequestPerfumeDetailReq.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/dto/RequestPerfumeDetailReq.java @@ -9,7 +9,7 @@ public class RequestPerfumeDetailReq { private String name; // 향수 이름 - private String brand; // 브랜드 이름 + private String brandName; // 브랜드 이름 private String topNote; // 탑 노트 private String middleNote; // 미들 노트 private String baseNote; // 베이스 노트 @@ -19,7 +19,7 @@ public class RequestPerfumeDetailReq { @Builder public RequestPerfumeDetailReq(String name, String brand, String topNote, String middleNote, String baseNote, String singleNote, int price) { this.name = name; - this.brand = brand; + this.brandName = brand; this.topNote = topNote; this.middleNote = middleNote; this.baseNote = baseNote; diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/entity/PerfumeNote.java b/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/entity/PerfumeNote.java index 3141a32..c743e7d 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/entity/PerfumeNote.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/perfumeNote/entity/PerfumeNote.java @@ -20,7 +20,7 @@ public class PerfumeNote extends BaseEntity { @Column(name = "PERFUME_NOTE_ID") private Long id; - @ManyToOne + @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "PERFUME_ID") private Perfume perfume; diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/request/controller/RequestController.java b/src/main/java/com/perfumepedia/perfumepedia/domain/request/controller/RequestController.java index f2cc48d..fd2a79b 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/request/controller/RequestController.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/request/controller/RequestController.java @@ -156,4 +156,5 @@ public ResponseEntity> rejectPerfumeRequest(@PathVariable return Response.success(response); } + } diff --git a/src/main/java/com/perfumepedia/perfumepedia/domain/request/entity/Request.java b/src/main/java/com/perfumepedia/perfumepedia/domain/request/entity/Request.java index e678c3b..efd4701 100644 --- a/src/main/java/com/perfumepedia/perfumepedia/domain/request/entity/Request.java +++ b/src/main/java/com/perfumepedia/perfumepedia/domain/request/entity/Request.java @@ -30,13 +30,13 @@ public class Request extends BaseEntity { private Long userId; // 유저 객체로 변경 가능성 있음 // 요청한 향수에 대한 정보 - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "REQUEST_PERFUME_NOTE_ID") + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "REQUEST_PERFUME_NOTE_ID", nullable = true) private RequestPerfume requestPerfume; // 수정, 삭제 요청시 이전 향수에 대한 정보 @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "PERFUME_NOTE_ID") + @JoinColumn(name = "PERFUME_NOTE_ID", nullable = true) private Perfume perfume; @Builder