ialbert 2026-04-06 14:12:45 +03:00
parent 9702cf8467
commit 7614aa88ed

View file

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