109 lines
4.4 KiB
Java
109 lines
4.4 KiB
Java
package com.goldenchart.service;
|
|
|
|
import com.goldenchart.dto.PaperLedgerEntryDto;
|
|
import com.goldenchart.dto.PaperPageDto;
|
|
import com.goldenchart.entity.GcPaperAccount;
|
|
import com.goldenchart.entity.GcPaperCashLedger;
|
|
import com.goldenchart.entity.GcPaperTrade;
|
|
import com.goldenchart.repository.GcPaperCashLedgerRepository;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.data.domain.Page;
|
|
import org.springframework.data.domain.PageRequest;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.time.LocalDateTime;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
@Transactional
|
|
public class PaperLedgerService {
|
|
|
|
public static final String INITIAL = "INITIAL";
|
|
public static final String BUY_SETTLE = "BUY_SETTLE";
|
|
public static final String SELL_SETTLE = "SELL_SETTLE";
|
|
public static final String RESET = "RESET";
|
|
|
|
private final GcPaperCashLedgerRepository ledgerRepo;
|
|
|
|
public void recordInitial(GcPaperAccount account, BigDecimal initialCash) {
|
|
ledgerRepo.save(GcPaperCashLedger.builder()
|
|
.accountId(account.getId())
|
|
.entryType(INITIAL)
|
|
.amount(initialCash)
|
|
.cashBefore(BigDecimal.ZERO)
|
|
.cashAfter(initialCash)
|
|
.build());
|
|
}
|
|
|
|
public void recordBuySettle(GcPaperAccount account, GcPaperTrade trade, BigDecimal totalCost) {
|
|
BigDecimal before = account.getCashBalance().add(totalCost);
|
|
ledgerRepo.save(GcPaperCashLedger.builder()
|
|
.accountId(account.getId())
|
|
.entryType(BUY_SETTLE)
|
|
.amount(totalCost.negate())
|
|
.cashBefore(before)
|
|
.cashAfter(account.getCashBalance())
|
|
.refTradeId(trade.getId())
|
|
.symbol(trade.getSymbol())
|
|
.build());
|
|
}
|
|
|
|
public void recordSellSettle(GcPaperAccount account, GcPaperTrade trade, BigDecimal netProceeds) {
|
|
BigDecimal before = account.getCashBalance().subtract(netProceeds);
|
|
ledgerRepo.save(GcPaperCashLedger.builder()
|
|
.accountId(account.getId())
|
|
.entryType(SELL_SETTLE)
|
|
.amount(netProceeds)
|
|
.cashBefore(before)
|
|
.cashAfter(account.getCashBalance())
|
|
.refTradeId(trade.getId())
|
|
.symbol(trade.getSymbol())
|
|
.build());
|
|
}
|
|
|
|
public void recordReset(GcPaperAccount account, BigDecimal cashBefore, BigDecimal newCash) {
|
|
ledgerRepo.save(GcPaperCashLedger.builder()
|
|
.accountId(account.getId())
|
|
.entryType(RESET)
|
|
.amount(newCash.subtract(cashBefore))
|
|
.cashBefore(cashBefore)
|
|
.cashAfter(newCash)
|
|
.build());
|
|
}
|
|
|
|
@Transactional(readOnly = true)
|
|
public PaperPageDto<PaperLedgerEntryDto> list(Long accountId, LocalDateTime from, LocalDateTime to,
|
|
int page, int size) {
|
|
PageRequest pr = PageRequest.of(Math.max(0, page), Math.min(100, Math.max(1, size)));
|
|
Page<GcPaperCashLedger> result = (from != null || to != null)
|
|
? ledgerRepo.findByAccountIdAndCreatedAtBetweenOrderByCreatedAtDesc(
|
|
accountId,
|
|
from != null ? from : LocalDateTime.of(2000, 1, 1, 0, 0),
|
|
to != null ? to : LocalDateTime.now().plusYears(10),
|
|
pr)
|
|
: ledgerRepo.findByAccountIdOrderByCreatedAtDesc(accountId, pr);
|
|
return PaperPageDto.<PaperLedgerEntryDto>builder()
|
|
.content(result.getContent().stream().map(this::toDto).toList())
|
|
.page(result.getNumber())
|
|
.size(result.getSize())
|
|
.totalElements(result.getTotalElements())
|
|
.totalPages(result.getTotalPages())
|
|
.build();
|
|
}
|
|
|
|
private PaperLedgerEntryDto toDto(GcPaperCashLedger e) {
|
|
return PaperLedgerEntryDto.builder()
|
|
.id(e.getId())
|
|
.entryType(e.getEntryType())
|
|
.amount(e.getAmount().doubleValue())
|
|
.cashBefore(e.getCashBefore().doubleValue())
|
|
.cashAfter(e.getCashAfter().doubleValue())
|
|
.refTradeId(e.getRefTradeId())
|
|
.symbol(e.getSymbol())
|
|
.createdAt(e.getCreatedAt() != null ? e.getCreatedAt().toString() : null)
|
|
.build();
|
|
}
|
|
}
|