From 12511a48e95cb38971e082944779375075092f8b Mon Sep 17 00:00:00 2001 From: ialbert Date: Fri, 3 Feb 2023 16:26:07 +0300 Subject: [PATCH] http://jira.mfd.msk:8088/browse/CLS-189 --- .../service/AccountBalanceService.java | 29 +++-- .../ru/spcex/clearing/service/Clearing.java | 42 ++++++- .../LiabilitiesClaimsAssetsCreator.java | 7 ++ .../LiabilitiesClaimsMoneyCreator.java | 104 ++++++++++++++++++ .../platform/utils/number/BigDecimalUtil.java | 5 + 5 files changed, 165 insertions(+), 22 deletions(-) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsMoneyCreator.java diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/AccountBalanceService.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/AccountBalanceService.java index c74026395..087df3786 100644 --- a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/AccountBalanceService.java +++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/AccountBalanceService.java @@ -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; - } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java index 4381680ea..a061ed233 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java @@ -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 executionDepositImdg; private final Imdg liabilitiesClaimsAssetsImdg; + private final Imdg liabilitiesClaimsMoneyImdg; private final Imdg clearingCategoryImdg; private final ExecutionDepositSorter sorter; private final BiFunction 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 validation, KafkaSender kafka, LiabilitiesClaimsAssetsCreator liabilitiesClaimsAssetsCreator) { + BiFunction 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 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 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); } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsAssetsCreator.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsAssetsCreator.java index cf4bcd74b..85876ea63 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsAssetsCreator.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsAssetsCreator.java @@ -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()); + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsMoneyCreator.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsMoneyCreator.java new file mode 100644 index 000000000..f6fd17c5c --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/LiabilitiesClaimsMoneyCreator.java @@ -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 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 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 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)); + } +} diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/number/BigDecimalUtil.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/number/BigDecimalUtil.java index b30f30f12..c458709f9 100644 --- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/number/BigDecimalUtil.java +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/number/BigDecimalUtil.java @@ -17,4 +17,9 @@ public class BigDecimalUtil { return null; } } + + public static BigDecimal safeBD(BigDecimal bd) { + return bd == null ? BigDecimal.ZERO : bd; + } + }