ialbert 2023-02-03 16:26:07 +03:00
parent e924df5be2
commit 12511a48e9
5 changed files with 165 additions and 22 deletions

View file

@ -19,6 +19,7 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.number.BigDecimalUtil;
import ru.spcex.platform.utils.validation.IValidator;
import java.math.BigDecimal;
@ -98,7 +99,7 @@ public class AccountBalanceService {
public void updateAccountBalanceByClearing(AccountBalanceClearingRequest req) {
ClearingCategory category = getClearingCategoryByCompanyId(req.getCompanyId());
req.setFirstLegAmount(safeBD(req.getFirstLegAmount()));
req.setFirstLegAmount(BigDecimalUtil.safeBD(req.getFirstLegAmount()));
if (category.equals(ClearingCategory.I)) {
updateAccountCategoryIClrn(req.getAccountId(), req.getCompanyId(), req.getFirstLegAmount());
updateAccountCategoryITran(req.getFirstLegAmount());
@ -120,9 +121,9 @@ public class AccountBalanceService {
private void updateAccountCategoryIClrn(Long accountId, Long companyId, BigDecimal firstLegAmount) {
AccountBalance accountBalance = loadAccountBalance(accountId, companyId, AccountType.Clrn);
log.trace("updating AccountBalance {} I CLRN", accountBalance.getId());
BigDecimal previousFreeBalanceAmount = safeBD(accountBalance.getFreeBalanceAmount());
BigDecimal previousChangeBalanceAmount = safeBD(accountBalance.getChangeBalanceAmount());
BigDecimal previousBalanceAmount = safeBD(accountBalance.getBalanceAmount());
BigDecimal previousFreeBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getFreeBalanceAmount());
BigDecimal previousChangeBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getChangeBalanceAmount());
BigDecimal previousBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getBalanceAmount());
accountBalance.setFreeBalanceAmount(previousFreeBalanceAmount.subtract(firstLegAmount));
accountBalance.setChangeBalanceAmount(previousChangeBalanceAmount.subtract(firstLegAmount));
accountBalance.setBalanceAmount(previousBalanceAmount.subtract(firstLegAmount));
@ -134,7 +135,7 @@ public class AccountBalanceService {
private void updateAccountCategoryITran(BigDecimal firstLegAmount) {
AccountBalance accountBalance = loadAccountBalance(AccountType.Tran);
log.trace("updating AccountBalance {} I TRAN", accountBalance.getId());
BigDecimal previousDebitAmount = safeBD(accountBalance.getDebitAmount());
BigDecimal previousDebitAmount = BigDecimalUtil.safeBD(accountBalance.getDebitAmount());
accountBalance.setDebitAmount(previousDebitAmount.add(firstLegAmount.abs()));
accountBalance.setUpdated(Instant.now());
log.trace("updateAccountCategoryITran: {}", accountBalance.getId());
@ -144,9 +145,9 @@ public class AccountBalanceService {
private void updateAccountCategoryVInfo(Long accountId, Long companyId, BigDecimal firstLegAmount) {
AccountBalance accountBalance = loadAccountBalance(accountId, companyId, AccountType.Info);
log.trace("updating AccountBalance {} V INFO", accountBalance.getId());
BigDecimal previousFreeBalanceAmount = safeBD(accountBalance.getFreeBalanceAmount());
BigDecimal changeBalanceAmount = safeBD(accountBalance.getChangeBalanceAmount());
BigDecimal balanceAmount = safeBD(accountBalance.getBalanceAmount());
BigDecimal previousFreeBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getFreeBalanceAmount());
BigDecimal changeBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getChangeBalanceAmount());
BigDecimal balanceAmount = BigDecimalUtil.safeBD(accountBalance.getBalanceAmount());
accountBalance.setFreeBalanceAmount(previousFreeBalanceAmount.subtract(firstLegAmount));
accountBalance.setChangeBalanceAmount(changeBalanceAmount.subtract(firstLegAmount));
accountBalance.setBalanceAmount(balanceAmount.subtract(firstLegAmount));
@ -158,9 +159,9 @@ public class AccountBalanceService {
private void updateAccountCategoryVAnlt(BigDecimal firstLegAmount) {
AccountBalance accountBalance = loadAccountBalance(AccountType.Anlt);
log.trace("updating AccountBalance {} V ANLT", accountBalance.getId());
BigDecimal previousFreeBalanceAmount = safeBD(accountBalance.getFreeBalanceAmount());
BigDecimal previousChangeBalanceAmount = safeBD(accountBalance.getChangeBalanceAmount());
BigDecimal previousBalanceAmount = safeBD(accountBalance.getBalanceAmount());
BigDecimal previousFreeBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getFreeBalanceAmount());
BigDecimal previousChangeBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getChangeBalanceAmount());
BigDecimal previousBalanceAmount = BigDecimalUtil.safeBD(accountBalance.getBalanceAmount());
accountBalance.setFreeBalanceAmount(previousFreeBalanceAmount.subtract(firstLegAmount));
accountBalance.setChangeBalanceAmount(previousChangeBalanceAmount.subtract(firstLegAmount));
accountBalance.setBalanceAmount(previousBalanceAmount.subtract(firstLegAmount));
@ -172,7 +173,7 @@ public class AccountBalanceService {
private void updateAccountCategoryBClrn(Long accountId, Long companyId, BigDecimal firstLegAmount) {
AccountBalance accountBalance = loadAccountBalance(accountId, companyId, AccountType.Clrn);
log.trace("updating AccountBalance {} B CLRN", accountBalance.getId());
BigDecimal debitAmount = safeBD(accountBalance.getDebitAmount());
BigDecimal debitAmount = BigDecimalUtil.safeBD(accountBalance.getDebitAmount());
accountBalance.setDebitAmount(plus(debitAmount, firstLegAmount.abs()));
accountBalance.setUpdated(Instant.now());
log.trace("updateAccountCategoryBClrn: {}", accountBalance.getId());
@ -192,8 +193,4 @@ public class AccountBalanceService {
"accountType", type.getKey())
);
}
private BigDecimal safeBD(BigDecimal bd) {
return bd == null ? BigDecimal.ZERO : bd;
}
}

View file

@ -7,12 +7,14 @@ import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney;
import ru.spcex.clearing.error.ClearingErrorInternal;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountBalanceClearingRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.builder.LiabilitiesClaimsAssetsCreator;
import ru.spcex.clearing.service.builder.LiabilitiesClaimsMoneyCreator;
import ru.spcex.clearing.service.builder.PaymentInstructionCreator;
import ru.spcex.clearing.service.order.ExecutionDepositSorter;
import ru.spcex.platform.enumeration.Allowed;
@ -33,6 +35,7 @@ public class Clearing {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<ExecutionDeposit> executionDepositImdg;
private final Imdg<LiabilitiesClaimsAssets> liabilitiesClaimsAssetsImdg;
private final Imdg<LiabilitiesClaimsMoney> liabilitiesClaimsMoneyImdg;
private final Imdg<ClearingMemberCategory> clearingCategoryImdg;
private final ExecutionDepositSorter sorter;
private final BiFunction<ClearingCategory, ExecutionDeposit, IValidator> validation;
@ -40,6 +43,8 @@ public class Clearing {
private final ImdgId idProvider;
private final KafkaSender kafka;
private final LiabilitiesClaimsAssetsCreator lbltsClmsAssetsCreator;
private final LiabilitiesClaimsMoneyCreator lbltsClmsMoneyCreator;
private Long lastAccBalanceResponseId = 0L;
//при прохождении по выгруженным ExecutionDeposit, ошибочные статусы проставляются для
//контр сделок. В таком случае, в коллекции хранятся не синхронизированные с IMDG ExecutionDeposit
@ -51,16 +56,18 @@ public class Clearing {
@Autowired
public Clearing(ImdgProvider imdgProvider,
ExecutionDepositSorter sorter, PaymentInstructionCreator paymentInstructionCreator,
BiFunction<ClearingCategory, ExecutionDeposit, IValidator> validation, KafkaSender kafka, LiabilitiesClaimsAssetsCreator liabilitiesClaimsAssetsCreator) {
BiFunction<ClearingCategory, ExecutionDeposit, IValidator> validation, KafkaSender kafka, LiabilitiesClaimsAssetsCreator liabilitiesClaimsAssetsCreator, LiabilitiesClaimsMoneyCreator lbltsClmsMoneyCreator) {
this.executionDepositImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
this.clearingCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.liabilitiesClaimsAssetsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsAssets, LiabilitiesClaimsAssets.class);
this.liabilitiesClaimsMoneyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsMoney, LiabilitiesClaimsMoney.class);
this.paymentInstructionCreator = paymentInstructionCreator;
this.idProvider = imdgProvider.getImdgIdGenerator();
this.sorter = sorter;
this.validation = validation;
this.kafka = kafka;
this.lbltsClmsAssetsCreator = liabilitiesClaimsAssetsCreator;
this.lbltsClmsMoneyCreator = lbltsClmsMoneyCreator;
}
public void startClearing() {
@ -165,8 +172,7 @@ public class Clearing {
Long sentRequestId = kafka.sendRequestToQueue(Consts.BALANCE_ACCOUNT_UPDATE, request);
log.trace("sent request to kafka, requestId: {}", sentRequestId);
try {
wait(5000);
//todo check that request Id was processed succesfully
wait(10000);
//если на этом месте произошла ошибка - непонятно как обрабатывать
//т.к. этом может быть уже вторая часть сделки, для первой accountBalance уже был обновлен
//либо вне зависимости от того какая часть сделки, accountBalance на самом деле мог быть
@ -181,9 +187,33 @@ public class Clearing {
continue;
}
}
LiabilitiesClaimsAssets liabilitiesClaimsAssets = lbltsClmsAssetsCreator.createLiabilitiesClaimsAssets(category, execDeposit);
liabilitiesClaimsAssetsImdg.insert(liabilitiesClaimsAssets);
log.trace("LiabilitiesClaimsAssets {} was created", liabilitiesClaimsAssets.getId());
LiabilitiesClaimsAssets lca = lbltsClmsAssetsCreator.createLiabilitiesClaimsAssets(category, execDeposit);
liabilitiesClaimsAssetsImdg.insert(lca);
log.trace("LiabilitiesClaimsAssets {} was created", lca.getId());
Optional<LiabilitiesClaimsMoney> lcmFirstLegFound = lbltsClmsMoneyCreator.searchLcmBySettlementDate(lca.getAccountId(), lca.getCompanyId(), lca.getSettlementDate());
var wrapperFirstLegCreated = new Object() {LiabilitiesClaimsMoney firstLegCreated;};
lcmFirstLegFound.ifPresentOrElse(lcm -> {
log.trace("LiabilitiesClaimsMoney first leg {} was found", lcm.getId());
lbltsClmsMoneyCreator.updateFirstLegLcm(lcm, lca, category);
liabilitiesClaimsMoneyImdg.update(lcm);
}, () -> {
LiabilitiesClaimsMoney lcmFirstLeg = lbltsClmsMoneyCreator.createFirstLegLcm(lca, category);
liabilitiesClaimsMoneyImdg.insert(lcmFirstLeg);
log.trace("LiabilitiesClaimsMoney first leg {} was created", lcmFirstLeg.getId());
wrapperFirstLegCreated.firstLegCreated = lcmFirstLeg;
});
Optional<LiabilitiesClaimsMoney> lcmSecondLegFound = lbltsClmsMoneyCreator.searchLcmByRefundDate(lca.getAccountId(), lca.getCompanyId(), lca.getRefundDate());
lcmSecondLegFound.ifPresentOrElse(lcm -> {
log.trace("LiabilitiesClaimsMoney second leg {} was found", lcm.getId());
lbltsClmsMoneyCreator.updateSecondLegLcm(lcm, lca, category);
liabilitiesClaimsMoneyImdg.update(lcm);
}, () -> {
LiabilitiesClaimsMoney lcmSecondLeg = lbltsClmsMoneyCreator.createSecondLegLcm(lca, category);
liabilitiesClaimsMoneyImdg.insert(lcmSecondLeg);
log.trace("LiabilitiesClaimsMoney second leg {} was created", lcmSecondLeg.getId());
});
lbltsClmsAssetsCreator.updateLca(lca, lcmFirstLegFound.orElse(wrapperFirstLegCreated.firstLegCreated));
liabilitiesClaimsAssetsImdg.update(lca);
}
}

View file

@ -6,6 +6,7 @@ import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ClearingCategory;
@ -66,4 +67,10 @@ public class LiabilitiesClaimsAssetsCreator {
liabilitiesClaimsAssets.setClearingDate(LocalDate.now());
return liabilitiesClaimsAssets;
}
public void updateLca(LiabilitiesClaimsAssets lca,
LiabilitiesClaimsMoney firstLeg) {
lca.setLiabilitiesClaimsMoneyId(firstLeg.getId());
lca.setUpdated(Instant.now());
}
}

View file

@ -0,0 +1,104 @@
package ru.spcex.clearing.service.builder;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.ClearingCategory;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Component
public class LiabilitiesClaimsMoneyCreator {
private final Imdg<LiabilitiesClaimsMoney> liabilitiesClaimsMoneyImdg;
private final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public LiabilitiesClaimsMoneyCreator(ImdgProvider imdgProvider) {
this.liabilitiesClaimsMoneyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsMoney, LiabilitiesClaimsMoney.class);
}
public Optional<LiabilitiesClaimsMoney> searchLcmBySettlementDate(Long accountId, Long companyId, LocalDate settlementDate) {
String sql = String.format("accountId=%d and companyId=%d and settlementDate=%s",
accountId, companyId, formatter.format(settlementDate));
LiabilitiesClaimsMoney liabilitiesClaimsMoney = liabilitiesClaimsMoneyImdg.getSingleObjectBySQL(sql);
return Optional.ofNullable(liabilitiesClaimsMoney);
}
public void updateFirstLegLcm(LiabilitiesClaimsMoney liabilitiesClaimsMoney,
LiabilitiesClaimsAssets liabilitiesClaimsAssets, ClearingCategory category) {
BigDecimal prevLAmount = safeBD(liabilitiesClaimsMoney.getLiabilitiesAmount());
BigDecimal prevClaimsAmount = safeBD(liabilitiesClaimsMoney.getClaimsAmount());
BigDecimal lcaLiabilitiesQuantity = safeBD(liabilitiesClaimsAssets.getLiabilitiesQuantity());
BigDecimal lcaClaimsQuantity = safeBD(liabilitiesClaimsAssets.getClaimsQuantity());
liabilitiesClaimsMoney.setLiabilitiesAmount(prevLAmount.add(lcaLiabilitiesQuantity));
liabilitiesClaimsMoney.setClaimsAmount(prevClaimsAmount.add(lcaClaimsQuantity));
}
public LiabilitiesClaimsMoney createFirstLegLcm(LiabilitiesClaimsAssets lca, ClearingCategory category) {
LiabilitiesClaimsMoney lcm = new LiabilitiesClaimsMoney();
lcm.setCompanyId(lca.getCompanyId());
lcm.setAccountId(lca.getAccountId());
lcm.setAccountType(lca.getAccountType());
lcm.setAccount(lca.getAccount());
if (category.equals(ClearingCategory.I) || category.equals(ClearingCategory.V)) {
lcm.setLiabilitiesAmount(lca.getLiabilitiesQuantity());
} else if (category.equals(ClearingCategory.B)) {
lcm.setClaimsAmount(lca.getClaimsQuantity());
}
lcm.setSettlementDate(lca.getSettlementDate());
lcm.setTradingDate(lca.getTradingDate());
lcm.setCurrency(lca.getCurrency());
lcm.setTradingCode(lca.getTradingCode());
lcm.setShortName(lca.getShortName());
lcm.setFullName(lca.getFullName());
lcm.setCreated(lca.getCreated());
lcm.setClearingDate(LocalDate.now());
return lcm;
}
public Optional<LiabilitiesClaimsMoney> searchLcmByRefundDate(Long accountId, Long companyId, LocalDate refundDate) {
String sql = String.format("accountId=%d and companyId=%d and settlementDate=%s",
accountId, companyId, formatter.format(refundDate));
LiabilitiesClaimsMoney liabilitiesClaimsMoney = liabilitiesClaimsMoneyImdg.getSingleObjectBySQL(sql);
return Optional.ofNullable(liabilitiesClaimsMoney);
}
public LiabilitiesClaimsMoney createSecondLegLcm(LiabilitiesClaimsAssets lca, ClearingCategory category) {
LiabilitiesClaimsMoney lcm = new LiabilitiesClaimsMoney();
lcm.setCompanyId(lca.getCompanyId());
lcm.setAccountId(lca.getAccountId());
lcm.setAccountType(lca.getAccountType());
lcm.setAccount(lca.getAccount());
if (category.equals(ClearingCategory.I) || category.equals(ClearingCategory.V)) {
lcm.setClaimsAmount(lca.getClaimsQuantity());
} else if (category.equals(ClearingCategory.B)) {
lcm.setLiabilitiesAmount(lca.getLiabilitiesQuantity());
}
lcm.setSettlementDate(lca.getRefundDate());
lcm.setTradingDate(lca.getTradingDate());
lcm.setCurrency(lca.getCurrency());
lcm.setTradingCode(lca.getTradingCode());
lcm.setShortName(lca.getShortName());
lcm.setFullName(lca.getFullName());
lcm.setCreated(lca.getCreated());
lcm.setClearingDate(lca.getRefundDate());
return lcm;
}
public void updateSecondLegLcm(LiabilitiesClaimsMoney lcm, LiabilitiesClaimsAssets lca, ClearingCategory category) {
BigDecimal prevLiabilitiesAmount = safeBD(lcm.getLiabilitiesAmount());
BigDecimal prevClaimsAmount = safeBD(lcm.getClaimsAmount());
BigDecimal lcaLiabilitiesQuantity = safeBD(lca.getLiabilitiesQuantity());
BigDecimal lcaClaimsQuantity = safeBD(lca.getClaimsQuantity());
lcm.setLiabilitiesAmount(prevLiabilitiesAmount.add(lcaLiabilitiesQuantity));
lcm.setClaimsAmount(prevClaimsAmount.add(lcaClaimsQuantity));
}
}

View file

@ -17,4 +17,9 @@ public class BigDecimalUtil {
return null;
}
}
public static BigDecimal safeBD(BigDecimal bd) {
return bd == null ? BigDecimal.ZERO : bd;
}
}