PortfolioTransactionController.java

package com.tdmconsult.ete.api;

import com.tdmconsult.ete.transactions.PortfolioTransactionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.net.URI;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
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;

@Tag(name = "NAme", description = "Description")
@RestController
@RequestMapping(value = "/api/transactions", produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
@PreAuthorize("hasRole('ete_admin')")
public class PortfolioTransactionController {

    private final PortfolioTransactionService portfolioTransactionService;
    
    public record BuyRequestDto(
        LocalDate tradingDate,
        String assetPublicId,
        long quantity,
        @Nullable Long principleAmountCents,
        long totalCostCents,
        @Nullable String documentPublicId) {
    }

    @PostMapping("buy")
    @Operation(summary = "buy an equity")
    public ResponseEntity<Void> buy(final @RequestBody BuyRequestDto request) {

        final var publicId = portfolioTransactionService.buy(request);
        return ResponseEntity.created(URI.create(publicId)).build();
    }
    
    public record SellRequestDto(
         LocalDate tradingDate,
         String assetIsin,
         long quantity,
         Long principleAmountCents,
         long totalCostCents) {
    }

    @PostMapping("sell")
    @Operation(summary = "sell an equity")
    public ResponseEntity<Void> sell(final @RequestBody SellRequestDto request) {

        final var publicId = portfolioTransactionService.sell(request);
        return ResponseEntity.created(URI.create(publicId)).build();
    }
    
    public record PaymentCaptureRequestDto(

        @NotNull
        String typeOfPayment,
        @NotNull
        LocalDate tradingDate,
        @NotNull
        String assetIsin,
        long quantity,

        @NotNull
        BigDecimal grossAmount,
        @NotNull
        BigDecimal netAmount,

        BigDecimal dividendPerShare,
        BigDecimal exchangeRate,
        BigDecimal domesticCapitalGainTax,
        BigDecimal domesticCapitalGainAddOn,
        BigDecimal foreignWithholdingTax) {
    }

    @PostMapping("payment")
    @Operation(summary = "capture a payment")
    public ResponseEntity<Void> payment(final @RequestBody @Validated PaymentCaptureRequestDto request) {

        final var publicId = portfolioTransactionService.payment(request);
        return ResponseEntity.created(URI.create(publicId)).build();
    }

}