currency session step 7 (paymentInstructions) - statements and assets
This commit is contained in:
parent
20bd9a0bb5
commit
11684bf923
1 changed files with 147 additions and 8 deletions
|
|
@ -2,12 +2,16 @@ package ru.spcex.clearing.session.stage.impl;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -17,11 +21,13 @@ import org.springframework.context.annotation.Scope;
|
|||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.SettlementHouseProperties;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.sdf.SDf03;
|
||||
import ru.clearing.classes.statics.data.sdf.SDf12;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.clearing.classes.statics.data.statement.Statement;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
|
|
@ -30,23 +36,28 @@ import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterR
|
|||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.service.Sdf03Creator;
|
||||
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2;
|
||||
import ru.spcex.clearing.service.registry.AssetTBFProcessing;
|
||||
import ru.spcex.clearing.service.registry.PaymentStateMarkService;
|
||||
import ru.spcex.clearing.service.registry.RegistryManager;
|
||||
import ru.spcex.clearing.session.stage.ISessionStage;
|
||||
import ru.spcex.clearing.session.stage.StageResult;
|
||||
import ru.spcex.clearing.session.stage.Task;
|
||||
import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionPayload;
|
||||
import ru.spcex.clearing.session.stage.util.RegistryUtil;
|
||||
import ru.spcex.platform.enumeration.AccountStatus;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.Allowed;
|
||||
import ru.spcex.platform.enumeration.InstrumentType;
|
||||
import ru.spcex.platform.enumeration.OperationStatus;
|
||||
import ru.spcex.platform.enumeration.RegistryDesignation;
|
||||
import ru.spcex.platform.enumeration.RegistryStatus;
|
||||
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
|
||||
import ru.spcex.platform.enumeration.RegistryUnit;
|
||||
import ru.spcex.platform.enumeration.SdfTable;
|
||||
import ru.spcex.platform.enumeration.Section;
|
||||
import ru.spcex.platform.enumeration.Sender;
|
||||
import ru.spcex.platform.enumeration.SessionType;
|
||||
import ru.spcex.platform.enumeration.StatementType;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgId;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
|
@ -54,12 +65,14 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
|||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
|
||||
import ru.spcex.platform.utils.collection.Pair;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
|
||||
import ru.spcex.platform.utils.number.BigDecimalUtil;
|
||||
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
|
||||
import ru.spcex.platform.utils.text.TextUtil;
|
||||
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
|
|
@ -69,12 +82,14 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
private ImdgProvider imdgProvider;
|
||||
private ImdgId idGenerator;
|
||||
private Imdg<Registry> registryImdg;
|
||||
private Imdg<Statement> stmtImdg;
|
||||
private Imdg<PaymentInstruction> paymentInstructionImdg;
|
||||
private Imdg<Security> securityImdg;
|
||||
private Imdg<Account> accountImdg;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<SDf03> sDf03Imdg;
|
||||
private Imdg<SDf12> sDf12Imdg;
|
||||
private Imdg<SettlementHouseProperties> stlmHPropsImdg;
|
||||
private final Sdf03Creator sdf03Creator;
|
||||
private KafkaSender kafkaSender;
|
||||
private final IMessageResolver msgResolver = new SimpleMessageResolver();
|
||||
|
|
@ -83,10 +98,11 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
private Section section;
|
||||
private SessionType sessionType;
|
||||
private final PaymentStateMarkService dmvSrv;
|
||||
private final AssetTBFProcessing assets;
|
||||
|
||||
@Autowired
|
||||
public FormingPaymentInstructionAssets(ImdgProvider imdgProvider,
|
||||
Sdf03Creator sdf03Creator, KafkaSender kafkaSender, RegistryManager rgsMng, PaymentStateMarkService dmvSrv) {
|
||||
Sdf03Creator sdf03Creator, KafkaSender kafkaSender, RegistryManager rgsMng, PaymentStateMarkService dmvSrv, AssetTBFProcessing assets) {
|
||||
this.sdf03Creator = sdf03Creator;
|
||||
this.kafkaSender = kafkaSender;
|
||||
this.imdgProvider = imdgProvider;
|
||||
|
|
@ -98,9 +114,12 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class);
|
||||
this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class);
|
||||
this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
||||
this.stlmHPropsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SettlementHouseProperties, SettlementHouseProperties.class);
|
||||
this.stmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
|
||||
this.rgsMng = rgsMng;
|
||||
this.securitySelector = new SecuritySelector<>(imdgProvider, Security.class);
|
||||
this.dmvSrv = dmvSrv;
|
||||
this.assets = assets;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -157,7 +176,7 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
false);
|
||||
}
|
||||
|
||||
List<PaymentInstruction> paymentInstructions = new ArrayList<>();
|
||||
List<Pair<PaymentInstruction, Registry>> paymentInstructions = new ArrayList<>();
|
||||
for (Registry registry : AMBregistries) {
|
||||
Account tranAcc = accountImdg.getFirstObjectBySQL(("accountType = '%s' " +
|
||||
"and status = '%s' " +
|
||||
|
|
@ -244,7 +263,7 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
registry.setPaymentId(paymentInstruction.getId());
|
||||
registry.setUpdated(now);
|
||||
registryImdg.update(registry);
|
||||
paymentInstructions.add(paymentInstruction);
|
||||
paymentInstructions.add(new Pair<>(paymentInstruction, registry));
|
||||
}
|
||||
if (section == null || !section.equals(Section.MKR)) {
|
||||
Collection<Registry> ASBregistries = selectASBRegistries(sessionId);
|
||||
|
|
@ -314,21 +333,22 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
registry.setPaymentId(paymentInstruction.getId());
|
||||
registry.setUpdated(now);
|
||||
registryImdg.update(registry);
|
||||
paymentInstructions.add(paymentInstruction);
|
||||
paymentInstructions.add(new Pair<>(paymentInstruction, registry));
|
||||
}
|
||||
}
|
||||
if (payload.getPaymentInstructionReturns().size() > 0) {
|
||||
log.debug("PaymentInstructions return size {}, PaymentInstructions deals size {}. sending SDF03",
|
||||
payload.getPaymentInstructionReturns().size(),
|
||||
paymentInstructions.size());
|
||||
paymentInstructions = Stream.concat(payload.getPaymentInstructionReturns().stream(),
|
||||
paymentInstructions = Stream.concat(payload.getPaymentInstructionReturns().stream()
|
||||
.map(p -> new Pair<PaymentInstruction, Registry>(p, null)),
|
||||
paymentInstructions.stream()).toList();
|
||||
}
|
||||
|
||||
|
||||
Collection<SdfTable> sdfTables = sendSdfs(paymentInstructions, sessionId, dtrnAcc);
|
||||
StageResult<PaymentInfo> stageResult = new StageResult<>(null, true);
|
||||
stageResult.setStageResult(new PaymentInfo(paymentInstructions, sdfTables));
|
||||
stageResult.setStageResult(new PaymentInfo(paymentInstructions.stream().map(Pair::getFirst).toList(), sdfTables));
|
||||
return stageResult;
|
||||
}
|
||||
|
||||
|
|
@ -373,13 +393,20 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
registryImdg.update(rgs);
|
||||
}
|
||||
|
||||
private Collection<SdfTable> sendSdfs(List<PaymentInstruction> formedPaymentInstructions, Long sessionId, Account dtrnAcc) {
|
||||
private Collection<SdfTable> sendSdfs(List<Pair<PaymentInstruction, Registry>> formedPaymentInstructions, Long sessionId, Account dtrnAcc) {
|
||||
Collection<SdfTable> sentSdfs = new ArrayList<>();
|
||||
List<SDf03> sDf03Created = new ArrayList<>();
|
||||
List<SDf12> sDf12Created = new ArrayList<>();
|
||||
for (PaymentInstruction paymentInstruction : formedPaymentInstructions) {
|
||||
for (Pair<PaymentInstruction, Registry> pair : formedPaymentInstructions) {
|
||||
PaymentInstruction paymentInstruction = pair.getFirst();
|
||||
Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId());
|
||||
Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId());
|
||||
if (SessionType.CURR.equals(sessionType)) {
|
||||
boolean madeStatements = createStatementsIfNeeded(paymentInstruction, pair.getSecond());
|
||||
if (madeStatements) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (List.of(AccountType.Corr, AccountType.Clrn, AccountType.Tran, AccountType.Anlt, AccountType.Info)
|
||||
.contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) {
|
||||
//если info подставить anlt (единственный счет в системе)
|
||||
|
|
@ -458,6 +485,118 @@ public class FormingPaymentInstructionAssets implements ISessionStage {
|
|||
return sDf12;
|
||||
}
|
||||
|
||||
private boolean createStatementsIfNeeded(PaymentInstruction pmt, Registry am_b) {
|
||||
ImdgPredicateBuilder pb = stlmHPropsImdg.predicateBuilder();
|
||||
String curCode = pmt.getCreditLeg_currencyCode();
|
||||
boolean noNeedForStatements = stlmHPropsImdg.getFirstObjectByPredicate(
|
||||
pb.and(
|
||||
pb.in("currencyCode", curCode),
|
||||
pb.equals("companyId", Sender.Prc.getId())
|
||||
)
|
||||
) != null;
|
||||
if (noNeedForStatements) return false;
|
||||
Supplier<Statement> stmtBldr = () -> {
|
||||
Statement stmt = new Statement();
|
||||
stmt.setSenderId(Sender.One.getId());
|
||||
stmt.setStatementType(StatementType.incr.getKey());
|
||||
stmt.setComment("Расчеты по сессии");
|
||||
stmt.setSettlementDate(LocalDate.now());
|
||||
stmt.setOperationStatus(OperationStatus.Executed.getKey());//todo тут что-то с апдейтом статуса на EXEC когда создались регистры с нулевым диффом?
|
||||
stmt.setClearingDate(LocalDate.now());
|
||||
stmt.setCreated(Instant.now());
|
||||
stmt.setComment(pmt.getPaymentPurpose());
|
||||
return stmt;
|
||||
};
|
||||
Statement stmtDeb = stmtBldr.get();
|
||||
Statement stmtCred = stmtBldr.get();
|
||||
|
||||
stmtCred.setAddresseeId(pmt.getSenderId());
|
||||
stmtDeb.setAddresseeId(pmt.getAddresseeId());
|
||||
|
||||
stmtDeb.setAccountId(pmt.getDebitLeg_accountId());
|
||||
stmtDeb.setAccount(pmt.getDebitLeg_account());
|
||||
stmtCred.setAccountId(pmt.getCreditLeg_accountId());
|
||||
stmtCred.setAccount(pmt.getCreditLeg_account());
|
||||
|
||||
|
||||
stmtDeb.setSecurityId(pmt.getDebitLeg_securityId());
|
||||
stmtCred.setSecurityId(pmt.getCreditLeg_securityId());
|
||||
|
||||
stmtDeb.setInOutDirection(pmt.getDebitLeg_direction());
|
||||
stmtCred.setInOutDirection(pmt.getCreditLeg_direction());
|
||||
|
||||
stmtDeb.setAmount(pmt.getDebitLeg_amount());
|
||||
stmtCred.setAmount(pmt.getCreditLeg_amount());
|
||||
|
||||
stmtImdg.insert(stmtDeb);
|
||||
stmtImdg.insert(stmtCred);
|
||||
|
||||
if (am_b != null) {
|
||||
Function<RegistryUnit, Registry> copy = (unit) -> {
|
||||
Registry res = am_b.clone();
|
||||
RegistryManager.zeroState(res);
|
||||
res.setRegistryUnit(RegistryUnit.B.getKey());
|
||||
res.setRegistryCode(RegistryUtil.clearingCode(res));
|
||||
return res;
|
||||
};
|
||||
|
||||
Registry am_t = assets.searchByTcrCompanyAccount(am_b, AM_T).orElseThrow(() -> {
|
||||
log.error("{}.id={} PaymentInstruction.id={} no AM*T found", am_b.getRegistryCode(), am_b.getId(), pmt.getId());
|
||||
return new RuntimeException("couldn't find AM*T");
|
||||
});
|
||||
|
||||
BigDecimal am_bBalance = safeBD(am_b.getBalance());
|
||||
am_b.setBalance(BigDecimal.ZERO);
|
||||
|
||||
{
|
||||
BigDecimal amtBalance = safeBD(am_t.getBalance());
|
||||
am_t.setBalance(amtBalance.subtract(am_bBalance));
|
||||
}
|
||||
|
||||
Registry am_f = assets.searchByTcrCompanyAccount(am_b, AM_F)
|
||||
.orElseGet(() -> copy
|
||||
.andThen(r -> {r.setBalance(am_t.getBalance()); return r;})
|
||||
.apply(RegistryUnit.F)
|
||||
);
|
||||
|
||||
assets.process(am_b, am_t, am_f, BigDecimal.ZERO);
|
||||
registryImdg.update(am_t);
|
||||
}
|
||||
|
||||
log.debug(("paymentInstruction.id=%d created statements [credit id=%d] and [debit id=%d]. " +
|
||||
"set am_b.id=%d balance to zero").formatted(
|
||||
pmt.getId(), stmtCred.getId(), stmtDeb.getId(), am_b != null ? am_b.getId() : null
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Registry copyRegB(Registry rgs) {
|
||||
Registry rgsB = rgs.clone();
|
||||
RegistryManager.zeroState(rgsB);
|
||||
rgsB.setRegistryUnit(RegistryUnit.B.getKey());
|
||||
rgsB.setRegistryCode(RegistryUtil.clearingCode(rgsB));
|
||||
return rgsB;
|
||||
}
|
||||
|
||||
private Registry copyRegF(Registry rgs) {
|
||||
Registry rgsF = rgs.clone();
|
||||
RegistryManager.zeroState(rgsF);
|
||||
rgsF.setRegistryUnit(RegistryUnit.F.getKey());
|
||||
rgsF.setRegistryCode(RegistryUtil.clearingCode(rgsF));
|
||||
rgsF.setBalance(safeBD(rgs.getBalance()));
|
||||
return rgsF;
|
||||
}
|
||||
|
||||
DateTimeFormatter payDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
|
||||
|
||||
private LocalDate settlementDate(String payDate) {
|
||||
if (TextUtil.isEmpty(payDate)) {
|
||||
return null;
|
||||
}
|
||||
return LocalDate.parse(payDate, payDateFormatter);
|
||||
}
|
||||
|
||||
public void setSection(Section section) {
|
||||
this.section = section;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue