Skip to content

Commit

Permalink
fix npe warns for TradePof
Browse files Browse the repository at this point in the history
  • Loading branch information
vananiev committed Jan 4, 2024
1 parent 774e2b5 commit 5390adf
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 33 deletions.
9 changes: 5 additions & 4 deletions src/main/java/ru/investbook/openformat/OpenFormatHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@

package ru.investbook.openformat;

import org.springframework.util.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.Objects;

import static org.springframework.util.StringUtils.hasLength;
import static ru.investbook.entity.SecurityEntity.isinPattern;

public class OpenFormatHelper {

public static String getValidCurrencyOrNull(String currency) {
public static @Nullable String getValidCurrencyOrNull(@Nullable String currency) {
if (currency == null) return null;
currency = currency.toUpperCase();
return Objects.equals(currency, "RUR") ? "RUB" : currency;
}

public static String getValidIsinOrNull(String isin) {
return StringUtils.hasLength(isin) && isinPattern.matcher(isin).matches() ?
public static @Nullable String getValidIsinOrNull(@Nullable String isin) {
return hasLength(isin) && isinPattern.matcher(isin).matches() ?
isin :
null;
}
Expand Down
60 changes: 31 additions & 29 deletions src/main/java/ru/investbook/openformat/v1_1_0/TradePof.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,18 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spacious_team.broker.pojo.SecurityType;
import org.spacious_team.broker.report_parser.api.AbstractTransaction;
import org.spacious_team.broker.report_parser.api.DerivativeTransaction;
import org.spacious_team.broker.report_parser.api.ForeignExchangeTransaction;
import org.spacious_team.broker.report_parser.api.SecurityTransaction;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.util.Assert;
import ru.investbook.entity.SecurityEventCashFlowEntity;
import ru.investbook.entity.TransactionCashFlowEntity;
Expand All @@ -60,33 +59,32 @@
@Slf4j
public class TradePof {

@NotNull
@JsonProperty("id")
int id;

@NotEmpty
@JsonProperty("trade-id")
@NotEmpty
String tradeId;

/**
* Дата и время сделки.
* Если значение null, то значение поля settlement обязательно
*/
@Nullable
@JsonProperty("timestamp")
@Nullable
Long timestamp;

/**
* Дата и время поставки.
* Если значение null, то значение поля timestamp обязательно
*/
@Nullable
@JsonProperty("settlement")
@Nullable
Long settlement;

@NotNull
@JsonProperty("account")
int account;

@NotNull
@Getter(AccessLevel.NONE)
@JsonProperty("asset")
int asset;
Expand All @@ -95,45 +93,48 @@ public class TradePof {
* Если '+', то это покупка, если '-', то это продажа.
* Поддерживаются дробные акции
*/
@NotNull
@JsonProperty("count")
BigDecimal count;

/**
* В валюте сделки, для облигации - без НКД, для деривативов в валюте - опционально
* Цена бумаги/контракта (за единицу) в валюте сделки,
* для облигации - без учета НКД, для деривативов поле может отсутствовать
*/
@Nullable
@JsonProperty("price")
@Nullable
BigDecimal price;

@Nullable
@JsonProperty("accrued-interest")
@Nullable
BigDecimal accruedInterest;

/**
* Котировка. Для облигации в процентах, для деривативов в пунктах
* Котировка. Для облигации в процентах, для деривативов в пунктах.
* Для деривативов - обязательное поле, для облигаций - опциональное.
*/
@Nullable
@JsonProperty("quote")
@Nullable
BigDecimal quote;

@Nullable
/**
* Может отсутствовать, если поле 'price' и 'accrued-interest' отсутствуют
*/
@JsonProperty("currency")
@Nullable
String currency;

/**
* Комиссия. Если отрицательное значение, значит возврат комиссии
*/
@NotNull
@JsonProperty("fee")
BigDecimal fee;

@NotEmpty
@JsonProperty("fee-currency")
@NotEmpty
String feeCurrency;

@Nullable
@JsonProperty("description")
@Nullable
String description;

static TradePof of(TransactionEntity transaction,
Expand Down Expand Up @@ -165,8 +166,8 @@ static TradePof of(TransactionEntity transaction,
.filter(e -> e.getCashFlowType().getId() == FEE.getId())
.findAny()
.ifPresentOrElse(e -> builder
.fee(e.getValue().negate())
.feeCurrency(getValidCurrencyOrNull(e.getCurrency())),
.fee(e.getValue().negate())
.feeCurrency(requireNonNull(getValidCurrencyOrNull(e.getCurrency()))),
() -> builder.fee(BigDecimal.ZERO).feeCurrency("RUB"));
return builder.build();
}
Expand Down Expand Up @@ -204,18 +205,19 @@ Optional<AbstractTransaction> toTransaction(Map<Integer, String> accountToPortfo
Map<Integer, SecurityType> assetTypes) {
try {
SecurityType securityType = requireNonNull(assetTypes.get(asset));
@Nullable BigDecimal value = (price == null) ? null : price.multiply(count).negate();
AbstractTransaction.AbstractTransactionBuilder<?, ?> builder = switch (securityType) {
case STOCK, BOND, STOCK_OR_BOND, ASSET -> SecurityTransaction.builder()
.value(requireNonNull(price).multiply(count).negate())
.value(requireNonNull(value))
.accruedInterest((accruedInterest == null) ? null : accruedInterest.multiply(count).negate())
.valueCurrency(getValidCurrencyOrNull(requireNonNull(currency)));
.valueCurrency(requireNonNull(getValidCurrencyOrNull(currency)));
case DERIVATIVE -> DerivativeTransaction.builder()
.valueInPoints(requireNonNull(quote).multiply(count).negate())
.value((price == null) ? null : price.multiply(count).negate()) // для деривативов - опциональное
.valueCurrency(getValidCurrencyOrNull(currency)); // для деривативов - опциональное
.valueInPoints(requireNonNull(quote).multiply(count).negate())
.value(value) // для деривативов - опциональное
.valueCurrency(getValidCurrencyOrNull(currency)); // для деривативов - опциональное
case CURRENCY_PAIR -> ForeignExchangeTransaction.builder()
.value(requireNonNull(price).multiply(count).negate())
.valueCurrency(getValidCurrencyOrNull(requireNonNull(currency)));
.value(requireNonNull(value))
.valueCurrency(requireNonNull(getValidCurrencyOrNull(currency)));
};

long ts = requireNonNull(getSettlementOrTimestamp());
Expand All @@ -225,8 +227,8 @@ Optional<AbstractTransaction> toTransaction(Map<Integer, String> accountToPortfo
.security(getSecurityId(assetToSecurityId))
.count(count.intValueExact())
.timestamp(Instant.ofEpochSecond(ts))
.fee((fee == null) ? null : fee.negate())
.feeCurrency(getValidCurrencyOrNull(feeCurrency))
.fee(fee.negate())
.feeCurrency(requireNonNull(getValidCurrencyOrNull(feeCurrency)))
.build());
} catch (Exception e) {
log.error("Не могу распарсить {}", this, e);
Expand Down

0 comments on commit 5390adf

Please sign in to comment.