Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/main/java/com/dangsim/reward/controller/RewardController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.dangsim.reward.controller;

import com.dangsim.reward.dto.response.RewardChatResponse;
import com.dangsim.reward.service.RewardService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class RewardController {
private final RewardService rewardService;

// "심부름 수행 버튼 클릭시"
@PostMapping("/api/reward/chat/{chatId}")
public RewardChatResponse rewardToPerformer(@PathVariable Long chatId) {

rewardService.updateRewardByTaskCompleteBtn(chatId);

return rewardService.rewardByChatId(chatId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dangsim.reward.dto.request;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class RewardChatRequest { // 프론트 채팅방이 전달하는 id
private Long chatId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.dangsim.reward.dto.response;

import com.dangsim.reward.entity.Reward;
import lombok.Builder;
import lombok.Getter;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Getter
@Builder
public class RewardChatResponse {
private Long performerId;
private BigDecimal beforeReward;
private BigDecimal amount;
private BigDecimal afterReward;
private LocalDateTime completedAt;

public static RewardChatResponse from(Reward statement) {
return RewardChatResponse.builder()
.performerId(statement.getUser().getId())
.beforeReward(statement.getBeforeReward())
.amount(statement.getAmount())
.afterReward(statement.getBeforeReward().add(statement.getAmount()))
.completedAt(statement.getCompletedAt())
.build();
}
}
82 changes: 82 additions & 0 deletions src/main/java/com/dangsim/reward/entity/Reward.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.dangsim.reward.entity;

import com.dangsim.common.entity.BaseEntity;
import com.dangsim.task.entity.Task;
import com.dangsim.user.entity.User;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;

import static lombok.AccessLevel.PRIVATE;

@Entity
@Table(name = "reward_statement")
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Reward extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "reward_statement_id")
private Long id;

// 수행자가 가지고 있던 리워드 값
@NotNull
@Column(name = "before_reward", nullable = false)
private BigDecimal beforeReward;

// task의 리워드 값
@NotNull
@Column(name = "amount", nullable = false)
private BigDecimal amount;

// 수행자의 최종 리워드 값
@NotNull
@Column(name = "after_reward", nullable = false)
private BigDecimal afterReward;

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "task_id", nullable = false, foreignKey = @ForeignKey(name = "fk_reward_task"))
private Task task;

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false, foreignKey = @ForeignKey(name = "fk_reward_user"))
private User user;

@NotNull
@Column(name = "requested_at", nullable = false)
private LocalDateTime requestedAt;

@Column(name = "completed_at")
private LocalDateTime completedAt;

@Builder(access = PRIVATE)
public Reward(BigDecimal amount, Task task, User user, LocalDateTime completedAt) {
this.amount = amount;
this.task = task;
this.user = user;
this.requestedAt = LocalDateTime.now();
this.completedAt = completedAt;
}

public static Reward of(BigDecimal amount, Task task, User user, LocalDateTime completedAt) {
return Reward.builder()
.amount(amount)
.task(task)
.user(user)
.requestedAt(LocalDateTime.now())
.completedAt(completedAt)
.build();
}

public void markCompleted() {
this.completedAt = LocalDateTime.now();
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/dangsim/reward/repository/RewardRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.dangsim.reward.repository;

import com.dangsim.reward.entity.Reward;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface RewardRepository extends JpaRepository<Reward, Long> {
Optional<Reward> findTopByTaskIdAndUserIdOrderByCreatedAtDesc(Long taskId, Long userId);
}
93 changes: 93 additions & 0 deletions src/main/java/com/dangsim/reward/service/RewardService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.dangsim.reward.service;

import com.dangsim.chat.entity.ChatRoom;
import com.dangsim.chat.repository.ChatRoomRepository;
import com.dangsim.payment.entity.Payment;
import com.dangsim.payment.repository.PaymentRepository;
import com.dangsim.reward.dto.response.RewardChatResponse;
import com.dangsim.reward.entity.Reward;
import com.dangsim.reward.repository.RewardRepository;
import com.dangsim.task.entity.Task;
import com.dangsim.task.repository.TaskRepository;
import com.dangsim.user.entity.User;
import com.dangsim.user.repository.UserRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class RewardService {

private final ChatRoomRepository chatRoomRepository;
private final TaskRepository taskRepository;
private final PaymentRepository paymentRepository;
private final UserRepository userRepository;
private final RewardRepository rewardStatementRepository;

/**
* 1. 실제 리워드 지급 로직 (심부름 완료 버튼 클릭 시 호출)
*/
@Transactional
public Reward updateRewardByTaskCompleteBtn(Long chatId) {
// 1. chatId → ChatRoom
ChatRoom chatRoom = chatRoomRepository.findById(chatId)
.orElseThrow(() -> new EntityNotFoundException("해당 채팅방을 찾을 수 없습니다."));

// 2. ChatRoom → Task
Task task = chatRoom.getTask();
Long taskId = task.getId();

// 3. Task → 리워드, 마감 시간
BigDecimal rewardAmount = task.getReward();
LocalDateTime deadline = task.getDeadline();

// 4. Task → Payment → performerId
Payment payment = paymentRepository.findByTaskId(taskId)
.orElseThrow(() -> new EntityNotFoundException("해당 Task에 대한 결제 정보를 찾을 수 없습니다."));
Long performerId = payment.getPerformer().getId();

// 5. performer → User
User performer = userRepository.findById(performerId)
.orElseThrow(() -> new EntityNotFoundException("해당 수행자 유저를 찾을 수 없습니다."));

BigDecimal beforeReward = performer.getReward();
BigDecimal afterReward = beforeReward.add(rewardAmount);

// 6. User reward 값 업데이트
performer.updateReward(afterReward);
userRepository.save(performer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프로젝트후에 JPA 변경 감지에 대해서 공부해보세요~~


// 7. 정산 내역 저장
Reward statement = Reward.of(
rewardAmount,
task,
performer,
LocalDateTime.now()
);
rewardStatementRepository.save(statement);

return statement;
}

/**
* 2. 리워드 정산 후 결과 반환
*/
@Transactional(readOnly = true)
public RewardChatResponse rewardByChatId (Long chatId){
ChatRoom chatRoom = chatRoomRepository.findById(chatId)
.orElseThrow(() -> new EntityNotFoundException("해당 채팅방을 찾을 수 없습니다."));
Long taskId = chatRoom.getTask().getId();
Long performerId = chatRoom.getPerformer().getId();

Reward statement = rewardStatementRepository
.findTopByTaskIdAndUserIdOrderByCreatedAtDesc(taskId, performerId)
.orElseThrow(() -> new EntityNotFoundException("정산 내역을 찾을 수 없습니다."));

return RewardChatResponse.from(statement);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RewardRefundEntity {
public class RewardRefund {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down Expand Up @@ -76,8 +76,8 @@ public class RewardRefundEntity {
private LocalDateTime completedAt;

@Builder(access = PRIVATE)
private RewardRefundEntity(User user, BigDecimal amount, String bankName, String bankAccount, String holderName,
RewardRefundStatus status) {
private RewardRefund(User user, BigDecimal amount, String bankName, String bankAccount, String holderName,
RewardRefundStatus status) {
this.user = user;
this.amount = amount;
this.bankName = bankName;
Expand All @@ -87,9 +87,9 @@ private RewardRefundEntity(User user, BigDecimal amount, String bankName, String
this.requestedAt = LocalDateTime.now();
}

public static RewardRefundEntity of(User user, BigDecimal amount, String bankName, String bankAccount,
String holderName, RewardRefundStatus status) {
return RewardRefundEntity.builder()
public static RewardRefund of(User user, BigDecimal amount, String bankName, String bankAccount,
String holderName, RewardRefundStatus status) {
return RewardRefund.builder()
.user(user)
.amount(amount)
.bankName(bankName)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.dangsim.rewardRefund.repository;

import com.dangsim.rewardRefund.entity.RewardRefund;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.dangsim.rewardRefund.entity.RewardRefundEntity;

@Repository
public interface RewardRefundRepository extends JpaRepository<RewardRefundEntity, Long> {
public interface RewardRefundRepository extends JpaRepository<RewardRefund, Long> {

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

import java.math.BigDecimal;

import com.dangsim.rewardRefund.entity.RewardRefund;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dangsim.common.exception.runtime.BaseException;
import com.dangsim.rewardRefund.dto.request.RewardRefundRequest;
import com.dangsim.rewardRefund.entity.RewardRefundEntity;
import com.dangsim.rewardRefund.entity.RewardRefundStatus;
import com.dangsim.rewardRefund.repository.RewardRefundRepository;
import com.dangsim.user.entity.User;
Expand Down Expand Up @@ -40,7 +40,7 @@ public void requestRefund(Long userId, RewardRefundRequest requestDto) {
throw new BaseException(REFUND_AMOUNT_EXCEEDS_BALANCE);
}

RewardRefundEntity rewardRequest = RewardRefundEntity.of(
RewardRefund rewardRequest = RewardRefund.of(
user,
requestAmount,
requestDto.getBankName(),
Expand Down
Loading