Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat [#45] 입금 관련 구현 #65

Merged
merged 73 commits into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
35de8ab
Feat [#45] 입금 Controller 생성
kych4n Jan 19, 2025
45d5447
Feat [#45] 입금 Facade 생성
kych4n Jan 19, 2025
d8bb2ca
Feat [#45] 입금 상세 조회 구현
kych4n Jan 19, 2025
6b2b8fd
Feat [#45] 입금 수정을 위한 상세 조회 구현
kych4n Jan 19, 2025
6a2499b
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
27d8358
Feat [#45] Transactional 어노테이션 추가
kych4n Jan 19, 2025
a56707d
Feat [#45] 입금 Controller 생성
kych4n Jan 19, 2025
7081ee9
Feat [#45] 입금 Facade 생성
kych4n Jan 19, 2025
16f867f
Feat [#45] 입금 상세 조회 구현
kych4n Jan 19, 2025
cb49505
Feat [#45] 입금 수정을 위한 상세 조회 구현
kych4n Jan 19, 2025
c647fac
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
984babf
Feat [#45] Transactional 어노테이션 추가
kych4n Jan 19, 2025
b7bf747
Merge remote-tracking branch 'origin/feat#45' into feat#45
kych4n Feb 1, 2025
b7144a9
Refactor [#45] 공통 응답 핸들러 추상화에 따른 수정
kych4n Feb 1, 2025
c33194e
Refactor [#45] Bank 엔티티 URL 저장하지 않음으로 변경
kych4n Feb 2, 2025
dfb62fe
Feat [#45] 은행 목록 조회 구현
kych4n Feb 2, 2025
2089ec7
Feat [#45] 입금 Controller 생성
kych4n Jan 19, 2025
0b473cf
Feat [#45] 입금 Facade 생성
kych4n Jan 19, 2025
c9cdf8e
Feat [#45] 입금 상세 조회 구현
kych4n Jan 19, 2025
bfb0fee
Feat [#45] 입금 수정을 위한 상세 조회 구현
kych4n Jan 19, 2025
21696a4
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
425c5a6
Feat [#45] Transactional 어노테이션 추가
kych4n Jan 19, 2025
d412e26
Refactor [#45] 공통 응답 핸들러 추상화에 따른 수정
kych4n Feb 1, 2025
1d27dc1
Refactor [#45] Bank 엔티티 URL 저장하지 않음으로 변경
kych4n Feb 2, 2025
dcc4b85
Feat [#45] 은행 목록 조회 구현
kych4n Feb 2, 2025
f87e9b4
Merge remote-tracking branch 'origin/feat#45' into feat#45
kych4n Feb 7, 2025
c51bba8
Feat [#45] 입금 수정 권한 제한
kych4n Feb 7, 2025
a088f4a
Feat [#45] 은행 목록 조회 권한 제한
kych4n Feb 7, 2025
52991b4
Fix [#45] 입금 정보 연관 관계 매핑 누락 수정
kych4n Feb 7, 2025
4e25def
Feat [#45] 입금 정보가 반환이 안된 경우 처리
kych4n Feb 7, 2025
9417d97
Feat [#45] 입금 정보 수정을 위한 정보 조회 시 입력이 안된 경우 처리
kych4n Feb 7, 2025
cbd3c4e
Feat [#45] 입금 Controller 생성
kych4n Jan 19, 2025
0fc00a1
Feat [#45] 입금 Facade 생성
kych4n Jan 19, 2025
dd0f002
Feat [#45] 입금 상세 조회 구현
kych4n Jan 19, 2025
c21799a
Feat [#45] 입금 수정을 위한 상세 조회 구현
kych4n Jan 19, 2025
49639cf
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
b6b8506
Feat [#45] Transactional 어노테이션 추가
kych4n Jan 19, 2025
9fe2a5e
Refactor [#45] 공통 응답 핸들러 추상화에 따른 수정
kych4n Feb 1, 2025
cac237f
Refactor [#45] Bank 엔티티 URL 저장하지 않음으로 변경
kych4n Feb 2, 2025
8539989
Feat [#45] 은행 목록 조회 구현
kych4n Feb 2, 2025
3ce578a
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
f23f8ee
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
40c910e
Refactor [#45] 공통 응답 핸들러 추상화에 따른 수정
kych4n Feb 1, 2025
62f8914
Feat [#45] 입금 수정 권한 제한
kych4n Feb 7, 2025
17abb57
Feat [#45] 은행 목록 조회 권한 제한
kych4n Feb 7, 2025
be6f56a
Fix [#45] 입금 정보 연관 관계 매핑 누락 수정
kych4n Feb 7, 2025
86b26b3
Feat [#45] 입금 정보가 반환이 안된 경우 처리
kych4n Feb 7, 2025
1577460
Feat [#45] 입금 정보 수정을 위한 정보 조회 시 입력이 안된 경우 처리
kych4n Feb 7, 2025
2a44b10
Merge remote-tracking branch 'origin/feat#45' into feat#45
kych4n Feb 7, 2025
37176e4
Feat [#45] IdValidation 적용
kych4n Feb 7, 2025
b9ad32d
Feat [#52] 과외방 관련 구현 (#60)
kych4n Feb 8, 2025
b1bcbfa
Feat [#45] 입금 Controller 생성
kych4n Jan 19, 2025
140f8e2
Feat [#45] 입금 Facade 생성
kych4n Jan 19, 2025
0972fa9
Feat [#45] 입금 상세 조회 구현
kych4n Jan 19, 2025
758316b
Feat [#45] 입금 수정을 위한 상세 조회 구현
kych4n Jan 19, 2025
a8531ca
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
f1fe7e4
Feat [#45] Transactional 어노테이션 추가
kych4n Jan 19, 2025
ba326b0
Refactor [#45] 공통 응답 핸들러 추상화에 따른 수정
kych4n Feb 1, 2025
5a254f2
Refactor [#45] Bank 엔티티 URL 저장하지 않음으로 변경
kych4n Feb 2, 2025
bf8cf34
Feat [#45] 은행 목록 조회 구현
kych4n Feb 2, 2025
3458a17
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
e3660c1
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
27e2ce1
Refactor [#45] 공통 응답 핸들러 추상화에 따른 수정
kych4n Feb 1, 2025
6b47f91
Feat [#45] 입금 수정 권한 제한
kych4n Feb 7, 2025
6352e0a
Feat [#45] 은행 목록 조회 권한 제한
kych4n Feb 7, 2025
4abb9fc
Fix [#45] 입금 정보 연관 관계 매핑 누락 수정
kych4n Feb 7, 2025
a931ac1
Feat [#45] 입금 정보가 반환이 안된 경우 처리
kych4n Feb 7, 2025
6725484
Feat [#45] 입금 정보 수정을 위한 정보 조회 시 입력이 안된 경우 처리
kych4n Feb 7, 2025
5f9b72d
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
a924978
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
2250cb0
Feat [#45] 입금 수정 구현
kych4n Jan 19, 2025
2845274
Feat [#45] IdValidation 적용
kych4n Feb 7, 2025
126e03c
Merge remote-tracking branch 'origin/feat#45' into feat#45
kych4n Feb 8, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.cotato.tlinkserver.api.controller;

import org.cotato.tlinkserver.api.facade.BankFacade;
import org.cotato.tlinkserver.domain.bank.application.dto.response.BanksResponse;
import org.cotato.tlinkserver.global.common.BaseResponse;
import org.cotato.tlinkserver.global.message.SuccessMessage;
import org.cotato.tlinkserver.global.util.ApiResponseUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api/v1/banks")
@RequiredArgsConstructor
public class BankController {

private final BankFacade bankFacade;

@GetMapping
public ResponseEntity<BaseResponse<?>> getBanks() {
BanksResponse banks = bankFacade.getBanks();
return ApiResponseUtil.success(SuccessMessage.SUCCESS, banks);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.cotato.tlinkserver.api.controller;

import org.cotato.tlinkserver.annotation.IdValidation;
import org.cotato.tlinkserver.annotation.Permission;
import org.cotato.tlinkserver.api.facade.DepositFacade;
import org.cotato.tlinkserver.domain.bank.application.dto.request.DepositRequest;
import org.cotato.tlinkserver.domain.bank.application.dto.response.DepositModifyResponse;
import org.cotato.tlinkserver.domain.bank.application.dto.response.DepositResponse;
import org.cotato.tlinkserver.domain.user.constant.Role;
import org.cotato.tlinkserver.global.common.BaseResponse;
import org.cotato.tlinkserver.global.message.SuccessMessage;
import org.cotato.tlinkserver.global.util.ApiResponseUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api/v1/rooms/{roomId}/deposit")
@RequiredArgsConstructor
public class DepositController {

private final DepositFacade depositFacade;

@GetMapping
public ResponseEntity<BaseResponse<?>> getDeposit(@PathVariable(value = "roomId") @IdValidation Long roomId) {
DepositResponse deposit = depositFacade.getDeposit(roomId);
return ApiResponseUtil.success(SuccessMessage.SUCCESS, deposit);
}

@Permission(role = {Role.TEACHER})
@GetMapping("/modify")
public ResponseEntity<BaseResponse<?>> getDepositModify(@PathVariable(value = "roomId") @IdValidation Long roomId) {
DepositModifyResponse depositModify = depositFacade.getDepositModify(roomId);
return ApiResponseUtil.success(SuccessMessage.SUCCESS, depositModify);
}

@Permission(role = {Role.TEACHER})
@PutMapping("/modify")
public ResponseEntity<BaseResponse<?>> modifyDeposit(@PathVariable(value = "roomId") @IdValidation Long roomId,
@RequestBody DepositRequest depositRequest) {
depositFacade.modifyDeposit(roomId, depositRequest);
return ApiResponseUtil.success(SuccessMessage.MODIFIED);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.cotato.tlinkserver.api.controller;

import org.cotato.tlinkserver.annotation.IdValidation;
import org.cotato.tlinkserver.annotation.Permission;
import org.cotato.tlinkserver.annotation.UserId;
import org.cotato.tlinkserver.api.facade.RoomFacade;
import org.cotato.tlinkserver.domain.room.application.dto.request.RoomRequest;
import org.cotato.tlinkserver.domain.room.application.dto.response.RoomModifyResponse;
import org.cotato.tlinkserver.domain.room.application.dto.response.RoomsResponse;
import org.cotato.tlinkserver.domain.room.application.dto.response.ShareCodeResponse;
import org.cotato.tlinkserver.domain.user.constant.Role;
import org.cotato.tlinkserver.global.common.BaseResponse;
import org.cotato.tlinkserver.global.message.ErrorMessage;
import org.cotato.tlinkserver.global.message.SuccessMessage;
import org.cotato.tlinkserver.global.util.ApiResponseUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api/v1/rooms")
@RequiredArgsConstructor
public class RoomController {

private final RoomFacade roomFacade;

@Permission(role = {Role.STUDENT, Role.PARENT, Role.TEACHER})
@GetMapping
public ResponseEntity<BaseResponse<?>> getRooms(@UserId Long userId) {
RoomsResponse roomsAndOpponents = roomFacade.getRooms(userId);
return ApiResponseUtil.success(SuccessMessage.SUCCESS, roomsAndOpponents);
}

@Permission(role = {Role.TEACHER})
@GetMapping("/{roomId}/info")
public ResponseEntity<BaseResponse<?>> getRoomModify(@PathVariable("roomId") @IdValidation Long roomId) {
RoomModifyResponse roomModify = roomFacade.getRoomModify(roomId);
return ApiResponseUtil.success(SuccessMessage.SUCCESS, roomModify);
}

@Permission(role = {Role.TEACHER})
@GetMapping("/{roomId}/shareCode")
public ResponseEntity<BaseResponse<?>> getShareCode(@PathVariable("roomId") @IdValidation Long roomId) {
ShareCodeResponse shareCode = roomFacade.getShareCode(roomId);
return ApiResponseUtil.success(SuccessMessage.CREATED, shareCode);
}

@Permission(role = {Role.TEACHER})
@PostMapping
public ResponseEntity<BaseResponse<?>> saveRoom(@UserId Long userId, @RequestBody RoomRequest roomRequest) {
Long roomId = roomFacade.saveRoom(userId, roomRequest);
return ApiResponseUtil.success(SuccessMessage.CREATED, roomId);
}

@Permission(role = {Role.PARENT, Role.STUDENT})
@PostMapping("/code/{shareCode}")
public ResponseEntity<BaseResponse<?>> joinRoom(@UserId Long userId, @PathVariable("shareCode") String shareCode) {
int result = roomFacade.joinRoom(userId, shareCode);
return switch (result) {
case 0, -1 -> ApiResponseUtil.failure(ErrorMessage.NOT_FOUND, result);
default -> ApiResponseUtil.success(SuccessMessage.SUCCESS);
};
}

@Permission(role = {Role.STUDENT, Role.PARENT, Role.TEACHER})
@PatchMapping("/{roomId}")
public ResponseEntity<BaseResponse<?>> modifyRoom(@UserId Long userId, @PathVariable("roomId") @IdValidation Long roomId,
@RequestBody RoomRequest roomRequest) {
roomFacade.modifyRoom(userId, roomId, roomRequest);
return ApiResponseUtil.success(SuccessMessage.MODIFIED);
}

@Permission(role = {Role.TEACHER})
@DeleteMapping("/{roomId}")
public ResponseEntity<BaseResponse<?>> removeRoom(@UserId Long userId, @PathVariable("roomId") @IdValidation Long roomId) {
roomFacade.removeRoom(userId, roomId);
return ApiResponseUtil.success(SuccessMessage.DELETED);
}

}
36 changes: 36 additions & 0 deletions src/main/java/org/cotato/tlinkserver/api/facade/BankFacade.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.cotato.tlinkserver.api.facade;

import java.util.List;

import org.cotato.tlinkserver.annotation.Permission;
import org.cotato.tlinkserver.domain.bank.application.BankService;
import org.cotato.tlinkserver.domain.bank.application.dto.response.BankResponse;
import org.cotato.tlinkserver.domain.bank.application.dto.response.BanksResponse;
import org.cotato.tlinkserver.domain.user.constant.Role;
import org.cotato.tlinkserver.global.util.S3FileHandler;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class BankFacade {

private final BankService bankService;
private final S3FileHandler s3FileHandler;
private final String FOLDER_NAME = "bank-logo/";
private final String FILE_EXTENSION = ".png";

@Permission(role = {Role.TEACHER})
@Transactional(readOnly = true)
public BanksResponse getBanks() {
List<BankResponse> banks = bankService.getBanks().stream().map(bank -> {
String bankUrl = s3FileHandler.getFileUrl(FOLDER_NAME + bank.getName() + FILE_EXTENSION).toString();
return BankResponse.from(bank, bankUrl);
}).toList();

return BanksResponse.from(banks);
}

}
43 changes: 43 additions & 0 deletions src/main/java/org/cotato/tlinkserver/api/facade/DepositFacade.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.cotato.tlinkserver.api.facade;

import org.cotato.tlinkserver.domain.bank.Bank;
import org.cotato.tlinkserver.domain.bank.application.BankService;
import org.cotato.tlinkserver.domain.bank.application.dto.request.DepositRequest;
import org.cotato.tlinkserver.domain.bank.application.dto.response.DepositModifyResponse;
import org.cotato.tlinkserver.domain.bank.application.dto.response.DepositResponse;
import org.cotato.tlinkserver.domain.room.Room;
import org.cotato.tlinkserver.domain.room.application.RoomService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class DepositFacade {

private final RoomService roomService;
private final BankService bankService;

@Transactional(readOnly = true)
public DepositResponse getDeposit(final Long roomId) {
Room room = roomService.getRoom(roomId);
return DepositResponse.from(room);
}

@Transactional(readOnly = true)
public DepositModifyResponse getDepositModify(final Long roomId) {
Room room = roomService.getRoom(roomId);
return DepositModifyResponse.from(room);
}

@Transactional
public void modifyDeposit(final Long roomId, final DepositRequest depositRequest) {
Room room = roomService.getRoom(roomId);
Bank bank = bankService.getBank(depositRequest.bankId());
room.setAccountNumber(depositRequest.accountNumber());
room.setDepositAt(depositRequest.depositAt());
room.setDepositAmount(depositRequest.depositAmount());
room.setBank(bank);
}
}
122 changes: 122 additions & 0 deletions src/main/java/org/cotato/tlinkserver/api/facade/RoomFacade.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package org.cotato.tlinkserver.api.facade;

import java.util.List;

import org.cotato.tlinkserver.annotation.Facade;
import org.cotato.tlinkserver.domain.room.Registration;
import org.cotato.tlinkserver.domain.room.Room;
import org.cotato.tlinkserver.domain.room.application.RegistrationService;
import org.cotato.tlinkserver.domain.room.application.RoomService;
import org.cotato.tlinkserver.domain.room.application.dto.request.RoomRequest;
import org.cotato.tlinkserver.domain.room.application.dto.response.RoomModifyResponse;
import org.cotato.tlinkserver.domain.room.application.dto.response.RoomResponse;
import org.cotato.tlinkserver.domain.room.application.dto.response.RoomsResponse;
import org.cotato.tlinkserver.domain.room.application.dto.response.ShareCodeResponse;
import org.cotato.tlinkserver.domain.user.User;
import org.cotato.tlinkserver.domain.user.application.UserService;
import org.cotato.tlinkserver.domain.user.constant.Role;
import org.cotato.tlinkserver.global.exception.UnauthorizedException;
import org.cotato.tlinkserver.global.message.ErrorMessage;
import org.cotato.tlinkserver.global.util.RandomUtil;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;

@Facade
@RequiredArgsConstructor
public class RoomFacade {

private final RoomService roomService;
private final RegistrationService registrationService;
private final UserService userService;

@Transactional
public Long saveRoom(final Long teacherId, final RoomRequest roomRequest) {
User teacher = userService.getValidUser(teacherId);
Room room = roomRequest.save(teacher);
return roomService.saveRoom(room);
}

@Transactional(readOnly = true)
public RoomsResponse getRooms(final Long userId) {
User user = userService.getValidUser(userId);
List<Room> userRooms = registrationService.getRegistrations(userId).stream().map(Registration::getRoom).toList();

if (user.getRole().equals(Role.TEACHER)) {
return RoomsResponse.from(userRooms.stream()
.map(room -> {
String roomName = registrationService.getRegistration(userId, room.getId()).getRoomName();
Registration opponentRegistration = registrationService.getRegistration(room.getId(), Role.STUDENT);
return RoomResponse.from(opponentRegistration, roomName);
})
.toList());
}
else if (user.getRole().equals(Role.STUDENT) || user.getRole().equals(Role.PARENT)) {
return RoomsResponse.from(userRooms.stream()
.map(room -> {
String roomName = registrationService.getRegistration(userId, room.getId()).getRoomName();
Registration opponentRegistration = registrationService.getRegistration(room.getId(), Role.TEACHER);
return RoomResponse.from(opponentRegistration, roomName);
})
.toList());
}
else {
throw new UnauthorizedException(ErrorMessage.UNAUTHORIZED);
}
}

@Transactional(readOnly = true)
public RoomModifyResponse getRoomModify(final Long roomId) {
return registrationService.getRoomModify(roomId);
}

@Transactional
public void modifyRoom(final Long userId, final Long roomId, final RoomRequest roomRequest) {
User user = userService.getValidUser(userId);
Room room = roomService.getRoom(roomId);
Registration registration = registrationService.getRegistration(userId, roomId);

if (user.getRole().equals(Role.TEACHER)) {
Registration parentRegistration = registrationService.getRegistration(roomId, Role.PARENT);
Registration studentRegistration = registrationService.getRegistration(roomId, Role.STUDENT);
roomRequest.modify(room, registration, parentRegistration, studentRegistration);
}
else if (user.getRole().equals(Role.STUDENT) || user.getRole().equals(Role.PARENT)) {
roomRequest.modify(registration);
}
}

@Transactional
public void removeRoom(final Long userId, final Long roomId) {
registrationService.getRegistration(userId, roomId);
roomService.removeRoom(roomId);
}

@Transactional
public ShareCodeResponse getShareCode(final Long roomId) {
String shareCode = RandomUtil.generateRandomCode('0', 'z', 10);
Room room = roomService.getRoom(roomId);
room.setShareCode(shareCode);
return ShareCodeResponse.from(shareCode);
}

@Transactional
public int joinRoom(final Long userId, final String shareCode) {
User user = userService.getValidUser(userId);
Room room = roomService.getRoom(shareCode);

Registration registration = registrationService.getRegistration(room.getId(), user.getRole());

if (registration.getUser() == null) {
registration.setUser(user);
user.addRegistration(registration);
return 1;
} else if (registration.getUser().equals(user)) {
return 0;
} else {
return -1;
}

}

}
7 changes: 2 additions & 5 deletions src/main/java/org/cotato/tlinkserver/domain/bank/Bank.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ public class Bank {
@Column(name = "bank_name", nullable = false, length = 20)
private String name;

@Column(name = "image_path", nullable = false, length = 250)
private String imagePath;

@Builder
public Bank(String name, String imagePath) {
public Bank(String name) {
this.name = name;
this.imagePath = imagePath;
}

}
Loading