Skip to content

Commit 668544a

Browse files
authored
Merge pull request #457 from Juinjang/fix/#456
🐛 [fix/#456] note update 빈 값 처리
2 parents d500380 + 5b8a593 commit 668544a

6 files changed

Lines changed: 136 additions & 9 deletions

File tree

src/main/java/umc/th/juinjang/api/limjang/controller/NoteControllerV2.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import umc.th.juinjang.api.limjang.controller.parameter.LimjangSortOptions;
1818
import umc.th.juinjang.api.limjang.controller.request.NoteInitRequest;
1919
import umc.th.juinjang.api.limjang.controller.request.NotePatchRequest;
20+
import umc.th.juinjang.api.limjang.controller.request.NotePatchRequestV2;
2021
import umc.th.juinjang.api.limjang.controller.request.NotePostRequest;
2122
import umc.th.juinjang.api.limjang.service.NoteCommandServiceV2;
2223
import umc.th.juinjang.api.limjang.service.NoteQueryServiceV2;
@@ -71,9 +72,9 @@ public ApiResponse<Void> updateNote(@PathVariable(name = "noteId") Long noteId,
7172
@Operation(summary = "임장 수정 API V2 - UI/UX 리팩토링")
7273
@PatchMapping("/notes/init/{noteId}")
7374
public ApiResponse<Void> updateNoteV2(@PathVariable(name = "noteId") Long noteId,
74-
@RequestBody @Valid NotePatchRequest request,
75+
@RequestBody @Valid NotePatchRequestV2 request,
7576
@AuthenticationPrincipal Member member) {
76-
noteCommandService.updateNoteV2(noteId, request);
77+
noteCommandService.updateNoteInitV2(noteId, request);
7778
return ApiResponse.onSuccess(null);
7879
}
7980

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package umc.th.juinjang.api.limjang.controller.request;
2+
3+
import jakarta.validation.constraints.NotNull;
4+
import jakarta.validation.constraints.Pattern;
5+
import umc.th.juinjang.domain.limjang.model.Address;
6+
import umc.th.juinjang.domain.limjang.model.LimjangPrice;
7+
import umc.th.juinjang.domain.limjang.model.LimjangPriceType;
8+
import umc.th.juinjang.domain.limjang.model.LimjangPurpose;
9+
import umc.th.juinjang.domain.limjang.repository.NotePriceFactory;
10+
11+
public record NotePatchRequestV2(
12+
@NotNull
13+
LimjangPriceType priceType,
14+
15+
@Pattern(regexp = "^[0-9]+$", message = "가격은 숫자만 입력해야 합니다.")
16+
String price,
17+
@Pattern(regexp = "^[0-9]+$", message = "가격은 숫자만 입력해야 합니다.")
18+
String monthlyRent,
19+
20+
String roadAddress,
21+
String addressDetail,
22+
23+
String bcode,
24+
25+
String nickname,
26+
27+
String floor,
28+
Integer pyong, //null 처리를 위해 Integer로 변경
29+
String sido,
30+
String sigungu,
31+
String bname1,
32+
String bname2
33+
) {
34+
35+
public LimjangPrice toUpdatedPrice(LimjangPurpose purpose) {
36+
if (price == null && monthlyRent == null) {
37+
return LimjangPrice.empty();
38+
}
39+
return NotePriceFactory.create(purpose, priceType, price, monthlyRent);
40+
}
41+
42+
public Address toUpdatedAddress() {
43+
// 둘 다 없음 -> 삭제(주소 null 처리 유도)
44+
if (isDeleteAddressIntent()) {
45+
return Address.empty();
46+
}
47+
48+
// 상세주소만 -> 정책상 금지
49+
if (isDetailOnly()) {
50+
throw new IllegalArgumentException("본주소 없이 상세주소만 입력할 수 없습니다.");
51+
}
52+
53+
// 본주소가 있으면 생성
54+
return Address.create(roadAddress, addressDetail, bcode, sido, sigungu, bname1, bname2);
55+
}
56+
57+
private boolean isBlank(String s) {
58+
return s == null || s.isBlank();
59+
}
60+
61+
private boolean isDeleteAddressIntent() { // 4번
62+
return isBlank(roadAddress) && isBlank(addressDetail);
63+
}
64+
65+
private boolean isDetailOnly() { // 3번
66+
return isBlank(roadAddress) && !isBlank(addressDetail);
67+
}
68+
}

src/main/java/umc/th/juinjang/api/limjang/service/NoteCommandServiceV2.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import umc.th.juinjang.api.address.service.AddressUpdater;
99
import umc.th.juinjang.api.limjang.controller.request.NoteInitRequest;
1010
import umc.th.juinjang.api.limjang.controller.request.NotePatchRequest;
11+
import umc.th.juinjang.api.limjang.controller.request.NotePatchRequestV2;
1112
import umc.th.juinjang.api.limjang.controller.request.NotePostRequest;
1213
import umc.th.juinjang.api.limjang.service.response.NotePostResponse;
1314
import umc.th.juinjang.common.code.status.ErrorStatus;
@@ -74,6 +75,37 @@ public void updateNoteV2(Long noteId, NotePatchRequest request) {
7475
note.updateNote(request.nickname(), request.priceType(), request.floor(), request.pyong());
7576
}
7677

78+
@Transactional
79+
public void updateNoteInitV2(Long noteId, NotePatchRequestV2 request) {
80+
try {
81+
Limjang note = noteFinder.getNoteByIdWhereDeletedIsFalse(noteId);
82+
83+
validatePriceType(note.getPurpose(), request.priceType());
84+
85+
LimjangPrice newPrice = request.toUpdatedPrice(note.getPurpose());
86+
Address newAddress = request.toUpdatedAddress();
87+
88+
Address currentAddress = note.getAddressEntity();
89+
if (newAddress.isEmpty()) {
90+
if (currentAddress != null) {
91+
note.setAddressEntity(null);
92+
}
93+
} else {
94+
if (currentAddress != null) {
95+
currentAddress.update(newAddress);
96+
} else {
97+
addressUpdater.save(newAddress);
98+
note.setAddressEntity(newAddress);
99+
}
100+
}
101+
102+
note.getLimjangPrice().updateLimjangPrice(newPrice);
103+
note.updateNote(request.nickname(), request.priceType(), request.floor(), request.pyong());
104+
} catch (Exception e) {
105+
e.printStackTrace();
106+
}
107+
}
108+
77109
private void validatePriceType(LimjangPurpose purposeType, LimjangPriceType priceType) {
78110
if (
79111
(purposeType == LimjangPurpose.RESIDENTIAL_PURPOSE && priceType == LimjangPriceType.MARKET_PRICE) ||

src/main/java/umc/th/juinjang/domain/limjang/model/Address.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package umc.th.juinjang.domain.limjang.model;
22

3-
import java.util.Objects;
43
import java.util.stream.Collectors;
54
import java.util.stream.Stream;
65

@@ -87,4 +86,22 @@ public void update(Address newAddress) {
8786
public String getFullAddress() {
8887
return this.roadAddress + " " + this.getAddressDetail();
8988
}
89+
90+
public static Address empty() {
91+
return Address.builder().build(); // 모든 필드 null
92+
}
93+
94+
public boolean isEmpty() {
95+
return isBlank(roadAddress)
96+
&& isBlank(addressDetail)
97+
&& isBlank(bcode)
98+
&& isBlank(sido)
99+
&& isBlank(sigungo)
100+
&& isBlank(bname1)
101+
&& isBlank(bname2);
102+
}
103+
104+
private boolean isBlank(String s) {
105+
return s == null || s.isBlank();
106+
}
90107
}

src/main/java/umc/th/juinjang/domain/limjang/model/Limjang.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,10 @@ public static Limjang initNote(Member member, LimjangPrice price, LimjangPurpose
199199
.build();
200200
}
201201

202-
public void updateNote(String nickname, LimjangPriceType limjangPriceType, String floor, int pyong) {
203-
this.nickname = nickname;
202+
public void updateNote(String nickname, LimjangPriceType limjangPriceType, String floor, Integer pyong) {
203+
if (nickname != null) {
204+
this.nickname = nickname;
205+
}
204206
this.priceType = limjangPriceType;
205207
this.floor = floor;
206208
this.pyong = pyong;

src/main/java/umc/th/juinjang/domain/limjang/model/LimjangPrice.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package umc.th.juinjang.domain.limjang.model;
22

3-
import java.util.ArrayList;
4-
import java.util.List;
5-
6-
import jakarta.persistence.*;
3+
import jakarta.persistence.CascadeType;
4+
import jakarta.persistence.Column;
5+
import jakarta.persistence.Entity;
6+
import jakarta.persistence.GeneratedValue;
7+
import jakarta.persistence.GenerationType;
8+
import jakarta.persistence.Id;
9+
import jakarta.persistence.OneToOne;
710
import lombok.AccessLevel;
811
import lombok.AllArgsConstructor;
912
import lombok.Builder;
@@ -57,4 +60,8 @@ public String getPrice(LimjangPriceType priceType, LimjangPurpose purpose) {
5760
}
5861
return null;
5962
}
63+
64+
public static LimjangPrice empty() {
65+
return LimjangPrice.builder().build(); // 모든 price 필드 null
66+
}
6067
}

0 commit comments

Comments
 (0)