PaymentInstruction Outbound
SDf06
This commit is contained in:
parent
848c26d69a
commit
745a13a8f8
10 changed files with 473 additions and 9 deletions
|
|
@ -22,14 +22,18 @@ import ru.clearing.classes.statics.data.statement.Statement;
|
|||
import ru.clearing.platform.dictionary.SectionDictionary;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.clearing.service.validation.*;
|
||||
import ru.spcex.clearing.util.security.UserRoleVerification;
|
||||
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.imdg.validation.LogPrefixId;
|
||||
import ru.spcex.platform.imdg.validation.rule.PresentById;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
import ru.spcex.platform.utils.validation.ValidatorImpl;
|
||||
|
||||
|
|
@ -312,4 +316,35 @@ public class ValidationConfig {
|
|||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<PIClearingOutbondActionNewRequest, IValidator> piOutboundValidation() {
|
||||
return pmtOut -> {
|
||||
ImdgValidationContext<PIClearingOutbondActionNewRequest> ctx = new ImdgValidationContext<>();
|
||||
ctx.setValidatedObject(pmtOut);
|
||||
ctx.addImdg(IMDGDistributedNames.Map_Company, imdgCompany);
|
||||
ctx.addImdg(IMDGDistributedNames.Map_Account, imdgAccount);
|
||||
return new ValidatorImpl<>(ctx,
|
||||
PaymentOutboundValidationRule.RequiredFields,
|
||||
IdPresentRule.instance("senderId",
|
||||
PIClearingOutbondActionNewRequest::getSenderId,
|
||||
IMDGDistributedNames.Map_Company,
|
||||
Company.class,
|
||||
ClearingError.RequiredFieldEmpty,
|
||||
ClearingError.DictionaryNotFound),
|
||||
IdPresentRule.instance("addresseeId",
|
||||
PIClearingOutbondActionNewRequest::getAddresseeId,
|
||||
IMDGDistributedNames.Map_Company,
|
||||
Company.class,
|
||||
ClearingError.RequiredFieldEmpty,
|
||||
ClearingError.DictionaryNotFound),
|
||||
PaymentOutboundValidationRule.CreditLegAccount,
|
||||
PaymentOutboundValidationRule.DebitLegAccount);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean("userRoleVerification")
|
||||
public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver msgs) {
|
||||
return new UserRoleVerification(imdgProvider, msgs, ClearingError.UserVerifyDenial);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ package ru.spcex.clearing.error;
|
|||
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
|
||||
|
||||
public enum ClearingError implements IErrorEnumId {
|
||||
WrongFieldValue(1004L),
|
||||
GeneralError(5400L),
|
||||
UserVerifyDenial(5001L),
|
||||
RequiredFieldEmpty(5002L),
|
||||
DictionaryNotFound(5003L),
|
||||
DepoAccNotFound(5011L),
|
||||
RecordNotFoundInDictionary(5423L),
|
||||
IncorrectValue(5404L),
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ import ru.spcex.clearing.platform.messaging.domain.cud.clearing.Sdf04Request;
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SessionContinueEvent;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApprovalRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.STradesImportedRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||
import ru.spcex.clearing.service.executors.Sdf06Executor;
|
||||
import ru.spcex.clearing.service.executors.Sdf10Executor;
|
||||
import ru.spcex.clearing.service.payment.PaymentInstructionOutboundService;
|
||||
import ru.spcex.clearing.session.stage.*;
|
||||
import ru.spcex.clearing.session.stage.impl.BalanceRevise;
|
||||
import ru.spcex.platform.enumeration.Task;
|
||||
|
|
@ -43,6 +45,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
private final Sdf10Executor sdf10Executor;
|
||||
private final BalanceRevise balanceRevise;
|
||||
private final Sdf05Sender sdf05Sender;
|
||||
private final PaymentInstructionOutboundService pmtOutboundService;
|
||||
|
||||
@Autowired
|
||||
public EventsReceiver(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaResponseQueue,
|
||||
|
|
@ -52,7 +55,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
SecondaryAuctionT0Session secondaryAuctionT0Session,
|
||||
PrimaryAuctionB0Session primaryAuctionB0Session, PrimaryAuctionT0Session primaryAuctionT0Session, IntermediateMkrSession intermediateMkrSession, FinalMkrSession finalMkrSession, ReturnDepositSession returnDepositSession, SessionManager sessionManager,
|
||||
Sdf06Executor sdf06Executor,
|
||||
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender) {
|
||||
Sdf10Executor sdf10Executor, BalanceRevise balanceRevise, Sdf05Sender sdf05Sender, PaymentInstructionOutboundService pmtOutboundService) {
|
||||
super(kafkaQueue, kafkaResponseQueue);
|
||||
this.clearingService = clearingService;
|
||||
this.registryService = registryService;
|
||||
|
|
@ -68,6 +71,7 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
this.sdf10Executor = sdf10Executor;
|
||||
this.balanceRevise = balanceRevise;
|
||||
this.sdf05Sender = sdf05Sender;
|
||||
this.pmtOutboundService = pmtOutboundService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -92,6 +96,9 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
.setConsumer(sessionManager::defineAndStartSession)
|
||||
.forDestination(Task.startOfClearing.topic(), callbacks::put);
|
||||
|
||||
callback(PIClearingOutbondActionNewRequest.class)
|
||||
.setFunction(pmtOutboundService::sendOutBoundPayment)
|
||||
.forDestination(Consts.PAYMENT_INSTRUCTION_CLEARING_OUTBOUND_ACTION, callbacks::put);
|
||||
callback(SessionContinueEvent.class)
|
||||
.setConsumer(req -> {
|
||||
primaryAuctionBnSession.continueSession(req);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,175 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.account.BankAccount;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.clearing.classes.statics.data.sdf.SDf54;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.CompanySymbol;
|
||||
import ru.spcex.platform.enumeration.Sender;
|
||||
import ru.spcex.platform.enumeration.Status;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgId;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.number.BigDecimalUtil;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class Sdf54Creator {
|
||||
private Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
|
||||
private final Imdg<Company> companyImdg;
|
||||
private final Imdg<CompanySymbols> companySymbolImdg;
|
||||
private final Imdg<Account> accountImdg;
|
||||
private final Imdg<BankAccount> bankAccountImdg;
|
||||
private final ImdgId idGenerator;
|
||||
private static DateTimeFormatter payDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
|
||||
|
||||
public Sdf54Creator(ImdgProvider imdgProvider) {
|
||||
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||
this.companySymbolImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
|
||||
this.bankAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
|
||||
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||
}
|
||||
|
||||
public SDf54 create(PaymentInstruction paymentInstruction) {
|
||||
AccountType creditAccType = getAccountType(paymentInstruction.getCreditLeg_accountId());
|
||||
AccountType debAccType = getAccountType(paymentInstruction.getDebitLeg_accountId());
|
||||
String c_acc_deb = null;
|
||||
String c_acc_cred = null;
|
||||
Account anltAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s'"
|
||||
.formatted(AccountType.Anlt.getKey(), Status.Active.getKey()));
|
||||
if (AccountType.Info.equals(creditAccType) ^ AccountType.Info.equals(debAccType)) {
|
||||
if (anltAcc == null) {
|
||||
throw new IllegalStateException("SDF54 creation error: paymentInstruction.creditLeg_accountId="
|
||||
+ paymentInstruction.getCreditLeg_accountId() + " accountType 'Info' but no 'ANLT' account found");
|
||||
}
|
||||
if (AccountType.Info.equals(creditAccType)) {
|
||||
c_acc_deb = anltAcc.getAccount();
|
||||
} else {
|
||||
c_acc_cred = anltAcc.getAccount();
|
||||
}
|
||||
}
|
||||
c_acc_deb = c_acc_deb == null ? paymentInstruction.getCreditLeg_account() : c_acc_deb;
|
||||
c_acc_cred = c_acc_cred == null ? paymentInstruction.getDebitLeg_account() : c_acc_cred;
|
||||
|
||||
|
||||
SDf54 sDf54 = new SDf54();
|
||||
sDf54.setId(idGenerator.nextId());
|
||||
sDf54.setSeg_type("V");
|
||||
|
||||
//**********************
|
||||
String tranBic = selectSymbolValue(Sender.Prc.getId(), CompanySymbol.BIC);
|
||||
if (tranBic == null) {
|
||||
log.warn("CompanySymbols BIC not found for companyId={}", Sender.Prc.getId());
|
||||
} else {
|
||||
sDf54.setSbankcode(tranBic);
|
||||
}
|
||||
Company prcCmp = companyImdg.getSingleObjectByID(Sender.Prc.getId());
|
||||
String senderSbankName = "";
|
||||
if (prcCmp != null) {
|
||||
senderSbankName = prcCmp.getShortName();
|
||||
}
|
||||
SpecifUtil.fillSegmentsBy35Symbols(senderSbankName,
|
||||
sDf54::setSbanknam1,
|
||||
sDf54::setSbanknam2,
|
||||
sDf54::setSbanknam3,
|
||||
sDf54::setSbanknam4,
|
||||
sDf54::setSbanknam5);
|
||||
sDf54.setOp_type("01");
|
||||
sDf54.setOp_order("5");
|
||||
String innDeb = selectSymbolValue(Sender.One.getId(), CompanySymbol.INN);
|
||||
if (innDeb == null) {
|
||||
log.warn("CompanySymbols INN not found for companyId={}", Sender.One.getId());
|
||||
} else {
|
||||
sDf54.setInn_deb(innDeb);
|
||||
}
|
||||
String kppDeb = selectSymbolValue(Sender.One.getId(), CompanySymbol.CPP);
|
||||
if (kppDeb == null) {
|
||||
log.warn("CompanySymbols CPP not found for companyId={}", Sender.One.getId());
|
||||
} else {
|
||||
sDf54.setKpp_deb(kppDeb);
|
||||
}
|
||||
|
||||
if (anltAcc != null) {
|
||||
sDf54.setAcc_deb(anltAcc.getAccount());
|
||||
}
|
||||
BankAccount bnkAcc = bankAccountImdg.getFirstObjectBySQL("accountId = %d".formatted(paymentInstruction.getDebitLeg_accountId()));
|
||||
if (bnkAcc != null) {
|
||||
sDf54.setInn_cred(bnkAcc.getTaxpayerIdentificationNumber());
|
||||
sDf54.setKpp_cred(bnkAcc.getTaxRegistrationReasonCode());
|
||||
}
|
||||
sDf54.setAcc_kr_1(paymentInstruction.getDebitLeg_account());
|
||||
//**********************
|
||||
|
||||
|
||||
sDf54.setDoc_type("002");
|
||||
String strId = paymentInstruction.getId().toString();
|
||||
String strIdCut = strId.length() > 16 ? strId.substring(strId.length() - 16) : strId;
|
||||
sDf54.setDocnm_ref(strIdCut);
|
||||
sDf54.setC_acc_deb(c_acc_deb);
|
||||
|
||||
|
||||
|
||||
sDf54.setC_acc_cred(c_acc_cred);
|
||||
|
||||
String addresseeSbankName = "";
|
||||
if (paymentInstruction.getAddresseeId().equals(1L)) {
|
||||
addresseeSbankName = paymentInstruction.getAddresseeBankName();
|
||||
} else {
|
||||
Company company = companyImdg.getSingleObjectByID(paymentInstruction.getAddresseeId());
|
||||
if (company != null) {
|
||||
addresseeSbankName = company.getShortName();
|
||||
}
|
||||
}
|
||||
|
||||
SpecifUtil.fillSegmentsBy35Symbols(addresseeSbankName,
|
||||
sDf54::setRbanknam1,
|
||||
sDf54::setRbanknam2,
|
||||
sDf54::setRbanknam3,
|
||||
sDf54::setRbanknam4,
|
||||
sDf54::setRbanknam5);
|
||||
|
||||
sDf54.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(paymentInstruction.getPaymentDate())));
|
||||
sDf54.setPay_val("RUR");
|
||||
String sumDeb = paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : "";
|
||||
sDf54.setSum_deb(BigDecimalUtil.limitDecimalPlaces(sumDeb, 2));
|
||||
sDf54.setSpecif_1(paymentInstruction.getPaymentPurpose());
|
||||
sDf54.setGenerationTime(Instant.now());
|
||||
log.debug("paymentInstruction.id={}, sdf54.id {}", paymentInstruction.getId(), sDf54.getId());
|
||||
return sDf54;
|
||||
}
|
||||
|
||||
private AccountType getAccountType(Long accountId) {
|
||||
Account account = accountImdg.getSingleObjectByID(accountId);
|
||||
return IEnumKey.getEnumByKey(AccountType.class, account.getAccountType());
|
||||
}
|
||||
|
||||
protected String selectSymbolValue(Long companyId, CompanySymbol symbol) {
|
||||
if (companyId == null) {
|
||||
return null;
|
||||
}
|
||||
CompanySymbols cSymbol = companySymbolImdg.getFirstObjectByFieldValues(Map.of(
|
||||
"companyId", companyId,
|
||||
"companySymbol", symbol.getKey()));
|
||||
if (cSymbol == null) {
|
||||
return null;
|
||||
} else {
|
||||
return cSymbol.getCompanySymbolValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -131,15 +131,12 @@ public class Sdf06Executor {
|
|||
if (err.isPresent()) {
|
||||
log.debug("sdf06.id={} validation error: {}", sDf06.getId(), messageResolver.resolve(err.get()));
|
||||
SDf07 errorSdf07;
|
||||
BigDecimal errorResult;
|
||||
BigDecimal errorResult = errorById(err.get());
|
||||
Statement stmt = null;
|
||||
if (needToCreateStatement(err.get())) {
|
||||
errorResult = errorById(err.get());
|
||||
stmt = createStatementBySdf06(sDf06,
|
||||
((Company) validator.getStored(ValidationStored.Sdf06Company)).getId(),
|
||||
validator.getStored(ValidationStored.Sdf06Account));
|
||||
} else {
|
||||
errorResult = errorResult2;
|
||||
}
|
||||
errorSdf07 = createSdf07(sDf06, now, errorResult);
|
||||
errorSdf07.setGenerationId(sdf07GroupId);
|
||||
|
|
@ -203,7 +200,12 @@ public class Sdf06Executor {
|
|||
if (ClearingError.BalanceInsufficient.equals(err.getSubject())) {
|
||||
return errorResult3;
|
||||
}
|
||||
return errorResult1;
|
||||
if ( ClearingError.CompanyNotFoundB.equals(err.getSubject())
|
||||
|| ClearingError.AccountNotFoundB.equals(err.getSubject())
|
||||
|| ClearingError.TCRegistryNotFound.equals(err.getSubject())) {
|
||||
return errorResult2;
|
||||
}
|
||||
return errorResult2;
|
||||
}
|
||||
|
||||
public void processGatewayResponse(BaseRequest<AssetOperationApprovalRequest> req) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
package ru.spcex.clearing.service.payment;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.account.BankAccount;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.misc.Currency;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.clearing.classes.statics.data.sdf.SDf54;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.SdfClearingRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import ru.spcex.clearing.platform.messaging.service.Status;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.service.RegistryManager;
|
||||
import ru.spcex.clearing.service.Sdf54Creator;
|
||||
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
import ru.spcex.clearing.util.security.UserRoleVerification;
|
||||
import ru.spcex.platform.enumeration.CurrencyCode;
|
||||
import ru.spcex.platform.enumeration.TransactionStatus;
|
||||
import ru.spcex.platform.enumeration.UserRole;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgId;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Service
|
||||
public class PaymentInstructionOutboundService {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final UserRoleVerification rights;
|
||||
private final IMessageResolver msgs;
|
||||
private final Function<PIClearingOutbondActionNewRequest, IValidator> validation;
|
||||
private final ImdgProvider imdgProvider;
|
||||
private final ImdgId idGenerator;
|
||||
private final Imdg<PaymentInstruction> pmtImdg;
|
||||
private final Imdg<Company> cmpImdg;
|
||||
private final Imdg<BankAccount> bnkAccImdg;
|
||||
private final Imdg<Registry> rgsImdg;
|
||||
private final Imdg<TradingClearingRegistry> tcrImdg;
|
||||
private final Imdg<Currency> currImdg;
|
||||
private final Imdg<SDf54> sdf54Imdg;
|
||||
private final RegistryManager rgsMng;
|
||||
private final Sdf54Creator sdf54Creator;
|
||||
private final KafkaSender kafkaSender;
|
||||
|
||||
@Autowired
|
||||
public PaymentInstructionOutboundService(UserRoleVerification rights,
|
||||
IMessageResolver msgs,
|
||||
ImdgProvider imdgProvider,
|
||||
Function<PIClearingOutbondActionNewRequest, IValidator> validation, RegistryManager rgsMng, KafkaSender kafkaSender) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.rights = rights;
|
||||
this.msgs = msgs;
|
||||
this.validation = validation;
|
||||
this.pmtImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
||||
this.cmpImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.tcrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
this.bnkAccImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
|
||||
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.currImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class);
|
||||
this.sdf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class);
|
||||
this.sdf54Creator = new Sdf54Creator(imdgProvider);
|
||||
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||
this.rgsMng = rgsMng;
|
||||
this.kafkaSender = kafkaSender;
|
||||
}
|
||||
|
||||
public RequestInfoUpdate sendOutBoundPayment(BaseRequest<PIClearingOutbondActionNewRequest> req) {
|
||||
log.info("new PIClearingOutbondActionNewRequest.id: {}", req.getId());
|
||||
PIClearingOutbondActionNewRequest payload = req.getRequestPayload();
|
||||
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
|
||||
return error(req.getId(), ClearingError.UserVerifyDenial);
|
||||
}
|
||||
IValidator validator = validation.apply(payload);
|
||||
Optional<EnumMessage> validationErr = validator.tillFirstError();
|
||||
if (validationErr.isPresent()) {
|
||||
return error(req.getId(), validationErr.get());
|
||||
}
|
||||
Account accCred = validator.getStored(ValidationStored.PIOutboundAccountCred);
|
||||
Account accDeb = validator.getStored(ValidationStored.PIOutboundAccountDeb);
|
||||
Company addressee = cmpImdg.getSingleObjectByID(payload.getAddresseeId());
|
||||
Company sender = cmpImdg.getSingleObjectByID(payload.getSenderId());
|
||||
BigDecimal amount = payload.getCreditLeg_amount();
|
||||
log.debug("all checks passed, accCred.id={}, accDeb.id={}, addressee.id={}, sender.id={}, amount: {}",
|
||||
accCred.getId(), accDeb.getId(), addressee.getId(), sender.getId(), amount);
|
||||
|
||||
TradingClearingRegistry tcr = tcrImdg.getFirstObjectBySQL("moneyAccountId = '%d' and companyId = %d"
|
||||
.formatted(accCred.getId(), addressee.getId()));
|
||||
PaymentInstruction pmt = PaymentInstructionBuilderV2.builder(imdgProvider)
|
||||
.registry(new Registry())
|
||||
.sender(addressee.getId())
|
||||
.addressee(addressee.getId())
|
||||
.debitLegAccount(accDeb)
|
||||
.creditLegAccount(accCred)
|
||||
.amount(amount)
|
||||
.sessionId(null)
|
||||
.purpose(tcr != null ? "Вывод средств по ТКР " + tcr.getCode() : "Вывод средств")
|
||||
.build();
|
||||
BankAccount bnkAcc = bnkAccImdg.getFirstObjectBySQL("accountId = %d".formatted(accDeb.getId()));
|
||||
if (bnkAcc != null) {
|
||||
pmt.setAddresseeBankName(bnkAcc.getBankIdentificationCode());
|
||||
pmt.setDebit_csAccount(bnkAcc.getCorrespondentAccount());
|
||||
}
|
||||
Currency currency = currImdg.getFirstObjectBySQL("currencyCode = '%s'".formatted(CurrencyCode.RUB.getKey()));
|
||||
if (currency != null) {
|
||||
pmt.setCreditLeg_securityId(currency.getId());
|
||||
pmt.setDebitLeg_securityId(currency.getId());
|
||||
}
|
||||
pmt.setTransactionStatus(TransactionStatus.exec.getKey());
|
||||
//fixme pmt.setDocumentNumber(registry.getSecurityId());
|
||||
|
||||
pmtImdg.insert(pmt);
|
||||
log.debug("new PaymentInstruction.id: {}", pmt.getId());
|
||||
SDf54 sDf54 = sdf54Creator.create(pmt);
|
||||
Long sdf54Id = idGenerator.nextId();
|
||||
sDf54.setId(sdf54Id);
|
||||
sDf54.setGenerationId(sdf54Id);
|
||||
sdf54Imdg.insert(sDf54);
|
||||
log.debug("new sdf54.id: {}", sDf54.getId());
|
||||
SdfClearingRequest exp = new SdfClearingRequest();
|
||||
exp.setGroupId(sdf54Id);
|
||||
kafkaSender.sendRequestToQueue(Consts.SDF54_PROCESS, exp);
|
||||
return success(req.getId());
|
||||
}
|
||||
|
||||
private RequestInfoUpdate error(Long id, EnumMessage err) {
|
||||
return new RequestInfoUpdate(id, Status.Error, msgs.resolve(err));
|
||||
}
|
||||
|
||||
private RequestInfoUpdate error(Long id, IEnumId sbj, Object... args) {
|
||||
EnumMessage error = new EnumMessage(sbj, args);
|
||||
return new RequestInfoUpdate(id, Status.Error, msgs.resolve(error));
|
||||
}
|
||||
|
||||
private RequestInfoUpdate success(Long id) {
|
||||
return new RequestInfoUpdate(id, Status.Success, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package ru.spcex.clearing.service.validation;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public enum PaymentOutboundValidationRule implements IValidationRule<ImdgValidationContext<PIClearingOutbondActionNewRequest>> {
|
||||
RequiredFields() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<PIClearingOutbondActionNewRequest> context) {
|
||||
PIClearingOutbondActionNewRequest pmtOut = context.getValidatedObject();
|
||||
if (pmtOut.getSenderId() == null) {
|
||||
return of(ClearingError.RequiredFieldEmpty, "senderId");
|
||||
}
|
||||
if (pmtOut.getAddresseeId() == null) {
|
||||
return of(ClearingError.RequiredFieldEmpty, "addresseeId");
|
||||
}
|
||||
if (pmtOut.getCreditLeg_amount() == null) {
|
||||
return of(ClearingError.RequiredFieldEmpty, "creditLeg_amount");
|
||||
}
|
||||
if (pmtOut.getCreditLeg_accountId() == null) {
|
||||
return of(ClearingError.RequiredFieldEmpty, "creditLeg_accountId");
|
||||
}
|
||||
if (pmtOut.getDebitLeg_accountId() == null) {
|
||||
return of(ClearingError.RequiredFieldEmpty, "debitLeg_accountId");
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
CreditLegAccount() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<PIClearingOutbondActionNewRequest> context) {
|
||||
PIClearingOutbondActionNewRequest pmtOut = context.getValidatedObject();
|
||||
Imdg<Account> accImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||
ImdgPredicateBuilder pb = accImdg.predicateBuilder();
|
||||
Account acc = accImdg.getSingleObjectByPredicate(
|
||||
pb.and(
|
||||
pb.equals("id", pmtOut.getCreditLeg_accountId()),
|
||||
pb.equals("accountType", AccountType.Info.getKey())
|
||||
)
|
||||
);
|
||||
if (acc == null) {
|
||||
return of(ClearingError.WrongFieldValue, "creditLeg_accountId");
|
||||
}
|
||||
context.storeObject(ValidationStored.PIOutboundAccountCred, acc);
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
DebitLegAccount() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<PIClearingOutbondActionNewRequest> context) {
|
||||
PIClearingOutbondActionNewRequest pmtOut = context.getValidatedObject();
|
||||
Imdg<Account> accImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||
ImdgPredicateBuilder pb = accImdg.predicateBuilder();
|
||||
Account acc = accImdg.getSingleObjectByPredicate(
|
||||
pb.and(
|
||||
pb.equals("id", pmtOut.getDebitLeg_accountId()),
|
||||
pb.equals("accountType", AccountType.Bank.getKey())
|
||||
)
|
||||
);
|
||||
if (acc == null) {
|
||||
return of(ClearingError.WrongFieldValue, "debitLeg_accountId");
|
||||
}
|
||||
context.storeObject(ValidationStored.PIOutboundAccountDeb, acc);
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
;
|
||||
private final static Logger log = LoggerFactory.getLogger(PaymentOutboundValidationRule.class);
|
||||
@Override
|
||||
public String ruleName() {
|
||||
return "PaymentOutboundValidationRule." + name();
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@ public enum ValidationStored {
|
|||
|
||||
Sdf21Account,
|
||||
|
||||
PIOutboundAccountDeb, PIOutboundAccountCred,
|
||||
|
||||
Sdf06Company, Sdf06Account, Sdf06Tcr,
|
||||
|
||||
ReturnDepositDmx,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ public class UserRoleVerification {
|
|||
public UserRoleVerification(ImdgProvider imdg,
|
||||
IMessageResolver messageResolver,
|
||||
IErrorEnumId roleVerificationError) {
|
||||
Objects.requireNonNull(roleForVerification);
|
||||
Objects.requireNonNull(roleVerificationError);
|
||||
Objects.requireNonNull(messageResolver);
|
||||
userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class);
|
||||
|
|
@ -62,7 +61,7 @@ public class UserRoleVerification {
|
|||
this.roleForVerification = roleForVerification;
|
||||
}
|
||||
|
||||
protected boolean userHasRole(Long userId, IEnumKey role) {
|
||||
public boolean userHasRole(Long userId, IEnumKey role) {
|
||||
return userHasRole(userId, role == null ? null : role.getKey());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration;
|
|||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum TransactionStatus implements IEnumKey {
|
||||
stld("STLD"), notSent("NSNT"), cher("CHER"), sent("SENT"), ok("OK"), fail("FAIL");
|
||||
stld("STLD"), notSent("NSNT"), cher("CHER"), sent("SENT"), ok("OK"), fail("FAIL"), exec("EXEC");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue