Skip to content

Commit

Permalink
feat: #71 일렉 기타 매물 정보 수정 API 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
Wo-ogie committed Mar 26, 2024
1 parent 5912572 commit 6ff7759
Show file tree
Hide file tree
Showing 21 changed files with 1,014 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public enum CustomExceptionType {
* 악기 관련 예외
*/
INSTRUMENT_NOT_FOUND_BY_ID(2600, "일치하는 매물 정보를 찾을 수 없습니다."),
INSTRUMENT_DELETE_PERMISSION_DENIED(2601, "악기 매물을 삭제할 권한이 없습니다. 매물은 판매자 본인만 삭제할 수 있습니다.");
INSTRUMENT_DELETE_PERMISSION_DENIED(2601, "악기 매물을 삭제할 권한이 없습니다. 매물은 판매자 본인만 삭제할 수 있습니다."),
INSTRUMENT_UPDATE_PERMISSION_DENIED(2602, "악기 매물 정보를 수정할 권한이 없습니다. 매물 정보는 판매자 본인만 수정할 수 있습니다");

private final Integer code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,43 @@
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.ajou.hertz.common.auth.UserPrincipal;
import com.ajou.hertz.domain.instrument.constant.InstrumentSortOption;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.AcousticAndClassicGuitarDto;
import com.ajou.hertz.domain.instrument.amplifier.dto.AmplifierDto;
import com.ajou.hertz.domain.instrument.audio_equipment.dto.AudioEquipmentDto;
import com.ajou.hertz.domain.instrument.bass_guitar.dto.BassGuitarDto;
import com.ajou.hertz.domain.instrument.effector.dto.EffectorDto;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.ElectricGuitarDto;
import com.ajou.hertz.domain.instrument.dto.InstrumentDto;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.amplifier.dto.request.AmplifierFilterConditions;
import com.ajou.hertz.domain.instrument.audio_equipment.dto.request.AudioEquipmentFilterConditions;
import com.ajou.hertz.domain.instrument.bass_guitar.dto.request.BassGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.CreateNewAcousticAndClassicGuitarRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.response.AcousticAndClassicGuitarResponse;
import com.ajou.hertz.domain.instrument.amplifier.dto.AmplifierDto;
import com.ajou.hertz.domain.instrument.amplifier.dto.request.AmplifierFilterConditions;
import com.ajou.hertz.domain.instrument.amplifier.dto.request.CreateNewAmplifierRequest;
import com.ajou.hertz.domain.instrument.amplifier.dto.response.AmplifierResponse;
import com.ajou.hertz.domain.instrument.audio_equipment.dto.AudioEquipmentDto;
import com.ajou.hertz.domain.instrument.audio_equipment.dto.request.AudioEquipmentFilterConditions;
import com.ajou.hertz.domain.instrument.audio_equipment.dto.request.CreateNewAudioEquipmentRequest;
import com.ajou.hertz.domain.instrument.audio_equipment.dto.response.AudioEquipmentResponse;
import com.ajou.hertz.domain.instrument.bass_guitar.dto.BassGuitarDto;
import com.ajou.hertz.domain.instrument.bass_guitar.dto.request.BassGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.bass_guitar.dto.request.CreateNewBassGuitarRequest;
import com.ajou.hertz.domain.instrument.bass_guitar.dto.response.BassGuitarResponse;
import com.ajou.hertz.domain.instrument.constant.InstrumentSortOption;
import com.ajou.hertz.domain.instrument.dto.InstrumentDto;
import com.ajou.hertz.domain.instrument.dto.response.InstrumentResponse;
import com.ajou.hertz.domain.instrument.dto.response.InstrumentSummaryResponse;
import com.ajou.hertz.domain.instrument.effector.dto.EffectorDto;
import com.ajou.hertz.domain.instrument.effector.dto.request.CreateNewEffectorRequest;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.request.CreateNewElectricGuitarRequest;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorFilterConditions;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.request.ElectricGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.response.AcousticAndClassicGuitarResponse;
import com.ajou.hertz.domain.instrument.amplifier.dto.response.AmplifierResponse;
import com.ajou.hertz.domain.instrument.audio_equipment.dto.response.AudioEquipmentResponse;
import com.ajou.hertz.domain.instrument.bass_guitar.dto.response.BassGuitarResponse;
import com.ajou.hertz.domain.instrument.effector.dto.response.EffectorResponse;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.ElectricGuitarDto;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.request.CreateNewElectricGuitarRequest;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.request.ElectricGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.request.ElectricGuitarUpdateRequest;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.response.ElectricGuitarResponse;
import com.ajou.hertz.domain.instrument.dto.response.InstrumentResponse;
import com.ajou.hertz.domain.instrument.dto.response.InstrumentSummaryResponse;
import com.ajou.hertz.domain.instrument.mapper.InstrumentMapper;
import com.ajou.hertz.domain.instrument.service.InstrumentCommandService;
import com.ajou.hertz.domain.instrument.service.InstrumentQueryService;
Expand Down Expand Up @@ -416,6 +418,29 @@ public ResponseEntity<AudioEquipmentResponse> createNewAudioEquipmentV1(
.body(InstrumentMapper.toAudioEquipmentResponse(audioEquipment));
}

@Operation(
summary = "일렉 기타 매물 수정",
description = """
<p>일렉 기타 매물 정보를 수정합니다.
<p>요청 시 <strong>multipart/form-data</strong> content-type으로 요쳥해야 합니다.
<p>변경하고자 하는 매물 정보만 request body에 담아 요청하면 됩니다. 요청 시 보내지 않은 필드는 수정하지 않습니다.
""",
security = @SecurityRequirement(name = "access-token")
)
@PatchMapping("/electric-guitars/{electricGuitarId}")
public ElectricGuitarResponse updateElectricGuitarV1(
@AuthenticationPrincipal UserPrincipal userPrincipal,
@Parameter(description = "수정하고자 하는 악기 매물의 id", example = "2") @PathVariable Long electricGuitarId,
@ParameterObject @ModelAttribute @Valid ElectricGuitarUpdateRequest updateRequest
) {
ElectricGuitarDto electricGuitarDto = instrumentCommandService.updateElectricGuitar(
userPrincipal.getUserId(),
electricGuitarId,
updateRequest
);
return InstrumentMapper.toElectricGuitarResponse(electricGuitarDto);
}

@Operation(
summary = "악기 매물 삭제",
description = "악기 매물을 삭제합니다. 매물 삭제는 판매자만 할 수 있습니다.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.ajou.hertz.domain.instrument.dto.request;

import java.util.List;

import org.hibernate.validator.constraints.Length;
import org.springframework.lang.Nullable;
import org.springframework.web.multipart.MultipartFile;

import com.ajou.hertz.common.dto.request.AddressRequest;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Setter
@Getter
public abstract class InstrumentUpdateRequest {

@Schema(description = "제목", example = "펜더 로드원 텔레캐스터")
@Nullable
private String title;

@Nullable
private InstrumentProgressStatus progressStatus;

@Schema(description = "거래 장소")
@Nullable
private AddressRequest tradeAddress;

@Schema(description = "악기 상태. 1~5 단계로 구성됩니다.", example = "3")
@Min(1)
@Max(5)
@Nullable
private Short qualityStatus;

@Schema(description = "가격", example = "527000")
@Nullable
private Integer price;

@Schema(description = "특이사항 유무", example = "true")
@Nullable
private Boolean hasAnomaly;

@Schema(description = "특이사항 및 상세 설명. 내용이 없을 경우에는 빈 문자열로 요청하면 됩니다.", example = "14년 시리얼 펜더 로드원 50 텔레입니다. 기존 ...")
@Nullable
private String description;

@Schema(description = "삭제한 이미지의 id 리스트")
@Nullable
private List<Long> deletedImageIds;

@Schema(description = "새로 추가된 악기 이미지 리스트")
@Nullable
private List<MultipartFile> newImages;

@Schema(description = "삭제한 해시태그의 id 리스트")
@Nullable
private List<Long> deletedHashtagIds;

@Schema(description = "새로 추가된 악기 해시태그(각 해시태그마다 최대 10글자) 리스트", example = "[\"펜더\", \"Fender\"]")
@Nullable
private List<@NotBlank @Length(max = 10) String> newHashtags;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class CreateNewElectricGuitarRequest extends CreateNewInstrumentRequest<E
@NotNull
private ElectricGuitarModel model;

@Schema(description = "생상연도", example = "2014")
@Schema(description = "생산연도", example = "2014")
@NotNull
private Short productionYear;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.ajou.hertz.domain.instrument.electric_guitar.dto.request;

import java.util.List;

import org.springframework.lang.Nullable;
import org.springframework.web.multipart.MultipartFile;

import com.ajou.hertz.common.dto.request.AddressRequest;
import com.ajou.hertz.domain.instrument.constant.GuitarColor;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarBrand;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarModel;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Setter
@Getter
public class ElectricGuitarUpdateRequest extends InstrumentUpdateRequest {

@Nullable
private ElectricGuitarBrand brand;

@Nullable
private ElectricGuitarModel model;

@Schema(description = "생산 연도", example = "2014")
@Nullable
private Short productionYear;

@Nullable
private GuitarColor color;

private ElectricGuitarUpdateRequest(
@Nullable String title,
@Nullable InstrumentProgressStatus progressStatus,
@Nullable AddressRequest tradeAddress,
@Nullable Short qualityStatus,
@Nullable Integer price,
@Nullable Boolean hasAnomaly,
@Nullable String description,
@Nullable List<Long> deletedImageIds,
@Nullable List<MultipartFile> newImages,
@Nullable List<Long> deletedHashtagIds,
@Nullable List<String> newHashtags,
@Nullable ElectricGuitarBrand brand,
@Nullable ElectricGuitarModel model,
@Nullable Short productionYear,
@Nullable GuitarColor color
) {
super(title, progressStatus, tradeAddress, qualityStatus, price, hasAnomaly, description,
deletedImageIds, newImages, deletedHashtagIds, newHashtags);
this.brand = brand;
this.model = model;
this.productionYear = productionYear;
this.color = color;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import com.ajou.hertz.common.entity.Address;
import com.ajou.hertz.domain.instrument.constant.GuitarColor;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarBrand;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarModel;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.request.ElectricGuitarUpdateRequest;
import com.ajou.hertz.domain.instrument.entity.Instrument;
import com.ajou.hertz.domain.user.entity.User;

Expand Down Expand Up @@ -79,4 +81,13 @@ public static ElectricGuitar create(
price, hasAnomaly, description, brand, model, productionYear, color
);
}

public void update(InstrumentUpdateRequest updateRequest) {
ElectricGuitarUpdateRequest electricGuitarUpdateRequest = (ElectricGuitarUpdateRequest)updateRequest;
super.update(updateRequest);
this.brand = electricGuitarUpdateRequest.getBrand();
this.model = electricGuitarUpdateRequest.getModel();
this.productionYear = electricGuitarUpdateRequest.getProductionYear();
this.color = electricGuitarUpdateRequest.getColor();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.ajou.hertz.domain.instrument.entity;

import org.springframework.util.StringUtils;

import com.ajou.hertz.common.entity.Address;
import com.ajou.hertz.common.entity.TimeTrackedBaseEntity;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;
import com.ajou.hertz.domain.user.entity.User;

import jakarta.persistence.Column;
Expand Down Expand Up @@ -88,4 +91,25 @@ protected Instrument(
this.hasAnomaly = hasAnomaly;
this.description = description;
}

public void update(InstrumentUpdateRequest updateRequest) {
if (StringUtils.hasText(updateRequest.getTitle())) {
this.title = updateRequest.getTitle();
}
if (updateRequest.getTradeAddress() != null) {
this.tradeAddress = updateRequest.getTradeAddress().toEntity();
}
if (updateRequest.getQualityStatus() != null) {
this.qualityStatus = updateRequest.getQualityStatus();
}
if (updateRequest.getPrice() != null) {
this.price = updateRequest.getPrice();
}
if (updateRequest.getHasAnomaly() != null) {
this.hasAnomaly = updateRequest.getHasAnomaly();
}
if (updateRequest.getDescription() != null) {
this.description = updateRequest.getDescription();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ajou.hertz.domain.instrument.entity;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

Expand All @@ -21,6 +22,10 @@ public void addAll(List<InstrumentHashtag> hashtags) {
content.addAll(hashtags);
}

public void deleteAllByIds(Collection<Long> ids) {
content.removeIf(hashtag -> ids.contains(hashtag.getId()));
}

public List<String> toStrings() {
return content.stream()
.map(InstrumentHashtag::getContent)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ajou.hertz.domain.instrument.entity;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

Expand All @@ -23,6 +24,10 @@ public void addAll(List<InstrumentImage> images) {
content.addAll(images);
}

public void deleteAllByIds(Collection<Long> ids) {
content.removeIf(image -> ids.contains(image.getId()));
}

public List<InstrumentImageDto> toDtos() {
return content.stream()
.map(InstrumentImageDto::from)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.ajou.hertz.domain.instrument.exception;

import com.ajou.hertz.common.exception.ForbiddenException;
import com.ajou.hertz.common.exception.constant.CustomExceptionType;

public class InstrumentUpdatePermissionDeniedException extends ForbiddenException {
public InstrumentUpdatePermissionDeniedException(Long userId, Long instrumentId) {
super(
CustomExceptionType.INSTRUMENT_UPDATE_PERMISSION_DENIED,
String.format("userId=%s instrumentId=%s", userId, instrumentId)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ajou.hertz.domain.instrument.repository;

import java.util.Collection;
import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -9,4 +10,6 @@
public interface InstrumentImageRepository extends JpaRepository<InstrumentImage, Long> {

List<InstrumentImage> findAllByInstrument_Id(Long instrumentId);

List<InstrumentImage> findAllByIdIn(Collection<Long> ids);
}
Loading

0 comments on commit 6ff7759

Please sign in to comment.