package ru.soune.nocopy.controller; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import ru.soune.nocopy.dto.payout.*; import ru.soune.nocopy.entity.payout.BankTransferPayoutMethod; import ru.soune.nocopy.entity.payout.CardPayoutMethod; import ru.soune.nocopy.entity.payout.PayoutRequest; import ru.soune.nocopy.entity.payout.PayoutType; import ru.soune.nocopy.entity.user.AuthToken; import ru.soune.nocopy.entity.user.User; import ru.soune.nocopy.exception.NotFoundAuthToken; import ru.soune.nocopy.repository.AuthTokenRepository; import ru.soune.nocopy.service.payout.PayoutMethodService; import ru.soune.nocopy.service.payout.PayoutRequestService; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @RestController @RequestMapping("/api/payouts") @RequiredArgsConstructor @Slf4j public class PayoutController { private final PayoutRequestService payoutRequestService; private final PayoutMethodService payoutMethodService; private final AuthTokenRepository authTokenRepository; /* Create payout */ @PostMapping("/create-request") public ResponseEntity createPayoutRequest(@RequestHeader("Authorization") String tokenHeader, @Valid @RequestBody PayoutRequestDTO request) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); PayoutRequest payoutRequest = payoutRequestService.createPayoutRequest(user.getId(), request); return ResponseEntity.status(HttpStatus.CREATED).body(payoutRequest); } /* Completed payout */ @PostMapping("/requests/{requestId}/process") public ResponseEntity processPayoutRequest(@PathVariable Long requestId) { PayoutRequest processed = payoutRequestService.processRequest(requestId); return ResponseEntity.ok(processed); } /* Cancel payout */ @PostMapping("/requests/{requestId}/cancel") public ResponseEntity cancelPayoutRequest(@PathVariable Long requestId, @RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); PayoutRequest cancelled = payoutRequestService.cancelPayoutRequest(user.getId(), requestId); return ResponseEntity.ok(cancelled); } /* Get user payouts */ @GetMapping("/requests") public ResponseEntity> getUserRequests(@RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); return ResponseEntity.ok(payoutRequestService.getUserPayoutRequests(user.getId())); } /* Get payout by id */ @GetMapping("/requests/{requestId}") public ResponseEntity getPayoutRequest(@PathVariable Long requestId, @RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); return ResponseEntity.ok(payoutRequestService.getPayoutRequest(user.getId(), requestId)); } /* Get payout by id */ @GetMapping("user/payout-methods") public ResponseEntity> getUserMethods(@RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); return ResponseEntity.ok(payoutMethodService.getUserMethods(user.getId())); } /* Get payout-methods */ @GetMapping("/payout-methods") public ResponseEntity> getAvailableMethodTypes() { List types = Arrays.stream(PayoutType.values()) .map(type -> PayoutMethodTypeDTO.builder() .code(type.name()) .name(type.getDisplayName()) .build()) .collect(Collectors.toList()); return ResponseEntity.ok(types); } /* add card method by userId */ @PostMapping("/payout-method/card") public ResponseEntity addCardMethod(@Valid @RequestBody AddCardRequest request, @RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); CardPayoutMethod method = payoutMethodService.addCardMethod(user.getId(), request); return ResponseEntity.status(HttpStatus.CREATED) .body(payoutMethodService.convertToDto(method)); } /* add bank payout-method */ @PostMapping("/payout-method/bank-transfer") public ResponseEntity addBankTransferMethod(@Valid @RequestBody AddBankTransferRequest request, @RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); BankTransferPayoutMethod method = payoutMethodService.addBankTransferMethod(user.getId(), request); return ResponseEntity.status(HttpStatus.CREATED) .body(payoutMethodService.convertToDto(method)); } /* set default bank payout-method */ @PutMapping("/payout-method/{methodId}/default") public ResponseEntity setDefaultMethod(@PathVariable Long methodId, @RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); Optional tokenOptional = authTokenRepository.findByToken(token); AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found")); User user = authToken.getUser(); payoutMethodService.setDefaultMethod(user.getId(), methodId); return ResponseEntity.ok().build(); } }