ialbert 2023-12-01 19:04:18 +03:00
parent 02e2b3a3f2
commit 17910bd224
2 changed files with 96 additions and 61 deletions

View file

@ -54,6 +54,7 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError; 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<Registry> find(List<Registry> group, RegistryTradingParams rgsCode) {
List<Registry> byCodeRes = group.stream()
.filter(rgs -> RegistryManager.equalsByCode(rgsCode, rgs))
.toList();
if (byCodeRes.size() > 1) {
Optional<Registry> 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() { public void resetBalances() {
Collection<Registry> registriesA = registryImdg.getCollectionObjectsByFieldValues(Map.of( Collection<Registry> registriesA = registryImdg.getCollectionObjectsByFieldValues(Map.of(
"registryDesignation", RegistryDesignation.A.getKey()) "registryDesignation", RegistryDesignation.A.getKey())
); );
for (Registry registry : registriesA) { Map<RgsKey, List<Registry>> allAssets = registriesA
if (RegistryUnit.B.equalsByKey(registry.getRegistryUnit())) { .stream()
registry.setBalance(BigDecimal.ZERO); .collect(Collectors.groupingBy(RgsKey::fromRgs));
}
if (RegistryUnit.F.equalsByKey(registry.getRegistryUnit())) {
Optional<Registry> 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<Registry> 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());
}
registry.setDebit(BigDecimal.ZERO); Instant timestamp = Instant.now();
registry.setSettledDebit(BigDecimal.ZERO); for (Map.Entry<RgsKey, List<Registry>> entry : allAssets.entrySet()) {
registry.setCredit(BigDecimal.ZERO); RgsKey key = entry.getKey();
registry.setSettledCredit(BigDecimal.ZERO); List<Registry> group = entry.getValue();
registry.setPlanBalance(BigDecimal.ZERO); Registry a__f = find(group, RegistryTradingParams.A__F).orElse(null);
registry.setCloseBalance(registry.getBalance()); Registry a__t = find(group, RegistryTradingParams.A__F).orElse(null);
Registry a__b = find(group, RegistryTradingParams.A__F).orElse(null);
registry.setUpdated(Instant.now()); if (a__t == null) {
registryImdg.update(registry); 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);
} }
} }

View file

@ -45,34 +45,60 @@ public class AssetTBFProcessing {
this.rgsMng = new RegistryManager(rgsImdg); 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) { 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_t::getBalance, am_t::setBalance);
safeWrapField(am_b::getBalance, am_b::setBalance); safeWrapField(am_b::getBalance, am_b::setBalance);
safeWrapField(am_f::getBalance, am_f::setBalance); safeWrapField(am_f::getBalance, am_f::setBalance);
Collection<Registry> d__is = searchByParams(am_b.getAccount(), Collection<Registry> d__is = searchByParams(am_t.getAccount(),
am_b.getSecuritySymbol(), am_t.getSecuritySymbol(),
am_b.getCompanyId(), am_t.getCompanyId(),
D__I.type(am_b.getRegistryInstrumentType())); D__I.type(am_t.getRegistryInstrumentType()));
BigDecimal d__iSum = d__is.stream() BigDecimal d__iSum = d__is.stream()
.filter(d__i -> safeBD(d__i.getBalance()).compareTo(BigDecimal.ZERO) < 0) .filter(d__i -> safeBD(d__i.getBalance()).compareTo(BigDecimal.ZERO) < 0)
.map(rgs -> safeBD(rgs.getBalance())) .map(rgs -> safeBD(rgs.getBalance()))
.reduce(BigDecimal.ZERO, BigDecimal::add); .reduce(BigDecimal.ZERO, BigDecimal::add);
Collection<Registry> d__vs = searchByParams(am_b.getAccount(), Collection<Registry> d__vs = searchByParams(am_t.getAccount(),
am_b.getSecuritySymbol(), am_t.getSecuritySymbol(),
am_b.getCompanyId(), am_t.getCompanyId(),
D__V.type(am_b.getRegistryInstrumentType())); D__V.type(am_t.getRegistryInstrumentType()));
BigDecimal d__vSum = d__vs.stream() BigDecimal d__vSum = d__vs.stream()
.map(rgs -> safeBD(rgs.getBalance())) .map(rgs -> safeBD(rgs.getBalance()))
.reduce(BigDecimal.ZERO, BigDecimal::add); .reduce(BigDecimal.ZERO, BigDecimal::add);
Instant now = Instant.now(); Instant now = Instant.now();
BigDecimal am_fBalanceForLoging = am_f.getBalance(); BigDecimal am_fBalanceForLoging = am_f.getBalance();
BigDecimal am_bBalanceForLoging = am_b.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_b.setBalance(am_b.getBalance().subtract(sum));
am_f.setBalance(am_t.getBalance().subtract(am_b.getBalance()).add(d__iSum).subtract(d__vSum)); 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); am_f.setUpdated(now);
rgsImdg.update(am_b);
rgsImdg.update(am_f); rgsImdg.update(am_f);
log.debug("assets processing [{}#id={}#balance={} | {}#id={}#balance={} | {}#id={}#balance={}] " + log.debug("assets processing [{}#id={}#balance={} | {}#id={}#balance={} | {}#id={}#balance={}] " +
"D**I.size={} D**V.size={}. {}.balance -> {}, {}.balance -> {}", "D**I.size={} D**V.size={}. {}.balance -> {}, {}.balance -> {}",
@ -182,14 +208,8 @@ public class AssetTBFProcessing {
ast.setRegistryStatus(RegistryStatus.OK.getKey()); ast.setRegistryStatus(RegistryStatus.OK.getKey());
ast.setBalanceDimension(BalanceDimension.PICS.getKey()); ast.setBalanceDimension(BalanceDimension.PICS.getKey());
RegistryManager.zeroState(ast); RegistryManager.zeroState(ast);
Registry asf = ast.clone(); Registry asf = copy(ast, RegistryUnit.F);
asf.setRegistryUnit(RegistryUnit.F.getKey()); Registry asb = copy(ast, RegistryUnit.B);
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);
return new AssetTrio(asf, asb, ast); return new AssetTrio(asf, asb, ast);
} }