diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/InspectionObligationsPrecAction.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/InspectionObligationsPrecAction.java index c96b723c2..8a5752dc5 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/InspectionObligationsPrecAction.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/InspectionObligationsPrecAction.java @@ -94,12 +94,14 @@ public class InspectionObligationsPrecAction extends ReviseStage1Action { return Long.compare(minId1, minId2); }; - private BigDecimal changeBalance(Registry asset, BigDecimal amount, Instant now) { - asset.setBalance(BigDecimal.ZERO); + private void changeBalance(Registry asset, BigDecimal amount, Instant now) { + BigDecimal effectiveBalance = BigDecimalUtil.safeSumBD(asset.getBalance(), amount); + asset.setBalance(effectiveBalance); asset.setUpdated(now); - return BigDecimalUtil.safeSumBD(asset.getBalance(), amount); } + private static record RgsTrio(Registry am_t, Registry am_b, Registry dm_t) {} + private void inspectionObligations(StateContext ctx) { Instant now = Instant.now(); String sqlCondition = String.format("(%s) and registryStatus = '%s'", @@ -121,7 +123,7 @@ public class InspectionObligationsPrecAction extends ReviseStage1Action { ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder(); Consumer> setGroupStatus = (group) -> group .forEach(registry -> { - registry.setRegistryStatus(RegistryStatus.OK.getKey()); + registry.setRegistryStatus(RegistryStatus.PROC.getKey()); registry.setUpdated(now); registry.setSessionId(sessionId); registry.setSessionType(sessionType.getKey()); @@ -139,6 +141,7 @@ public class InspectionObligationsPrecAction extends ReviseStage1Action { errs.add(new RgsErr(registry, err)); }); + Map assetsByTcrAndSec = new HashMap<>(); for (Map.Entry> entry : registriesByGroupSorted) { List group = entry.getValue(); for (Registry rgs : group) { @@ -167,53 +170,60 @@ public class InspectionObligationsPrecAction extends ReviseStage1Action { Registry am_b = Optional.ofNullable( registryImdg.getFirstObjectByPredicate(am_bPrdct) ).orElseGet(() -> copyRgs(am_t, now, RegistryTradingParams.A__B)); - BigDecimal am_bOldBalance = am_b.getBalance(); RegistryDesignation designation = getEnumByKey(RegistryDesignation.class, rgs.getRegistryDesignation()); - BigDecimal am_bDelta; + //важно: за счет кэша AM_B по одним условиям выгружается как один и тот же + //java объект. по этой причине changeBalance срабатывают на одном объекте, + //хоть он и не писался в hazelcast. нам это важно для расчетов. if (designation.equals(RegistryDesignation.O)) { - am_bDelta = changeBalance(am_b, rgs.getBalance(), now); + changeBalance(am_b, rgs.getBalance(), now); } else { - am_bDelta = changeBalance(am_b, safeBD(rgs.getBalance()).negate(), now); + changeBalance(am_b, safeBD(rgs.getBalance()).negate(), now); } - rgssToStore.put(am_b.getId(), am_b); - Registry dm_t = registryImdg.getFirstObjectByPredicate(dm_tPrdct); - BigDecimal dm_tBalance = dm_t != null ? safeBD(dm_t.getBalance()) : BigDecimal.ZERO; - BigDecimal difference = am_t.getBalance() - .subtract(am_bDelta) - .subtract(dm_tBalance); - logChanges(entry, am_b, am_t, dm_t, rgs, am_bOldBalance, am_bDelta, difference); - - if (difference.compareTo(BigDecimal.ZERO) < 0) { - Registry pm_t = copyRgs(am_t, now, RegistryTradingParams.P___); - pm_t.setSessionId(sessionId); - pm_t.setSessionType(sessionType.getKey()); - pm_t.setBalance(difference); - rgssToStore.put(pm_t.getId(), pm_t); - } + PKey key = new PKey(am_t.getTradingClearingRegistryId(), am_t.getSecurityId()); + assetsByTcrAndSec.computeIfAbsent(key, k -> new RgsTrio(am_t, am_b, dm_t)); } setGroupStatus.accept(group); } + assetsByTcrAndSec.forEach((key, trio) -> { + Registry dm_t = trio.dm_t; + Registry am_t = trio.am_t; + Registry am_b = trio.am_b; + + BigDecimal dm_tBalance = dm_t != null ? safeBD(dm_t.getBalance()) : BigDecimal.ZERO; + + BigDecimal difference = am_t.getBalance() + .subtract(am_b.getBalance()) + .subtract(dm_tBalance); + logChanges(am_b, am_t, dm_t, difference); + am_b.setBalance(BigDecimal.ZERO); + rgssToStore.put(am_b.getId(), am_b); + if (difference.compareTo(BigDecimal.ZERO) >= 0) { + log.debug("tcr.id[{}], security.id[{}] - difference >= 0, skipping creating PM_T", key.tcrId, key.securityId); + return; + } + Registry newPm_t = copyRgs(am_t, now, P___); + newPm_t.setSessionId(sessionId); + newPm_t.setSessionType(sessionType.getKey()); + newPm_t.setBalance(BigDecimal.ZERO); + rgssToStore.put(newPm_t.getId(), newPm_t); + }); ctx.getExtendedState().getVariables().put(DataEnum.erroneousRegistries, errs); ctx.getExtendedState().getVariables().put(DataEnum.inspectionObligationStashedRgs, rgssToStore); } - private void logChanges(Map.Entry> entry, + private record PKey(Long tcrId, Long securityId) { + } + + private void logChanges( Registry am_b, Registry am_t, Registry dm_t, - Registry rgs, - BigDecimal am_bOldBalance, - BigDecimal am_bDelta, BigDecimal difference) { - log.debug("group id={}; {}.id={} found by {}.id={}: balance " + - "was changed from {} to {}; balance diff {}[{}] - {}[{}]* - {}[{}] = {}", - entry.getKey().groupId(), + log.debug("{}.id={}: balance " + + "was changed to {}; balance diff {}[{}] - {}[{}]* - {}[{}] = {}", am_b.getRegistryCode(), am_b.getId(), - rgs.getRegistryCode(), - rgs.getId(), - am_bOldBalance, am_b.getBalance(), am_t.getRegistryCode(), am_t.getId(), @@ -227,18 +237,22 @@ public class InspectionObligationsPrecAction extends ReviseStage1Action { } private Registry copyRgs(Registry rgs, Instant now, RegistryTradingParams params) { - Registry pm_t = rgs.clone(); - RegistryManager.zeroState(pm_t); + Registry newRgs = rgs.clone(); + RegistryManager.zeroState(newRgs); if (params.registryDesignation() != null) { - pm_t.setRegistryDesignation(params.registryDesignation().getKey()); + newRgs.setRegistryDesignation(params.registryDesignation().getKey()); } if (params.registryUnit() != null) { - pm_t.setRegistryUnit(params.registryUnit().getKey()); + newRgs.setRegistryUnit(params.registryUnit().getKey()); } - pm_t.setRegistryCode(RegistryUtil.clearingCode(pm_t)); - pm_t.setId(idGen.nextId()); - pm_t.setCreated(now); - log.debug("created {}.id={} by {}.id={}", pm_t.getRegistryCode(), pm_t.getId(), rgs.getRegistryCode(), rgs.getId()); - return pm_t; + newRgs.setRegistryCode(RegistryUtil.clearingCode(newRgs)); + newRgs.setId(idGen.nextId()); + newRgs.setCreated(now); + if (params.equalByParams(P___)) { + return newRgs; + } + registryImdg.insert(newRgs); + log.debug("created {}.id={} by {}.id={}", newRgs.getRegistryCode(), newRgs.getId(), rgs.getRegistryCode(), rgs.getId()); + return newRgs; } }