Skip to content

Commit

Permalink
Merge pull request #133 from sharemindteam/feature/132-post-isPaid
Browse files Browse the repository at this point in the history
feat: 일대다 비공개 상담 결제 여부 처리하는 어드민 api 구현
  • Loading branch information
letskuku authored Mar 10, 2024
2 parents 4154f0a + e596cc1 commit 3b333cb
Show file tree
Hide file tree
Showing 14 changed files with 199 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import com.example.sharemind.admin.dto.response.ConsultGetUnpaidResponse;
import com.example.sharemind.admin.dto.response.PaymentGetRefundWaitingResponse;
import com.example.sharemind.admin.dto.response.PaymentGetSettlementOngoingResponse;
import com.example.sharemind.admin.dto.response.PostGetUnpaidPrivateResponse;
import com.example.sharemind.counselor.dto.response.CounselorGetProfileResponse;

import java.util.List;

public interface AdminService {
List<ConsultGetUnpaidResponse> getUnpaidConsults();

void updateIsPaid(Long consultId);
void updateConsultIsPaid(Long consultId);

List<CounselorGetProfileResponse> getPendingCounselors();

Expand All @@ -23,4 +24,8 @@ public interface AdminService {
List<PaymentGetSettlementOngoingResponse> getSettlementOngoingPayments();

void updateSettlementComplete(Long paymentId);

List<PostGetUnpaidPrivateResponse> getUnpaidPrivatePosts();

void updatePostIsPaid(Long postId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.example.sharemind.admin.dto.response.ConsultGetUnpaidResponse;
import com.example.sharemind.admin.dto.response.PaymentGetRefundWaitingResponse;
import com.example.sharemind.admin.dto.response.PaymentGetSettlementOngoingResponse;
import com.example.sharemind.admin.dto.response.PostGetUnpaidPrivateResponse;
import com.example.sharemind.chat.application.ChatService;
import com.example.sharemind.chat.domain.Chat;
import com.example.sharemind.consult.application.ConsultService;
Expand All @@ -26,6 +27,10 @@
import com.example.sharemind.payment.domain.Payment;
import com.example.sharemind.payment.exception.PaymentErrorCode;
import com.example.sharemind.payment.exception.PaymentException;
import com.example.sharemind.post.application.PostService;
import com.example.sharemind.post.domain.Post;
import com.example.sharemind.post.exception.PostErrorCode;
import com.example.sharemind.post.exception.PostException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -43,6 +48,7 @@ public class AdminServiceImpl implements AdminService {
private final PaymentService paymentService;
private final CounselorService counselorService;
private final CustomerService customerService;
private final PostService postService;

@Override
public List<ConsultGetUnpaidResponse> getUnpaidConsults() {
Expand All @@ -52,7 +58,7 @@ public List<ConsultGetUnpaidResponse> getUnpaidConsults() {
}

@Transactional
public void updateIsPaid(Long consultId) {
public void updateConsultIsPaid(Long consultId) {
Consult consult = consultService.getConsultByConsultId(consultId);
if (consult.getPayment().getIsPaid()) {
throw new ConsultException(ConsultErrorCode.CONSULT_ALREADY_PAID, consultId.toString());
Expand Down Expand Up @@ -139,4 +145,22 @@ public void updateSettlementComplete(Long paymentId) {

payment.updateCounselorStatusSettlementComplete();
}

@Override
public List<PostGetUnpaidPrivateResponse> getUnpaidPrivatePosts() {
return postService.getUnpaidPrivatePosts().stream()
.map(PostGetUnpaidPrivateResponse::of)
.toList();
}

@Transactional
@Override
public void updatePostIsPaid(Long postId) {
Post post = postService.getPostByPostId(postId);
if (post.getIsPaid()) {
throw new PostException(PostErrorCode.POST_ALREADY_PAID, postId.toString());
}

post.updateIsPaid();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.example.sharemind.admin.dto.response;

import com.example.sharemind.post.domain.Post;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;

@Getter
public class PostGetUnpaidPrivateResponse {

@Schema(description = "일대다 상담 아이디")
private final Long postId;

@Schema(description = "구매자 닉네임")
private final String customerName;

@Schema(description = "상담료")
private final Long cost;

@Schema(description = "상담 공개 여부")
private final Boolean isPublic;

@Schema(description = "상담 신청 일시")
private final LocalDateTime createdAt;

@Builder
public PostGetUnpaidPrivateResponse(Long postId, String customerName, Long cost,
Boolean isPublic, LocalDateTime createdAt) {
this.postId = postId;
this.customerName = customerName;
this.cost = cost;
this.isPublic = isPublic;
this.createdAt = createdAt;
}

public static PostGetUnpaidPrivateResponse of(Post post) {
return PostGetUnpaidPrivateResponse.builder()
.postId(post.getPostId())
.customerName(post.getCustomer().getNickname())
.cost(post.getCost())
.isPublic(post.getIsPublic())
.createdAt(post.getCreatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.example.sharemind.admin.dto.response.ConsultGetUnpaidResponse;
import com.example.sharemind.admin.dto.response.PaymentGetRefundWaitingResponse;
import com.example.sharemind.admin.dto.response.PaymentGetSettlementOngoingResponse;
import com.example.sharemind.admin.dto.response.PostGetUnpaidPrivateResponse;
import com.example.sharemind.counselor.dto.response.CounselorGetProfileResponse;
import com.example.sharemind.global.exception.CustomExceptionResponse;
import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -28,7 +29,7 @@ public class AdminController {

private final AdminService adminService;

@Operation(summary = "미결제 상담 리스트 조회", description = "결제 여부(isPaid)가 false인 consult 리스트 조회")
@Operation(summary = "미결제 상담(편지/채팅) 리스트 조회", description = "결제 여부(isPaid)가 false인 consult 리스트 조회")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "조회 성공")
})
Expand All @@ -37,7 +38,7 @@ public ResponseEntity<List<ConsultGetUnpaidResponse>> getUnpaidConsults() {
return ResponseEntity.ok(adminService.getUnpaidConsults());
}

@Operation(summary = "상담 결제 여부 수정", description = "결제 여부(isPaid)가 false인 consult를 true로 수정")
@Operation(summary = "상담(편지/채팅) 결제 여부 수정", description = "결제 여부(isPaid)가 false인 consult를 true로 수정")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "수정 성공"),
@ApiResponse(responseCode = "400", description = "이미 결제 완료된 상담",
Expand All @@ -53,8 +54,8 @@ public ResponseEntity<List<ConsultGetUnpaidResponse>> getUnpaidConsults() {
@Parameter(name = "consultId", description = "상담 아이디")
})
@PatchMapping("/unpaid-consults/{consultId}")
public ResponseEntity<Void> updateIsPaid(@PathVariable Long consultId) {
adminService.updateIsPaid(consultId);
public ResponseEntity<Void> updateConsultIsPaid(@PathVariable Long consultId) {
adminService.updateConsultIsPaid(consultId);
return ResponseEntity.ok().build();
}

Expand Down Expand Up @@ -152,4 +153,34 @@ public ResponseEntity<Void> updateSettlementComplete(@PathVariable Long paymentI
adminService.updateSettlementComplete(paymentId);
return ResponseEntity.ok().build();
}

@Operation(summary = "미결제 일대다 상담 리스트 조회", description = "결제 여부(isPaid)가 false인 일대다 상담 리스트 조회")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "조회 성공")
})
@GetMapping("/unpaid-posts")
public ResponseEntity<List<PostGetUnpaidPrivateResponse>> getUnpaidPrivatePosts() {
return ResponseEntity.ok(adminService.getUnpaidPrivatePosts());
}

@Operation(summary = "일대다 비공개 상담 결제 여부 수정", description = "결제 여부(isPaid)가 false인 일대다 상담을 true로 수정")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "수정 성공"),
@ApiResponse(responseCode = "400", description = "이미 결제 완료된 상담",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = CustomExceptionResponse.class))
),
@ApiResponse(responseCode = "404", description = "존재하지 않는 일대다 상담 아이디로 요청됨",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = CustomExceptionResponse.class))
)
})
@Parameters({
@Parameter(name = "postId", description = "일대다 상담 아이디")
})
@PatchMapping("/unpaid-posts/{postId}")
public ResponseEntity<Void> updatePostIsPaid(@PathVariable Long postId) {
adminService.updatePostIsPaid(postId);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.example.sharemind.letter.exception.LetterException;
import com.example.sharemind.letterMessage.exception.LetterMessageException;
import com.example.sharemind.payment.exception.PaymentException;
import com.example.sharemind.post.exception.PostException;
import com.example.sharemind.review.exception.ReviewException;
import com.example.sharemind.wishList.exception.WishListException;
import jakarta.validation.ConstraintViolationException;
Expand Down Expand Up @@ -108,6 +109,13 @@ public ResponseEntity<CustomExceptionResponse> catchPaymentException(PaymentExce
.body(CustomExceptionResponse.of(e.getErrorCode().name(), e.getMessage()));
}

@ExceptionHandler(PostException.class)
public ResponseEntity<CustomExceptionResponse> catchPostException(PostException e) {
log.error(e.getMessage(), e);
return ResponseEntity.status(e.getErrorCode().getHttpStatus())
.body(CustomExceptionResponse.of(e.getErrorCode().name(), e.getMessage()));
}

@ExceptionHandler(GlobalException.class)
public ResponseEntity<CustomExceptionResponse> catchGlobalException(GlobalException e) {
log.error(e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package com.example.sharemind.post.application;

import com.example.sharemind.post.domain.Post;
import com.example.sharemind.post.dto.request.PostCreateRequest;
import java.util.List;

public interface PostService {

void createPost(PostCreateRequest postCreateRequest, Long customerId);

List<Post> getUnpaidPrivatePosts();

Post getPostByPostId(Long postId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import com.example.sharemind.customer.application.CustomerService;
import com.example.sharemind.customer.domain.Customer;
import com.example.sharemind.global.content.ConsultCategory;
import com.example.sharemind.post.domain.Post;
import com.example.sharemind.post.dto.request.PostCreateRequest;
import com.example.sharemind.post.exception.PostErrorCode;
import com.example.sharemind.post.exception.PostException;
import com.example.sharemind.post.repository.PostRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -21,9 +24,18 @@ public class PostServiceImpl implements PostService {
@Override
public void createPost(PostCreateRequest postCreateRequest, Long customerId) {
Customer customer = customerService.getCustomerByCustomerId(customerId);
ConsultCategory consultCategory = ConsultCategory.getConsultCategoryByName(
postCreateRequest.getConsultCategory());

postRepository.save(postCreateRequest.toEntity(customer, consultCategory));
postRepository.save(postCreateRequest.toEntity(customer));
}

@Override
public List<Post> getUnpaidPrivatePosts() {
return postRepository.findAllByIsPaidIsFalseAndIsActivatedIsTrue();
}

@Override
public Post getPostByPostId(Long postId) {
return postRepository.findByPostIdAndIsActivatedIsTrue(postId).orElseThrow(
() -> new PostException(PostErrorCode.POST_NOT_FOUND, postId.toString()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@RequiredArgsConstructor
public enum PostStatus {

WAITING("상담 대기"),
PROCEEDING("상담 진행 중"),
COMPLETED("상담 마감"),
REPORTED("신고로 인한 게시 중단");
Expand Down
26 changes: 16 additions & 10 deletions src/main/java/com/example/sharemind/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,13 @@ public class Post extends BaseEntity {
@JoinColumn(name = "customer_id")
private Customer customer;

@Column(name = "consult_category", nullable = false)
@Column(name = "consult_category")
@Enumerated(EnumType.STRING)
private ConsultCategory consultCategory;

@Column(nullable = false)
private String title;

@Size(max = 1000, message = "상담 내용은 최대 1000자입니다.")
@Column(nullable = false)
private String content;

@Column(nullable = false)
Expand All @@ -65,17 +63,25 @@ public class Post extends BaseEntity {
private Boolean isPaid;

@Builder
public Post(Customer customer, ConsultCategory consultCategory, String title, String content,
Long cost, Boolean isPublic) {
public Post(Customer customer, Long cost, Boolean isPublic) {
this.customer = customer;
this.consultCategory = consultCategory;
this.title = title;
this.content = content;
this.cost = cost;
this.isPublic = isPublic;
this.postStatus = PostStatus.PROCEEDING;
this.postStatus = PostStatus.WAITING;
this.totalLike = 0L;
this.totalComment = 0L;
this.isPaid = false;
setIsPaid(isPublic);
}

public void updateIsPaid() {
this.isPaid = true;
}

private void setIsPaid(Boolean isPublic) {
if (isPublic) {
this.isPaid = true;
} else {
this.isPaid = false;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
package com.example.sharemind.post.dto.request;

import com.example.sharemind.customer.domain.Customer;
import com.example.sharemind.global.content.ConsultCategory;
import com.example.sharemind.post.domain.Post;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Getter;

@Getter
public class PostCreateRequest {

@Schema(description = "선택한 상담 카테고리", example = "BOREDOM")
@NotBlank(message = "상담 카테고리는 공백일 수 없습니다.")
private String consultCategory;

@Schema(description = "상담 제목", example = "남자친구의 심리가 궁금해요")
@NotBlank(message = "상담 제목은 공백일 수 없습니다.")
private String title;

@Schema(description = "상담 내용", example = "안녕하세요 어쩌구저쩌구~")
@NotBlank(message = "상담 내용은 공백일 수 없습니다.")
@Size(max = 1000, message = "상담 내용은 최대 1000자입니다.")
private String content;

@Schema(description = "상담료")
@NotNull(message = "상담료는 공백일 수 없습니다.")
private Long cost;
Expand All @@ -33,12 +17,9 @@ public class PostCreateRequest {
@NotNull(message = "상담 공개 여부는 공백일 수 없습니다.")
private Boolean isPublic;

public Post toEntity(Customer customer, ConsultCategory consultCategory) {
public Post toEntity(Customer customer) {
return Post.builder()
.customer(customer)
.consultCategory(consultCategory)
.title(title)
.content(content)
.cost(cost)
.isPublic(isPublic)
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.sharemind.post.exception;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor
public enum PostErrorCode {

POST_NOT_FOUND(HttpStatus.NOT_FOUND, "일대다 상담이 존재하지 않습니다."),
POST_ALREADY_PAID(HttpStatus.BAD_REQUEST, "이미 결제 완료된 일대다 상담입니다.");

private final HttpStatus httpStatus;
private final String message;
}
Loading

0 comments on commit 3b333cb

Please sign in to comment.