From 17910bd22453f54b4c255e8accef67eeebb9d861 Mon Sep 17 00:00:00 2001 From: ialbert Date: Fri, 1 Dec 2023 19:04:18 +0300 Subject: [PATCH] http://jira.mfd.msk:8088/browse/CLS-328 --- .../clearing/service/RegistryService.java | 101 ++++++++++-------- .../service/registry/AssetTBFProcessing.java | 56 ++++++---- 2 files changed, 96 insertions(+), 61 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java index 1c799934f..89c5f0dac 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java @@ -54,6 +54,7 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; import java.util.stream.Stream; import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError; @@ -456,56 +457,70 @@ public class RegistryService { } + public record RgsKey (Long companyId, Long accountId, Long securityId) { + public static RgsKey fromRgs(Registry rgs) { + return new RgsKey(rgs.getCompanyId(), rgs.getAccountId(), rgs.getSecurityId()); + } + } + + private Optional find(List group, RegistryTradingParams rgsCode) { + List byCodeRes = group.stream() + .filter(rgs -> RegistryManager.equalsByCode(rgsCode, rgs)) + .toList(); + + if (byCodeRes.size() > 1) { + Optional any = group.stream().findFirst(); + if (any.isEmpty()) throw new IllegalStateException(); //never + String err = "FATAL: found %d entries by code %s in group %s".formatted( + byCodeRes.size(), + rgsCode, + RgsKey.fromRgs(any.get()).toString() + ); + throw new IllegalStateException(err); + } + return byCodeRes.stream().findFirst(); + } + public void resetBalances() { Collection registriesA = registryImdg.getCollectionObjectsByFieldValues(Map.of( "registryDesignation", RegistryDesignation.A.getKey()) ); - for (Registry registry : registriesA) { - if (RegistryUnit.B.equalsByKey(registry.getRegistryUnit())) { - registry.setBalance(BigDecimal.ZERO); - } - if (RegistryUnit.F.equalsByKey(registry.getRegistryUnit())) { - Optional registryBOptional = registriesA.stream().filter(rgs -> - rgs.getAccount() != null && rgs.getSecurityId() != null && - rgs.getTradingClearingRegistryId() != null && rgs.getCompanyId() != null && - RegistryUnit.B.equalsByKey(rgs.getRegistryUnit()) && - rgs.getSecurityId() != null && rgs.getSecurityId().equals(registry.getSecurityId()) && - rgs.getCompanyId() != null && rgs.getCompanyId().equals(registry.getCompanyId()) && - rgs.getAccount() != null && rgs.getAccount().equals(registry.getAccount()) && - rgs.getTradingClearingRegistryId() != null && rgs.getTradingClearingRegistryId().equals(registry.getTradingClearingRegistryId()) - ).findFirst(); - Optional registryTOptional = registriesA.stream().filter(rgs -> - rgs.getAccount() != null && rgs.getSecurityId() != null && - rgs.getTradingClearingRegistryId() != null && rgs.getCompanyId() != null && - RegistryUnit.T.equalsByKey(rgs.getRegistryUnit()) && - rgs.getSecurityId() != null && rgs.getSecurityId().equals(registry.getSecurityId()) && - rgs.getCompanyId() != null && rgs.getCompanyId().equals(registry.getCompanyId()) && - rgs.getAccount() != null && rgs.getAccount().equals(registry.getAccount()) && - rgs.getTradingClearingRegistryId() != null && rgs.getTradingClearingRegistryId().equals(registry.getTradingClearingRegistryId()) - ).findFirst(); - BigDecimal balanceB; - if (registryBOptional.isPresent()) { - balanceB = registryBOptional.get().getBalance(); - } else { - balanceB = BigDecimal.ZERO; - } - registryTOptional.ifPresent(rgsT -> registry.setBalance(rgsT.getBalance().subtract(balanceB))); - } - if (RegistryUnit.T.equalsByKey(registry.getRegistryUnit())) { - registry.setOpenBalance(registry.getBalance()); - } + Map> allAssets = registriesA + .stream() + .collect(Collectors.groupingBy(RgsKey::fromRgs)); - registry.setDebit(BigDecimal.ZERO); - registry.setSettledDebit(BigDecimal.ZERO); - registry.setCredit(BigDecimal.ZERO); - registry.setSettledCredit(BigDecimal.ZERO); - registry.setPlanBalance(BigDecimal.ZERO); - registry.setCloseBalance(registry.getBalance()); - - registry.setUpdated(Instant.now()); - registryImdg.update(registry); + Instant timestamp = Instant.now(); + for (Map.Entry> entry : allAssets.entrySet()) { + RgsKey key = entry.getKey(); + List group = entry.getValue(); + Registry a__f = find(group, RegistryTradingParams.A__F).orElse(null); + Registry a__t = find(group, RegistryTradingParams.A__F).orElse(null); + Registry a__b = find(group, RegistryTradingParams.A__F).orElse(null); + if (a__t == null) { + log.warn("registry group {}: no A**T registry found.", key); + continue; + } + BigDecimal a__tBalance = safeBD(a__t.getBalance()); + a__t.setOpenBalance(a__tBalance); + a__t.setCloseBalance(a__tBalance); + a__t.setCredit(BigDecimal.ZERO); + a__t.setDebit(BigDecimal.ZERO); + a__t.setSettledCredit(BigDecimal.ZERO); + a__t.setSettledDebit(BigDecimal.ZERO); + a__t.setUpdated(timestamp); + registryImdg.update(a__t); + if (a__f == null) { + a__f = assets.copy(a__t, RegistryUnit.F); + registryImdg.insert(a__f); + } + if (a__b != null) { + a__b.setBalance(BigDecimal.ZERO); + registryImdg.update(a__b); + } + assets.process(a__b, a__t, a__f, BigDecimal.ZERO); } + } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/registry/AssetTBFProcessing.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/registry/AssetTBFProcessing.java index 3b6a8b741..2f79bcd50 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/registry/AssetTBFProcessing.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/registry/AssetTBFProcessing.java @@ -45,34 +45,60 @@ public class AssetTBFProcessing { this.rgsMng = new RegistryManager(rgsImdg); } + //если нет B ссчитаем что он 0 + //если нет F надо его создать... + //если нет T журнал WARN и ничего не делаем + public Registry copy(Registry a__t, RegistryUnit rgsUnit) { + Registry a___ = a__t.clone(); + a___.setRegistryUnit(rgsUnit.getKey()); + a___.setRegistryCode(RegistryUtil.clearingCode(a___)); + RegistryManager.zeroState(a___); + return a___; + } + + /** + * пересчитывает A**F = A**T - A**B + D**I - D**V + * учитываются только D**I с отрицательным balance. + * @param am_b регистр блокированных средств + * @param am_t регистр средств под торги + * @param am_f регистр свободных средств + * @param sum отнимается от блокировки. + */ public void process(Registry am_b, Registry am_t, Registry am_f, BigDecimal sum) { + boolean am_bExists = am_b != null; + am_b = new Registry(); safeWrapField(am_t::getBalance, am_t::setBalance); safeWrapField(am_b::getBalance, am_b::setBalance); safeWrapField(am_f::getBalance, am_f::setBalance); - Collection d__is = searchByParams(am_b.getAccount(), - am_b.getSecuritySymbol(), - am_b.getCompanyId(), - D__I.type(am_b.getRegistryInstrumentType())); + Collection d__is = searchByParams(am_t.getAccount(), + am_t.getSecuritySymbol(), + am_t.getCompanyId(), + D__I.type(am_t.getRegistryInstrumentType())); BigDecimal d__iSum = d__is.stream() .filter(d__i -> safeBD(d__i.getBalance()).compareTo(BigDecimal.ZERO) < 0) .map(rgs -> safeBD(rgs.getBalance())) .reduce(BigDecimal.ZERO, BigDecimal::add); - Collection d__vs = searchByParams(am_b.getAccount(), - am_b.getSecuritySymbol(), - am_b.getCompanyId(), - D__V.type(am_b.getRegistryInstrumentType())); + Collection d__vs = searchByParams(am_t.getAccount(), + am_t.getSecuritySymbol(), + am_t.getCompanyId(), + D__V.type(am_t.getRegistryInstrumentType())); BigDecimal d__vSum = d__vs.stream() .map(rgs -> safeBD(rgs.getBalance())) .reduce(BigDecimal.ZERO, BigDecimal::add); Instant now = Instant.now(); BigDecimal am_fBalanceForLoging = am_f.getBalance(); BigDecimal am_bBalanceForLoging = am_b.getBalance(); + if (!am_bExists && sum != null && sum.compareTo(BigDecimal.ZERO) != 0) { + log.error("FATAL: A**F.id={}; A**T.id={} A**B is null, yet #sum={}", am_f.getId(), am_t.getId(), sum); + } am_b.setBalance(am_b.getBalance().subtract(sum)); am_f.setBalance(am_t.getBalance().subtract(am_b.getBalance()).add(d__iSum).subtract(d__vSum)); - am_b.setUpdated(now); + if (am_bExists) { + am_b.setUpdated(now); + rgsImdg.update(am_b); + } am_f.setUpdated(now); - rgsImdg.update(am_b); rgsImdg.update(am_f); log.debug("assets processing [{}#id={}#balance={} | {}#id={}#balance={} | {}#id={}#balance={}] " + "D**I.size={} D**V.size={}. {}.balance -> {}, {}.balance -> {}", @@ -182,14 +208,8 @@ public class AssetTBFProcessing { ast.setRegistryStatus(RegistryStatus.OK.getKey()); ast.setBalanceDimension(BalanceDimension.PICS.getKey()); RegistryManager.zeroState(ast); - Registry asf = ast.clone(); - asf.setRegistryUnit(RegistryUnit.F.getKey()); - asf.setRegistryCode(RegistryUtil.clearingCode(asf)); - RegistryManager.zeroState(asf); - Registry asb = ast.clone(); - asb.setRegistryUnit(RegistryUnit.B.getKey()); - asb.setRegistryCode(RegistryUtil.clearingCode(asb)); - RegistryManager.zeroState(asb); + Registry asf = copy(ast, RegistryUnit.F); + Registry asb = copy(ast, RegistryUnit.B); return new AssetTrio(asf, asb, ast); }