Skip to content

Commit 3d99f01

Browse files
authored
[TB-14] 영수증 수정 API 기능 구현 (#21)
1 parent b6c600b commit 3d99f01

22 files changed

+255
-83
lines changed

src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/CreateReceiptApi.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.ClubAccount_BE.receipt.adapter.in.web;
22

33
import com.ClubAccount_BE.core.meta.LoginUser;
4-
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.CreateReceiptRequestDto;
4+
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.ReceiptRequest;
55
import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.CreateReceiptResponseDto;
66
import com.ClubAccount_BE.user.domain.User;
77
import io.swagger.v3.oas.annotations.Operation;
@@ -16,6 +16,6 @@ public interface CreateReceiptApi {
1616
CreateReceiptResponseDto createReceipt(
1717
@LoginUser User user,
1818
@RequestPart(value = "image") MultipartFile image,
19-
@RequestPart(value = "request") CreateReceiptRequestDto createReceiptRequestDto
19+
@RequestPart(value = "request") ReceiptRequest receiptRequest
2020
);
2121
}

src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/CreateReceiptController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.ClubAccount_BE.receipt.adapter.in.web;
22

33
import com.ClubAccount_BE.core.meta.LoginUser;
4-
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.CreateReceiptRequestDto;
4+
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.ReceiptRequest;
55
import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.CreateReceiptResponseDto;
66
import com.ClubAccount_BE.receipt.application.port.in.CreateReceiptUseCase;
77
import com.ClubAccount_BE.user.domain.User;
@@ -23,8 +23,8 @@ public class CreateReceiptController implements CreateReceiptApi {
2323
public CreateReceiptResponseDto createReceipt(
2424
@LoginUser User user,
2525
@RequestPart(value = "image", required = false) MultipartFile image,
26-
@RequestPart(value = "request") CreateReceiptRequestDto createReceiptRequestDto
26+
@RequestPart(value = "request") ReceiptRequest receiptRequest
2727
) {
28-
return createReceiptUseCase.createReceipt(user, image, createReceiptRequestDto);
28+
return createReceiptUseCase.createReceipt(user, image, receiptRequest);
2929
}
3030
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.ClubAccount_BE.receipt.adapter.in.web;
2+
3+
import com.ClubAccount_BE.core.meta.LoginUser;
4+
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.ReceiptRequest;
5+
import com.ClubAccount_BE.user.domain.User;
6+
import io.swagger.v3.oas.annotations.Operation;
7+
import io.swagger.v3.oas.annotations.tags.Tag;
8+
import org.springframework.web.bind.annotation.PathVariable;
9+
import org.springframework.web.bind.annotation.RequestBody;
10+
11+
@Tag(name = "Update Receipt", description = "영수증 수정 API")
12+
public interface UpdateReceiptApi {
13+
14+
@Operation(summary = "영수증 수정", description = "파싱된 영수증 정보를 수정한다.")
15+
Long updateReceipt(
16+
@LoginUser User user,
17+
@PathVariable("receiptId") Long receiptId,
18+
@RequestBody ReceiptRequest receiptRequest
19+
);
20+
21+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.ClubAccount_BE.receipt.adapter.in.web;
2+
3+
import com.ClubAccount_BE.core.meta.LoginUser;
4+
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.ReceiptRequest;
5+
import com.ClubAccount_BE.receipt.application.port.in.UpdateReceiptUseCase;
6+
import com.ClubAccount_BE.user.domain.User;
7+
import lombok.RequiredArgsConstructor;
8+
import org.springframework.web.bind.annotation.PathVariable;
9+
import org.springframework.web.bind.annotation.PutMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
@RestController
15+
@RequiredArgsConstructor
16+
@RequestMapping("/api/v1/receipts")
17+
public class UpdateReceiptController implements UpdateReceiptApi {
18+
19+
private final UpdateReceiptUseCase updateReceiptUseCase;
20+
21+
@PutMapping("/{receiptId}")
22+
public Long updateReceipt(
23+
@LoginUser User user,
24+
@PathVariable("receiptId") Long receiptId,
25+
@RequestBody ReceiptRequest receiptRequest
26+
) {
27+
return updateReceiptUseCase.updateReceipt(user, receiptId, receiptRequest);
28+
}
29+
}

src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/request/CreateReceiptItemRequestDto.java renamed to src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/request/ReceiptItemRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import io.swagger.v3.oas.annotations.media.Schema;
44
import java.math.BigDecimal;
55

6-
public record CreateReceiptItemRequestDto(
6+
public record ReceiptItemRequest(
77

88
@Schema(description = "영수증 아이템 이름", example = "치킨")
99
String name,
@@ -13,7 +13,7 @@ public record CreateReceiptItemRequestDto(
1313

1414
@Schema(description = "영수증 아이템 총 가격", example = "20000")
1515
BigDecimal totalPrice,
16-
16+
1717
@Schema(description = "영수증 아이템 수량", example = "2")
1818
int quantity
1919
) {

src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/request/CreateReceiptRequestDto.java renamed to src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/request/ReceiptRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.time.LocalDate;
77
import java.util.List;
88

9-
public record CreateReceiptRequestDto(
9+
public record ReceiptRequest(
1010

1111
@Schema(
1212
description = "영수증 분류 카테고리",
@@ -29,7 +29,7 @@ public record CreateReceiptRequestDto(
2929
String etc,
3030

3131
@Schema(description = "영수증 내 아이템 리스트")
32-
List<CreateReceiptItemRequestDto> receiptItems
32+
List<ReceiptItemRequest> receiptItems
3333
) {
3434

3535
}

src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import com.ClubAccount_BE.receipt.adapter.out.persistence.repository.ReceiptRepository;
55
import com.ClubAccount_BE.receipt.application.port.out.CreateReceiptPort;
66
import com.ClubAccount_BE.receipt.application.port.out.FindReceiptPort;
7+
import com.ClubAccount_BE.receipt.application.port.out.UpdateReceiptPort;
78
import com.ClubAccount_BE.receipt.domain.Receipt;
89
import com.ClubAccount_BE.receipt.domain.ReceiptItem;
910
import com.ClubAccount_BE.receipt.mapper.ReceiptMapper;
1011
import com.ClubAccount_BE.user.domain.User;
11-
import com.ClubAccount_BE.user.mapper.UserMapper;
1212
import java.util.List;
1313
import lombok.RequiredArgsConstructor;
1414
import org.springframework.data.domain.Page;
@@ -17,16 +17,16 @@
1717

1818
@Component
1919
@RequiredArgsConstructor
20-
public class ReceiptRepositoryAdapter implements CreateReceiptPort, FindReceiptPort {
20+
public class ReceiptRepositoryAdapter
21+
implements CreateReceiptPort, FindReceiptPort, UpdateReceiptPort {
2122

2223
private final ReceiptRepository receiptRepository;
2324

2425
@Override
2526
public Long createReceipt(Receipt receipt, List<ReceiptItem> receiptItems) {
2627

2728
ReceiptEntity receiptEntity = ReceiptMapper.toEntity(receipt);
28-
ReceiptMapper.toEntity(receiptItems, receiptEntity);
29-
29+
receiptEntity.replaceReceiptItem(receiptItems);
3030
return receiptRepository
3131
.save(receiptEntity)
3232
.getId();
@@ -42,8 +42,22 @@ public Page<Receipt> getReceipts(User user, Pageable pageable) {
4242
@Override
4343
public Receipt getReceipt(User user, Long receiptId) {
4444
return receiptRepository
45-
.findByUserAndId(UserMapper.toEntity(user), receiptId)
45+
.findById(receiptId)
4646
.map(ReceiptMapper::toDomain)
4747
.orElseThrow(() -> new IllegalArgumentException("Receipt not found"));
4848
}
49+
50+
@Override
51+
public Long updateReceipt(
52+
Long receiptId,
53+
Receipt receipt,
54+
List<ReceiptItem> receiptItems
55+
) {
56+
ReceiptEntity receiptEntity = receiptRepository.findReceiptById(receiptId)
57+
.orElseThrow(() -> new IllegalArgumentException("Receipt not found"));
58+
59+
receiptEntity.updateReceipt(receipt);
60+
receiptEntity.replaceReceiptItem(receiptItems);
61+
return receiptEntity.getId();
62+
}
4963
}

src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/entity/ReceiptEntity.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.ClubAccount_BE.receipt.adapter.out.persistence.entity;
22

33
import com.ClubAccount_BE.core.entity.TimeBaseEntity;
4+
import com.ClubAccount_BE.receipt.domain.Receipt;
5+
import com.ClubAccount_BE.receipt.domain.ReceiptItem;
46
import com.ClubAccount_BE.receipt.domain.type.ReceiptCategory;
7+
import com.ClubAccount_BE.receipt.mapper.ReceiptItemMapper;
58
import com.ClubAccount_BE.user.adapter.out.persistence.entity.UserEntity;
69
import jakarta.persistence.CascadeType;
710
import jakarta.persistence.Column;
@@ -65,10 +68,26 @@ public class ReceiptEntity extends TimeBaseEntity {
6568
@OneToMany(mappedBy = "receipt", cascade = CascadeType.ALL, orphanRemoval = true)
6669
private List<ReceiptItemEntity> receiptItems = new ArrayList<>();
6770

71+
public void updateReceipt(Receipt receipt) {
72+
this.category = receipt.getCategory();
73+
this.categoryName = receipt.getCategoryName();
74+
this.businessName = receipt.getBusinessName();
75+
this.amount = receipt.getAmount();
76+
this.date = receipt.getDate();
77+
this.etc = receipt.getEtc();
78+
}
79+
6880
public void addReceiptItem(ReceiptItemEntity receiptItem) {
6981
this.receiptItems.add(receiptItem);
7082
if (receiptItem.getReceipt() != this) {
7183
receiptItem.addReceipt(this);
7284
}
7385
}
86+
87+
public void replaceReceiptItem(List<ReceiptItem> receiptItems) {
88+
this.receiptItems.clear();
89+
receiptItems.stream()
90+
.map(ReceiptItemMapper::toEntity)
91+
.forEach(this::addReceiptItem);
92+
}
7493
}

src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/repository/ReceiptRepository.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.ClubAccount_BE.receipt.adapter.out.persistence.repository;
22

33
import com.ClubAccount_BE.receipt.adapter.out.persistence.entity.ReceiptEntity;
4-
import com.ClubAccount_BE.user.adapter.out.persistence.entity.UserEntity;
54
import java.util.Optional;
65
import org.springframework.data.domain.Page;
76
import org.springframework.data.domain.Pageable;
@@ -13,5 +12,5 @@ public interface ReceiptRepository extends JpaRepository<ReceiptEntity, Long> {
1312
Page<ReceiptEntity> findAllByUserId(Long id, Pageable pageable);
1413

1514
@EntityGraph(attributePaths = "receiptItems")
16-
Optional<ReceiptEntity> findByUserAndId(UserEntity user, Long id);
15+
Optional<ReceiptEntity> findReceiptById(Long receiptId);
1716
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.ClubAccount_BE.receipt.application.port.in;
22

3-
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.CreateReceiptRequestDto;
3+
import com.ClubAccount_BE.receipt.adapter.in.web.dto.request.ReceiptRequest;
44
import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.CreateReceiptResponseDto;
55
import com.ClubAccount_BE.user.domain.User;
66
import org.springframework.web.multipart.MultipartFile;
@@ -10,6 +10,6 @@ public interface CreateReceiptUseCase {
1010
CreateReceiptResponseDto createReceipt(
1111
User user,
1212
MultipartFile image,
13-
CreateReceiptRequestDto createReceiptRequestDto
13+
ReceiptRequest receiptRequest
1414
);
1515
}

0 commit comments

Comments
 (0)