Skip to content

Commit

Permalink
✨ Feature/#28 - 4.5 영수증 리뷰 등록하기 API 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
dongkyeomjang committed Nov 19, 2024
1 parent 6ebd1bd commit 785c325
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 3 deletions.
17 changes: 15 additions & 2 deletions http/onjung/OnjungControllerHttpRequest.http
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,24 @@ Authorization: Bearer {{access_token}}
### 4.4 가게 방문 인증용 영수증 OCR 조회하기
// @no-log
POST {{host_url}}/api/v1/receipts/ocr
Content-Type: multipart/form-data; boundary=boundary
Authorization: Bearer {{access_token}}
Content-Type: multipart/form-data; boundary=boundary

--boundary
Content-Disposition: form-data; name="file"; filename="receipt.jpg"
Content-Type: image/jpeg

< /Users/kyeom/Desktop/receipt3.jpeg
< /Users/kyeom/Desktop/receipt3.jpeg

### 4.5 영수증 리뷰 등록하기
// @no-log
POST {{host_url}}/api/v1/receipts
Authorization: Bearer {{access_token}}
Content-Type: application/json

{
"store_name": "{{onjung.API_4_5.store_name}}",
"store_address": "{{onjung.API_4_5.store_address}}",
"payment_date": "{{onjung.API_4_5.payment_date}}",
"payment_amount": "{{onjung.API_4_5.payment_amount}}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface StoreRepository extends JpaRepository <Store, Long> {

Optional<Store> findByOcrStoreNameAndOcrStoreAddress(String ocrStoreName, String ocrStoreAddress);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public enum ErrorCode {
// Not Found Error
NOT_FOUND_END_POINT(40400, HttpStatus.NOT_FOUND, "존재하지 않는 API 엔드포인트입니다."),
NOT_FOUND_RESOURCE(40404, HttpStatus.NOT_FOUND, "해당 리소스가 존재하지 않습니다."),
NOT_FOUND_MATCHED_STORE(40410, HttpStatus.NOT_FOUND, "영수증 내용과 일치하는 매장이 존재하지 않습니다."),

// Invalid Argument Error
MISSING_REQUEST_PARAMETER(40000, HttpStatus.BAD_REQUEST, "필수 요청 파라미터가 누락되었습니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,48 @@
package com.daon.onjung.onjung.application.controller.command;

import com.daon.onjung.core.annotation.security.AccountID;
import com.daon.onjung.core.dto.ResponseDto;
import com.daon.onjung.onjung.application.dto.request.CreateReceiptRequestDto;
import com.daon.onjung.onjung.application.dto.response.ReceiptOCRResponseDto;
import com.daon.onjung.onjung.application.usecase.CreateReceiptUseCase;
import com.daon.onjung.onjung.application.usecase.ReceiptOCRUseCase;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.UUID;

@RestController
@RequiredArgsConstructor
public class OnjungCommandV1Controller {

private final ReceiptOCRUseCase receiptOCRUseCase;
private final CreateReceiptUseCase createReceiptUseCase;

/**
* 영수증 OCR 처리하기
* 4.4 가게 방문 인증용 영수증 OCR 조회하기
*/
@PostMapping(value = "/api/v1/receipts/ocr", consumes = "multipart/form-data")
public ResponseDto<ReceiptOCRResponseDto> OCRReceipt(
@RequestPart(value = "file") MultipartFile file
) {
return ResponseDto.ok(receiptOCRUseCase.execute(file));
}

/**
* 4.5 영수증 리뷰 등록하기
*/
@PostMapping("/api/v1/receipts")
public ResponseDto<Void> reviewReceipt(
@AccountID UUID accountId,
@RequestBody @Valid CreateReceiptRequestDto requestDto
) {
createReceiptUseCase.execute(accountId, requestDto);
return ResponseDto.created(null);
}

}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.daon.onjung.onjung.application.dto.request;

import com.fasterxml.jackson.annotation.JsonProperty;

public record CreateReceiptRequestDto(
@JsonProperty("store_name")
String storeName,

@JsonProperty("store_address")
String storeAddress,

@JsonProperty("payment_date")
String paymentDate,

@JsonProperty("payment_amount")
String paymentAmount
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.daon.onjung.onjung.application.service;

import com.daon.onjung.account.domain.Store;
import com.daon.onjung.account.domain.User;
import com.daon.onjung.account.repository.mysql.StoreRepository;
import com.daon.onjung.account.repository.mysql.UserRepository;
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.core.utility.DateTimeUtil;
import com.daon.onjung.onjung.application.dto.request.CreateReceiptRequestDto;
import com.daon.onjung.onjung.application.usecase.CreateReceiptUseCase;
import com.daon.onjung.onjung.domain.Receipt;
import com.daon.onjung.onjung.domain.service.ReceiptService;
import com.daon.onjung.onjung.repository.mysql.ReceiptRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class CreateReceiptService implements CreateReceiptUseCase {

private final UserRepository userRepository;
private final StoreRepository storeRepository;
private final ReceiptRepository receiptRepository;

private final ReceiptService receiptService;

@Override
@Transactional
public void execute(UUID accountId, CreateReceiptRequestDto requestDto) {

// 유저 조회
User user = userRepository.findById(accountId)
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE));

// 매장 조회
Store store = storeRepository.findByOcrStoreNameAndOcrStoreAddress(requestDto.storeName(), requestDto.storeAddress())
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_MATCHED_STORE));

// paymentDate 형변환
LocalDate paymentDate = DateTimeUtil.convertStringToLocalDate(requestDto.paymentDate());

// paymentAmount 쉼표 제거 및 형변환
Integer paymentAmount = Integer.parseInt(requestDto.paymentAmount().replaceAll(",", ""));

// 영수증 생성
Receipt receipt = receiptRepository.save(receiptService.createReceipt(
paymentDate,
paymentAmount,
user,
store
));
receiptRepository.save(receipt);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.daon.onjung.onjung.application.usecase;

import com.daon.onjung.core.annotation.bean.UseCase;
import com.daon.onjung.onjung.application.dto.request.CreateReceiptRequestDto;

import java.util.UUID;

@UseCase
public interface CreateReceiptUseCase {
void execute(UUID accountId, CreateReceiptRequestDto requestDto);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
package com.daon.onjung.onjung.domain.service;

import com.daon.onjung.account.domain.Store;
import com.daon.onjung.account.domain.User;
import com.daon.onjung.onjung.domain.Receipt;
import org.springframework.stereotype.Service;

import java.time.LocalDate;

@Service
public class ReceiptService {

public Receipt createReceipt(
LocalDate paymentDate,
Integer paymentAmount,
User user,
Store store
) {
return Receipt.builder()
.paymentAmount(paymentAmount)
.paymentDate(paymentDate)
.user(user)
.store(store)
.build();
}
}

0 comments on commit 785c325

Please sign in to comment.