Added better currency and exchange information.
This commit is contained in:
parent
c643475f45
commit
5ffe9b3a84
|
@ -5,6 +5,9 @@ import lombok.Getter;
|
|||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -31,5 +34,11 @@ public class Account {
|
|||
@OneToMany(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private Set<Balance> balances;
|
||||
|
||||
|
||||
public Map<Currency, BigDecimal> getMappedBalances() {
|
||||
Map<Currency, BigDecimal> b = new HashMap<>();
|
||||
for (var bal : getBalances()) {
|
||||
b.put(bal.getCurrency(), bal.getAmount());
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,6 @@ public class Balance {
|
|||
@ManyToOne(optional = false, fetch = FetchType.EAGER)
|
||||
private Currency currency;
|
||||
|
||||
@Column(nullable = false, precision = 24, scale = 4)
|
||||
@Column(nullable = false, precision = 24, scale = 10)
|
||||
private BigDecimal amount;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package nl.andrewl.coyotecredit.model;
|
|||
import lombok.Getter;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a type of currency. This can be an actual fiat currency, or
|
||||
|
@ -10,6 +11,7 @@ import javax.persistence.*;
|
|||
* exchange.
|
||||
*/
|
||||
@Entity
|
||||
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"identifier", "type"}))
|
||||
@Getter
|
||||
public class Currency {
|
||||
@Id
|
||||
|
@ -19,9 +21,28 @@ public class Currency {
|
|||
@Column(nullable = false)
|
||||
private String identifier;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private CurrencyType type;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column
|
||||
private String description;
|
||||
|
||||
@Column(nullable = false)
|
||||
private float minDenomination = 0.01f;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof Currency c)) return false;
|
||||
if (c.getId() != null && this.getId() != null) return this.getId().equals(c.getId());
|
||||
return this.identifier.equals(c.getIdentifier()) &&
|
||||
this.type.equals(c.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.identifier, this.type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package nl.andrewl.coyotecredit.model;
|
||||
|
||||
public enum CurrencyType {
|
||||
FIAT,
|
||||
CRYPTO,
|
||||
STOCK
|
||||
}
|
|
@ -3,6 +3,7 @@ package nl.andrewl.coyotecredit.model;
|
|||
import lombok.Getter;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -21,11 +22,15 @@ public class Exchange {
|
|||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@JoinTable(
|
||||
name = "exchange_supported_currency",
|
||||
joinColumns = @JoinColumn(name = "currency_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "exchange_id")
|
||||
)
|
||||
private Set<Currency> supportedCurrencies;
|
||||
@OneToMany(mappedBy = "exchange")
|
||||
private Set<ExchangePair> currencyPairs;
|
||||
|
||||
public Set<Currency> getSupportedCurrencies() {
|
||||
Set<Currency> currencies = new HashSet<>();
|
||||
for (var pair : getCurrencyPairs()) {
|
||||
currencies.add(pair.getFromCurrency());
|
||||
currencies.add(pair.getToCurrency());
|
||||
}
|
||||
return currencies;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package nl.andrewl.coyotecredit.model;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Represents a pair of currencies that can be exchanged at a set exchange rate.
|
||||
*/
|
||||
@Entity
|
||||
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"from_currency_id", "to_currency_id", "exchange_id"}))
|
||||
@Getter
|
||||
public class ExchangePair {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
private Exchange exchange;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
private Currency fromCurrency;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
private Currency toCurrency;
|
||||
|
||||
@Column(nullable = false, precision = 24, scale = 10)
|
||||
private BigDecimal exchangeRate = new BigDecimal("1.0");
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package nl.andrewl.coyotecredit.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import nl.andrewl.coyotecredit.dao.AccountRepository;
|
||||
import nl.andrewl.coyotecredit.model.Account;
|
||||
|
@ -9,6 +10,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
|
@ -29,13 +31,36 @@ public class AccountService {
|
|||
.toList();
|
||||
}
|
||||
|
||||
public static class FullAccountData {
|
||||
public long id;
|
||||
public String number;
|
||||
public String exchangeName;
|
||||
public List<BalanceData> balances;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class BalanceData {
|
||||
public String currencyIdentifier;
|
||||
public String amount;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public AccountData getAccountData(User user, long accountId) {
|
||||
public FullAccountData getAccountData(User user, long accountId) {
|
||||
Account account = accountRepository.findById(accountId)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
|
||||
if (!account.getUser().getId().equals(user.getId())) {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
return new AccountData(account.getId(), account.getNumber(), account.getExchange().getName());
|
||||
FullAccountData d = new FullAccountData();
|
||||
d.id = account.getId();
|
||||
d.number = account.getNumber();
|
||||
d.exchangeName = account.getExchange().getName();
|
||||
List<BalanceData> balanceData = new ArrayList<>();
|
||||
for (var bal : account.getBalances()) {
|
||||
balanceData.add(new BalanceData(bal.getCurrency().getIdentifier(), bal.getAmount().toPlainString()));
|
||||
}
|
||||
d.balances = balanceData;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html
|
||||
lang="en"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
>
|
||||
<head>
|
||||
<title>CC - Account</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Account <span th:text="${account.number}"></span></h1>
|
||||
|
||||
<h3>Balance</h3>
|
||||
<ul>
|
||||
<li th:each="balance : ${account.balances}">
|
||||
<span th:text="${balance.currencyIdentifier}"></span> - <span th:text="${balance.amount}"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
Loading…
Reference in New Issue