feat: implement CardService
This commit is contained in:
175
src/main/java/com/example/bankcards/service/CardService.java
Normal file
175
src/main/java/com/example/bankcards/service/CardService.java
Normal file
@@ -0,0 +1,175 @@
|
||||
package com.example.bankcards.service;
|
||||
|
||||
import com.example.bankcards.dto.CardResponse;
|
||||
import com.example.bankcards.dto.CreateCardRequest;
|
||||
import com.example.bankcards.dto.TransferRequest;
|
||||
import com.example.bankcards.entity.Card;
|
||||
import com.example.bankcards.entity.CardStatus;
|
||||
import com.example.bankcards.entity.User;
|
||||
import com.example.bankcards.exception.AccessDeniedException;
|
||||
import com.example.bankcards.exception.BadRequestException;
|
||||
import com.example.bankcards.exception.ResourceNotFoundException;
|
||||
import com.example.bankcards.repository.CardRepository;
|
||||
import com.example.bankcards.repository.UserRepository;
|
||||
import com.example.bankcards.util.CardEncryptionUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CardService {
|
||||
|
||||
private final CardRepository cardRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final CardEncryptionUtil encryptionUtil;
|
||||
|
||||
public CardResponse createCard(CreateCardRequest request) {
|
||||
User owner = userRepository
|
||||
.findById(request.getOwnerId())
|
||||
.orElseThrow(() ->
|
||||
new ResourceNotFoundException(
|
||||
"User not found: " + request.getOwnerId()
|
||||
)
|
||||
);
|
||||
|
||||
String encrypted = encryptionUtil.encrypt(request.getCardNumber());
|
||||
Card card = Card.builder()
|
||||
.cardNumberEncrypted(encrypted)
|
||||
.owner(owner)
|
||||
.expiryDate(request.getExpiryDate())
|
||||
.status(CardStatus.ACTIVE)
|
||||
.balance(request.getInitialBalance())
|
||||
.build();
|
||||
return toResponse(cardRepository.save(card));
|
||||
}
|
||||
|
||||
public Page<CardResponse> getAllCards(Pageable pageable) {
|
||||
return cardRepository.findAll(pageable).map(this::toResponse);
|
||||
}
|
||||
|
||||
public Page<CardResponse> getMyCards(
|
||||
String username,
|
||||
CardStatus status,
|
||||
Pageable pageable
|
||||
) {
|
||||
User user = userRepository
|
||||
.findByUsername(username)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("User not found"));
|
||||
if (status != null) {
|
||||
return cardRepository
|
||||
.findByOwnerIdAndStatus(user.getId(), status, pageable)
|
||||
.map(this::toResponse);
|
||||
}
|
||||
return cardRepository
|
||||
.findByOwnerId(user.getId(), pageable)
|
||||
.map(this::toResponse);
|
||||
}
|
||||
|
||||
public CardResponse getCard(Long id, String username, boolean isAdmin) {
|
||||
Card card = cardRepository
|
||||
.findById(id)
|
||||
.orElseThrow(() ->
|
||||
new ResourceNotFoundException("Card not found: " + id)
|
||||
);
|
||||
if (!isAdmin && !card.getOwner().getUsername().equals(username)) {
|
||||
throw new AccessDeniedException("Access denied");
|
||||
}
|
||||
return toResponse(card);
|
||||
}
|
||||
|
||||
public CardResponse blockCard(Long id) {
|
||||
Card card = cardRepository
|
||||
.findById(id)
|
||||
.orElseThrow(() ->
|
||||
new ResourceNotFoundException("Card not found: " + id)
|
||||
);
|
||||
card.setStatus(CardStatus.BLOCKED);
|
||||
return toResponse(cardRepository.save(card));
|
||||
}
|
||||
|
||||
public CardResponse activateCard(Long id) {
|
||||
Card card = cardRepository
|
||||
.findById(id)
|
||||
.orElseThrow(() ->
|
||||
new ResourceNotFoundException("Card not found: " + id)
|
||||
);
|
||||
card.setStatus(CardStatus.ACTIVE);
|
||||
return toResponse(cardRepository.save(card));
|
||||
}
|
||||
|
||||
public void deleteCard(Long id) {
|
||||
if (!cardRepository.existsById(id)) {
|
||||
throw new ResourceNotFoundException("Card not found: " + id);
|
||||
}
|
||||
cardRepository.deleteById(id);
|
||||
}
|
||||
|
||||
public void requestBlock(Long id, String username) {
|
||||
Card card = cardRepository
|
||||
.findById(id)
|
||||
.orElseThrow(() ->
|
||||
new ResourceNotFoundException("Card not found: " + id)
|
||||
);
|
||||
if (!card.getOwner().getUsername().equals(username)) {
|
||||
throw new AccessDeniedException("Access denied");
|
||||
}
|
||||
card.setStatus(CardStatus.BLOCKED);
|
||||
cardRepository.save(card);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void transfer(TransferRequest request, String username) {
|
||||
Card from = cardRepository
|
||||
.findById(request.getFromCardId())
|
||||
.orElseThrow(() ->
|
||||
new ResourceNotFoundException("Source card not found")
|
||||
);
|
||||
Card to = cardRepository
|
||||
.findById(request.getToCardId())
|
||||
.orElseThrow(() ->
|
||||
new ResourceNotFoundException("Destination card not found")
|
||||
);
|
||||
|
||||
if (!from.getOwner().getUsername().equals(username)) {
|
||||
throw new AccessDeniedException(
|
||||
"Source card does not belong to you"
|
||||
);
|
||||
}
|
||||
if (!to.getOwner().getUsername().equals(username)) {
|
||||
throw new AccessDeniedException(
|
||||
"Destination card does not belong to you"
|
||||
);
|
||||
}
|
||||
if (from.getStatus() != CardStatus.ACTIVE) {
|
||||
throw new BadRequestException("Source card is not active");
|
||||
}
|
||||
if (to.getStatus() != CardStatus.ACTIVE) {
|
||||
throw new BadRequestException("Destination card is not active");
|
||||
}
|
||||
if (from.getBalance().compareTo(request.getAmount()) < 0) {
|
||||
throw new BadRequestException("Insufficient balance");
|
||||
}
|
||||
|
||||
from.setBalance(from.getBalance().subtract(request.getAmount()));
|
||||
to.setBalance(to.getBalance().add(request.getAmount()));
|
||||
cardRepository.save(from);
|
||||
cardRepository.save(to);
|
||||
}
|
||||
|
||||
public CardResponse toResponse(Card card) {
|
||||
CardResponse response = new CardResponse();
|
||||
response.setId(card.getId());
|
||||
String decrypted = encryptionUtil.decrypt(
|
||||
card.getCardNumberEncrypted()
|
||||
);
|
||||
response.setMaskedNumber(encryptionUtil.mask(decrypted));
|
||||
response.setOwnerUsername(card.getOwner().getUsername());
|
||||
response.setExpiryDate(card.getExpiryDate());
|
||||
response.setStatus(card.getStatus());
|
||||
response.setBalance(card.getBalance());
|
||||
return response;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user