From 1037b271650905d9f11c22501af3b14604b2132f Mon Sep 17 00:00:00 2001 From: ialbert Date: Thu, 13 Jun 2024 18:00:42 +0300 Subject: [PATCH] =?UTF-8?q?1.=20paymentPurpose=20+=3D=20"=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D0=B8=D1=82=D0=BE=D0=B3=D1=83=20=D0=BA=D0=BB=D0=B8=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=D0=B0"=202.=20=D0=A2=D0=9A=D0=A0/TKR=20sdf57?= =?UTF-8?q?/sdf06=20search=203.=20=D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=80=D1=83=D1=81/=D0=B0?= =?UTF-8?q?=D0=BD=D0=B3=D0=BB=20purpose=20=D0=B4=D0=BB=D1=8F=20PaymentInst?= =?UTF-8?q?ructionOutboundService=204.=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B2=20=D0=B4=D0=BE=D0=BF=D1=83=D1=81=D0=BA=D0=B5=20?= =?UTF-8?q?=D0=BA=20CURR=20=D1=81=D0=B5=D1=81=D1=81=D0=B8=D0=B8=205.=20swt?= =?UTF-8?q?-exporter=20bugfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spcex/clearing/config/MessagesConfig.java | 22 ++++---- .../clearing/messages/ClearingMessage.java | 21 ++++++++ .../spcex/clearing/service/AnltSearcher.java | 2 +- .../spcex/clearing/service/Sdf54Creator.java | 52 +++++++++++-------- .../builder/RegistrySecurityBuilder.java | 49 +++++++++++------ .../service/executors/Sdf21Executor.java | 50 +++++++++--------- .../service/executors/Sdf57Executor.java | 13 ----- .../PaymentInstructionOutboundService.java | 16 ++++-- .../RegistryStep3ValidationRule.java | 11 ++-- ...ormingPaymentInstructionDepositReturn.java | 8 +-- .../FormingPaymentInstructionReturnMkr.java | 4 +- .../ru/spcex/clearing/util/LocaleUtil.java | 31 +++++++++++ .../messages/clearing_eng.properties | 2 + .../resources/messages/clearing_ru.properties | 2 + .../services/exportimpl/DF12Exporter.java | 16 +++--- .../SpringPropertiesLocalizer.java | 41 +++++++++++++++ 16 files changed, 231 insertions(+), 109 deletions(-) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/messages/ClearingMessage.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/LocaleUtil.java create mode 100644 clearing-parent/clearing-service/src/main/resources/messages/clearing_eng.properties create mode 100644 clearing-parent/clearing-service/src/main/resources/messages/clearing_ru.properties create mode 100644 platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/localization/SpringPropertiesLocalizer.java diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MessagesConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MessagesConfig.java index 38d52587e..26fdf82e1 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MessagesConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MessagesConfig.java @@ -1,19 +1,18 @@ package ru.spcex.clearing.config; +import java.util.Locale; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; -import ru.spcex.platform.utils.enumeration.IMessageResolver; -import ru.spcex.platform.utils.enumeration.SpringPropertiesMessageResolver; +import ru.spcex.platform.utils.localization.SpringPropertiesLocalizer; -import java.util.Locale; - -//@Configuration +@Configuration public class MessagesConfig { - @Bean("validation-error-messages") + @Bean("clearing-messages") public ResourceBundleMessageSource messages() { ResourceBundleMessageSource source = new ResourceBundleMessageSource(); - source.setBasenames("messages/error"); + source.setBasenames("messages/clearing"); source.setUseCodeAsDefaultMessage(true); source.setDefaultEncoding("utf8"); source.setDefaultLocale(Locale.ROOT); @@ -21,9 +20,12 @@ public class MessagesConfig { } @Bean - public IMessageResolver errorResolver(@Qualifier("validation-error-messages") ResourceBundleMessageSource messageBundle) { - SpringPropertiesMessageResolver resolver = new SpringPropertiesMessageResolver(messageBundle); - resolver.setLocale("ru"); + public SpringPropertiesLocalizer localizer( + @Qualifier("clearing-messages") + ResourceBundleMessageSource messageBundle + ) { + SpringPropertiesLocalizer resolver = new SpringPropertiesLocalizer(messageBundle); + resolver.setDefaultLocale("ru"); return resolver; } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/messages/ClearingMessage.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/messages/ClearingMessage.java new file mode 100644 index 000000000..cf150d1ff --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/messages/ClearingMessage.java @@ -0,0 +1,21 @@ +package ru.spcex.clearing.messages; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum ClearingMessage implements IEnumKey { + WithdrawalFreeFromTkr("payment-instruction.purpose.withdrawal.tcr"), + WithdrawalOfFunds("payment-instruction.purpose.withdrawal"), + urgent("sdf54.urgent"), + ; + private final String key; + + ClearingMessage(String key) { + this.key = key; + } + + + @Override + public String getKey() { + return key; + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/AnltSearcher.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/AnltSearcher.java index f99423124..a4e537fcc 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/AnltSearcher.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/AnltSearcher.java @@ -116,7 +116,7 @@ public class AnltSearcher { return new AnltSearch(infoAcc, company, tcr, tcrList, currencyCode); } - private static final Pattern tcrPattern = Pattern.compile("ТКР.*?([0-9A-Z-]{12})"); + private static final Pattern tcrPattern = Pattern.compile("ТКР|TKR.*?([0-9A-Z-]{12})"); private static String getTkrCodeFromComment(String comment) { if (TextUtil.isEmpty(comment)) { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Sdf54Creator.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Sdf54Creator.java index cb0f1cf29..ea7d91174 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Sdf54Creator.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Sdf54Creator.java @@ -3,6 +3,7 @@ package ru.spcex.clearing.service; import java.time.Instant; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Locale; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,6 +16,8 @@ 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.clearing.messages.ClearingMessage; +import ru.spcex.clearing.util.LocaleUtil; import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.CompanySymbol; @@ -25,6 +28,7 @@ import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.localization.SpringPropertiesLocalizer; import ru.spcex.platform.utils.number.BigDecimalUtil; import ru.spcex.platform.utils.time.TimeUtil; @@ -38,9 +42,10 @@ public class Sdf54Creator { private final Imdg sdf54Imdg; private final Imdg bankAccountImdg; private final ImdgId idGenerator; + private final SpringPropertiesLocalizer resolver; private static DateTimeFormatter payDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yy"); - public Sdf54Creator(ImdgProvider imdgProvider) { + public Sdf54Creator(ImdgProvider imdgProvider, SpringPropertiesLocalizer resolver) { 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); @@ -48,23 +53,25 @@ public class Sdf54Creator { this.bankAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class); this.sdf54Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf54, SDf54.class); this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.resolver = resolver; } private final static DateTimeFormatter docnmRefFormatter = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS"); - public SDf54 create(PaymentInstruction paymentInstruction) { + public SDf54 create(PaymentInstruction pmt) { Instant now = Instant.now(); String c_acc_cred = null; Account anltAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and currency = '%s'" .formatted( AccountType.Anlt.getKey(), Status.Active.getKey(), - paymentInstruction.getCreditLeg_currencyCode() + pmt.getCreditLeg_currencyCode() )); // 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; + c_acc_cred = c_acc_cred == null ? pmt.getDebitLeg_account() : c_acc_cred; + Locale locale = LocaleUtil.locale(pmt.getCreditLeg_currencyCode(), pmt.getDebitLeg_currencyCode()); SDf54 sDf54 = new SDf54(); sDf54.setId(idGenerator.nextId()); sDf54.setSeg_type("V"); @@ -80,6 +87,9 @@ public class Sdf54Creator { String senderSbankName = ""; if (prcCmp != null) { senderSbankName = prcCmp.getShortName(); + if (!LocaleUtil.isRus(locale) && prcCmp.getProfile() != null) { + senderSbankName = prcCmp.getProfile().getShortNameEng(); + } } SpecifUtil.fillSegmentsBy35Symbols(senderSbankName, sDf54::setSbanknam1, @@ -105,29 +115,27 @@ public class Sdf54Creator { if (anltAcc != null) { sDf54.setAcc_deb(anltAcc.getAccount()); } - Account accDebAcc = accountImdg.getSingleObjectByID(paymentInstruction.getDebitLeg_accountId()); + Account accDebAcc = accountImdg.getSingleObjectByID(pmt.getDebitLeg_accountId()); if (accDebAcc == null || !AccountStatus.ACTIVE.equalsByKey(accDebAcc.getStatus())) { - log.warn("paymentInstruction[{}].DebitLeg_accountId={} account not exist or not active.", paymentInstruction.getId(), paymentInstruction.getDebitLeg_accountId()); + log.warn("paymentInstruction[{}].DebitLeg_accountId={} account not exist or not active.", pmt.getId(), pmt.getDebitLeg_accountId()); } - BankAccount bnkAcc = bankAccountImdg.getFirstObjectBySQL("accountId = %d".formatted(paymentInstruction.getDebitLeg_accountId())); + BankAccount bnkAcc = bankAccountImdg.getFirstObjectBySQL("accountId = %d".formatted(pmt.getDebitLeg_accountId())); if (bnkAcc != null) { sDf54.setInn_cred(bnkAcc.getTaxpayerIdentificationNumber()); sDf54.setKpp_cred(bnkAcc.getTaxRegistrationReasonCode()); c_acc_cred = bnkAcc.getCorrespondentAccount(); - sDf54.setSwift_ben(bnkAcc.getSwiftCode()); + if (!LocaleUtil.isRus(locale)) { + sDf54.setSwift_ben(bnkAcc.getSwiftCode()); + sDf54.setSwift_int(bnkAcc.getIntermediarySwiftCode()); + } } else { - log.warn("Bank account not found for DebitLeg_accountId={}", paymentInstruction.getDebitLeg_accountId()); + log.warn("Bank account not found for DebitLeg_accountId={}", pmt.getDebitLeg_accountId()); } sDf54.setDoc_num(String.valueOf(nextDocNum())); - BankAccount prcBankAcc = bankAccountImdg.getFirstObjectBySQL("companyId = %d and currency = '%s'" - .formatted(Sender.Prc.getId(), paymentInstruction.getCreditLeg_currencyCode())); - if (prcBankAcc != null) { - sDf54.setSwift_int(prcBankAcc.getSwiftCode()); - } String today = payDateFormatter.format(LocalDate.now()); sDf54.setDoc_date(today); sDf54.setValue_date(today); - sDf54.setAcc_kr_1(paymentInstruction.getDebitLeg_account()); + sDf54.setAcc_kr_1(pmt.getDebitLeg_account()); { Account prcCorrAcc = accountImdg.getFirstObjectBySQL("companyId=%d and accountType = '%s' and status = '%s' and currency = '%s'" @@ -135,7 +143,7 @@ public class Sdf54Creator { Sender.Prc.getId(), AccountType.Bank.getKey(), Status.Active.getKey(), - paymentInstruction.getCreditLeg_currencyCode() + pmt.getCreditLeg_currencyCode() )); if (prcCorrAcc == null) { log.warn("Account for PRC CORR not found"); @@ -145,7 +153,7 @@ public class Sdf54Creator { } //********************** - sDf54.setSend_type("срочно"); + sDf54.setSend_type(resolver.resolve(ClearingMessage.urgent, locale)); sDf54.setDoc_type("002"); sDf54.setDocnm_ref(docnmRefFormatter.format(TimeUtil.toDateTime(now))); @@ -186,13 +194,13 @@ public class Sdf54Creator { } } - sDf54.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(paymentInstruction.getPaymentDate()))); - sDf54.setPay_val(paymentInstruction.getCreditLeg_currencyCode()); - String sumDeb = paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : ""; + sDf54.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(pmt.getPaymentDate()))); + sDf54.setPay_val(pmt.getCreditLeg_currencyCode()); + String sumDeb = pmt.getDebitLeg_amount() != null ? pmt.getDebitLeg_amount().toString() : ""; sDf54.setSum_deb(BigDecimalUtil.limitDecimalPlaces(sumDeb, 2)); - sDf54.setSpecif_1(paymentInstruction.getPaymentPurpose()); + sDf54.setSpecif_1(pmt.getPaymentPurpose()); sDf54.setGenerationTime(now); - log.debug("paymentInstruction.id={}, sdf54.id {}", paymentInstruction.getId(), sDf54.getId()); + log.debug("paymentInstruction.id={}, sdf54.id {}", pmt.getId(), sDf54.getId()); return sDf54; } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/RegistrySecurityBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/RegistrySecurityBuilder.java index 8be4f2591..c00e5aced 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/RegistrySecurityBuilder.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/RegistrySecurityBuilder.java @@ -1,5 +1,10 @@ package ru.spcex.clearing.service.builder; +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; +import java.util.Collection; +import java.util.Map; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.ClearingAccount; import ru.clearing.classes.statics.data.company.Company; @@ -8,28 +13,31 @@ import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Currency; import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.classes.statics.data.sdf.SDf21; import ru.clearing.classes.statics.data.security.CurrencyPairSecurity; import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.clearing.classes.statics.data.security.Security; import ru.clearing.classes.statics.data.statement.Statement; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.session.stage.util.RegistryUtil; -import ru.spcex.platform.enumeration.*; +import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryInstrumentType; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IEnumKey; - -import java.math.BigDecimal; -import java.time.Instant; -import java.time.LocalDate; -import java.util.Collection; -import java.util.Map; +import ru.spcex.platform.utils.number.BigDecimalUtil; public class RegistrySecurityBuilder { private Statement statement; private Company company; private Account account; private RegistryDesignation designation; + private SDf21 sdf21; + private final ImdgProvider imdgProvider; private final Imdg clearingAccountImdg; @@ -92,19 +100,18 @@ public class RegistrySecurityBuilder { rgs.setRegistryInstrumentType(RegistryInstrumentType.S.getKey()); AccountType accType = IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()); - if (AccountType.Clrn.equals(accType)) { - ClearingAccount accountForStatement = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", statement.getAccountId())); - if (accountForStatement != null) { - rgs.setRegistryCapacity(accountForStatement.getClearingAccountType()); - } - } else if (AccountType.Info.equals(accType) || AccountType.Anlt.equals(accType)) { - rgs.setRegistryCapacity(RegistryCapacity.A.getKey()); - } + //if (AccountType.Clrn.equals(accType)) { + // ClearingAccount accountForStatement = clearingAccountImdg.getFirstObjectByFieldValues(Map.of("accountId", statement.getAccountId())); + // if (accountForStatement != null) { + // rgs.setRegistryCapacity(accountForStatement.getClearingAccountType()); + // } + //} else if (AccountType.Info.equals(accType) || AccountType.Anlt.equals(accType)) { + // rgs.setRegistryCapacity(RegistryCapacity.A.getKey()); + //} rgs.setRegistryUnit(RegistryUnit.T.getKey()); - rgs.setRegistryCode(RegistryUtil.clearingCode(rgs)); Collection tcrsByAccount = tradingClearingRegistryImdg.getCollectionObjectsByFieldValues(Map.of( - "moneyAccountId", account.getId(), + "depoAccountId", account.getId(), "companyId", company.getId(), "status", ServiceStatus.Active.getKey() )); @@ -112,7 +119,9 @@ public class RegistrySecurityBuilder { TradingClearingRegistry tcr = tcrsByAccount.iterator().next(); rgs.setTradingClearingRegistryId(tcr.getId()); rgs.setTradingClearingRegistry(tcr.getCode()); + rgs.setRegistryCapacity(tcr.getTradingClearingRegistryType()); } + rgs.setRegistryCode(RegistryUtil.clearingCode(rgs)); rgs.setRegistryStatus(RegistryStatus.PROC.getKey()); rgs.setSecurityId(statement.getSecurityId()); @@ -131,6 +140,7 @@ public class RegistrySecurityBuilder { rgs.setCreated(Instant.now()); //по дефолту создаем с балансом 0, а потом пересчитываем по необходимости + rgs.setPlanBalance(BigDecimalUtil.parse(sdf21.getCloseBalance())); rgs.setBalance(BigDecimal.ZERO); rgs.setDebit(BigDecimal.ZERO); rgs.setCredit(BigDecimal.ZERO); @@ -154,4 +164,9 @@ public class RegistrySecurityBuilder { if (currency != null) return currency.getCurrencyCode(); return null; } + + public RegistrySecurityBuilder sdf21(SDf21 sdf21) { + this.sdf21 = sdf21; + return this; + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java index 040862e1b..a08ab39e8 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java @@ -1,5 +1,13 @@ package ru.spcex.clearing.service.executors; +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Collection; +import java.util.Optional; +import java.util.function.Function; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; @@ -26,7 +34,21 @@ import ru.spcex.clearing.service.model.Result; import ru.spcex.clearing.service.registry.AssetTBFProcessing; import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.clearing.session.stage.util.RegistryUtil; -import ru.spcex.platform.enumeration.*; +import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.BalanceDimension; +import ru.spcex.platform.enumeration.InOutDirection; +import ru.spcex.platform.enumeration.InOutSDfType; +import ru.spcex.platform.enumeration.OperationCode; +import ru.spcex.platform.enumeration.OperationStatus; +import ru.spcex.platform.enumeration.RegistryCapacity; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryInstrumentType; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.enumeration.RegistryTradingParams; +import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.enumeration.Sender; +import ru.spcex.platform.enumeration.StatementType; +import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; @@ -36,20 +58,10 @@ import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.enumeration.IMessageResolver; +import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD; import ru.spcex.platform.utils.text.TextUtil; import ru.spcex.platform.utils.validation.IValidator; -import java.math.BigDecimal; -import java.time.Instant; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.Collection; -import java.util.Optional; -import java.util.function.Function; -import java.util.regex.Pattern; - -import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD; - @Service public class Sdf21Executor extends AbstractExecutor { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -193,6 +205,7 @@ public class Sdf21Executor extends AbstractExecutor { rgs.getCredit()); }, () -> { Registry registry = RegistrySecurityBuilder.builder(imdgProvider) + .sdf21(sdf21) .statement(stmt) .company(company) .account(account) @@ -428,19 +441,6 @@ public class Sdf21Executor extends AbstractExecutor { } } - private static String getTkrCodeFromComment(String comment) { - if (comment == null) { - return null; - } - comment = comment.toUpperCase(); - int tcrIndex = comment.indexOf("ТКР"); - if (tcrIndex == -1) { - return null; - } - comment = comment.substring(tcrIndex + 3); - return comment.replaceAll("\\s+", ""); - } - private static String getContractFromSpecif(String specif) { if (specif == null) { return null; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java index 2674e9f35..d421a5b5b 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java @@ -790,19 +790,6 @@ public class Sdf57Executor extends AbstractExecutor { return LocalDate.parse(payDate, payDateFormatter); } - private static String getTkrCodeFromComment(String comment) { - if (comment == null) { - return null; - } - comment = comment.toUpperCase(); - int tcrIndex = comment.indexOf("ТКР"); - if (tcrIndex == -1) { - return null; - } - comment = comment.substring(tcrIndex + 3); - return comment.replaceAll("\\s+", ""); - } - private String getContractFromSpecif(String specif) { if (TextUtil.isEmpty(specif)) { return null; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/payment/PaymentInstructionOutboundService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/payment/PaymentInstructionOutboundService.java index 72cf231a4..ee1e59243 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/payment/PaymentInstructionOutboundService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/payment/PaymentInstructionOutboundService.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.service.payment; import java.math.BigDecimal; import java.time.Instant; +import java.util.Locale; import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; @@ -19,6 +20,7 @@ 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.messages.ClearingMessage; import ru.spcex.clearing.notification.NotificationSender; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -39,6 +41,7 @@ import ru.spcex.clearing.service.schedule.TradingTimeService; import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.clearing.session.stage.impl.GatewayRequester; import static ru.spcex.clearing.session.stage.impl.GatewayRequester.mapError; +import ru.spcex.clearing.util.LocaleUtil; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.platform.enumeration.CurrencyCode; import ru.spcex.platform.enumeration.ObjectType; @@ -51,6 +54,7 @@ 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.localization.SpringPropertiesLocalizer; import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD; import ru.spcex.platform.utils.text.TextUtil; import ru.spcex.platform.utils.validation.IValidator; @@ -78,12 +82,14 @@ public class PaymentInstructionOutboundService { private final TradingTimeService time; private final GatewayRequester gateway; private final NotificationSender notification; + private final SpringPropertiesLocalizer resolver; @Autowired public PaymentInstructionOutboundService(UserRoleVerification rights, IMessageResolver msgs, ImdgProvider imdgProvider, - Function validation, RegistryManager rgsMng, KafkaSender kafkaSender, AssetTBFProcessing assetsMng, DmiService dmiService, TradingTimeService time, GatewayRequester gateway, NotificationSender notification) { + Function validation, RegistryManager rgsMng, KafkaSender kafkaSender, AssetTBFProcessing assetsMng, DmiService dmiService, TradingTimeService time, GatewayRequester gateway, NotificationSender notification, + SpringPropertiesLocalizer resolver) { this.imdgProvider = imdgProvider; this.rights = rights; this.msgs = msgs; @@ -95,7 +101,7 @@ public class PaymentInstructionOutboundService { 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.sdf54Creator = new Sdf54Creator(imdgProvider, resolver); this.idGenerator = imdgProvider.getImdgIdGenerator(); this.rgsMng = rgsMng; this.kafkaSender = kafkaSender; @@ -103,6 +109,7 @@ public class PaymentInstructionOutboundService { this.dmiService = dmiService; this.time = time; this.gateway = gateway; + this.resolver = resolver; this.gateway.setName("PaymentInstructionOutboundService|PI"); this.notification = notification; } @@ -128,7 +135,10 @@ public class PaymentInstructionOutboundService { log.debug("all checks passed, accCred.id={}, accDeb.id={}, addressee.id={}, sender.id={}, amount: {}", accCred.getId(), accDeb.getId(), addressee.getId(), sender.getId(), amount); - String purpose = tcr != null ? "Возврат денежных средств, свободных от обязательств с ТКР " + tcr.getCode() + " ." : "Вывод средств."; + Locale locale = LocaleUtil.locale(accDeb); + String purpose = tcr != null ? + resolver.resolve(ClearingMessage.WithdrawalFreeFromTkr, locale, tcr.getCode()) : + resolver.resolve(ClearingMessage.WithdrawalOfFunds, locale); if (payload.getPaymentPurpose() != null) { String reqPmtPrpse = payload.getPaymentPurpose(); if (!(reqPmtPrpse.endsWith(".") || reqPmtPrpse.endsWith("!") || reqPmtPrpse.endsWith("?") || reqPmtPrpse.endsWith(";"))) { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java index 8ecb45f2c..c60eb806a 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java @@ -5,11 +5,11 @@ import java.util.Optional; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; -import ru.clearing.classes.statics.data.misc.Session; import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.enumeration.Section; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; @@ -42,11 +42,14 @@ public enum RegistryStep3ValidationRule implements IValidationRule relationImdg = context.obtainMap(IMDGDistributedNames.Map_Relation, Relation.class); - Imdg sessionImdg = context.obtainMap(IMDGDistributedNames.Map_Session, Session.class); - //Session activeSession = sessionImdg.getSingleObjectByID(validatedObject.getSessionId()); + String section = validatedObject.getSection(); + Section sctn = IEnumKey.getEnumByKey(Section.class, validatedObject.getSection()); + if (Section.CURR.equals(sctn)) { + section = Section.MKR.getKey(); + } Relation relation = relationImdg.getFirstObjectByFieldValues(Map.of( "consumerId", validatedObject.getCompanyId(), - "service", validatedObject.getSection())); + "service", section)); if (relation == null || (!ServiceStatus.Active.equalsByKey(relation.getServiceStatus()) && !ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus()))) { return of(ClearingError.ClearingUnavailableForCompany, validatedObject.getSection(), validatedObject.getCompanyId()); } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDepositReturn.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDepositReturn.java index 2c9085cef..c2714baa9 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDepositReturn.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDepositReturn.java @@ -171,8 +171,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage { .cm_t(cm_t) .tranAcc(tranAcc) .sessionId(sessionId) - .paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry()) - .paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry()) + .paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry() + " по итогу клиринга") + .paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry() + " по итогу клиринга") .currency(lm_t.getSecuritySymbol()) .build(); Pair.forEach(pmts, paymentInstructionImdg::insert); @@ -231,8 +231,8 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage { .cm_t(cm_t) .tranAcc(tranAcc) .sessionId(sessionId) - .paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry()) - .paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry()) + .paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry() + " по итогу клиринга") + .paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry() + " по итогу клиринга") .currency(lm_t.getSecuritySymbol()) .build(); Pair.forEach(pmts, paymentInstructionImdg::insert); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionReturnMkr.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionReturnMkr.java index 75b40ceee..7ed8bec5f 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionReturnMkr.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionReturnMkr.java @@ -204,8 +204,8 @@ public class FormingPaymentInstructionReturnMkr implements ISessionStage { .cm_t(cm_t) .tranAcc(tranAcc) .sessionId(sessionId) - .paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry()) - .paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry()) + .paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry() + " по итогу клиринга") + .paymentPurposeLmt("Возврат депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry() + " по итогу клиринга") .currency(lm_t.getSecuritySymbol()) .build(); Pair.forEach(pmts, paymentInstructionImdg::insert); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/LocaleUtil.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/LocaleUtil.java new file mode 100644 index 000000000..d1563e9bc --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/LocaleUtil.java @@ -0,0 +1,31 @@ +package ru.spcex.clearing.util; + +import java.util.Locale; +import ru.clearing.classes.statics.data.account.Account; +import ru.spcex.platform.enumeration.CurrencyCode; + +public class LocaleUtil { + private static final Locale ru = new Locale("ru"); + private static final Locale eng = new Locale("eng"); + + public static boolean isRus(Locale locale) { + return ru.equals(locale); + } + + public static Locale locale(Account acc) { + if (CurrencyCode.isRub(acc.getCurrency())) { + return ru; + } else { + return eng; + } + } + + public static Locale locale(String... currencyCode) { + for (String s : currencyCode) { + if (CurrencyCode.isRub(s)) { + return ru; + } + } + return eng; + } +} diff --git a/clearing-parent/clearing-service/src/main/resources/messages/clearing_eng.properties b/clearing-parent/clearing-service/src/main/resources/messages/clearing_eng.properties new file mode 100644 index 000000000..a1d9300cf --- /dev/null +++ b/clearing-parent/clearing-service/src/main/resources/messages/clearing_eng.properties @@ -0,0 +1,2 @@ +payment-instruction.purpose.withdrawal.tcr=Debt free cash withdrawal from TKR {0}. +payment-instruction.purpose.withdrawal=Debt free cash withdrawal. \ No newline at end of file diff --git a/clearing-parent/clearing-service/src/main/resources/messages/clearing_ru.properties b/clearing-parent/clearing-service/src/main/resources/messages/clearing_ru.properties new file mode 100644 index 000000000..fbad191dc --- /dev/null +++ b/clearing-parent/clearing-service/src/main/resources/messages/clearing_ru.properties @@ -0,0 +1,2 @@ +payment-instruction.purpose.withdrawal.tcr=Возврат средств, свободных от обязательств с ТКР {0}. +payment-instruction.purpose.withdrawal=Вывод средств. \ No newline at end of file diff --git a/clearing-parent/swt-exporter/src/main/java/ru/spcex/clearing/swt/exporter/services/exportimpl/DF12Exporter.java b/clearing-parent/swt-exporter/src/main/java/ru/spcex/clearing/swt/exporter/services/exportimpl/DF12Exporter.java index 3ffcf1729..1d9e4dede 100644 --- a/clearing-parent/swt-exporter/src/main/java/ru/spcex/clearing/swt/exporter/services/exportimpl/DF12Exporter.java +++ b/clearing-parent/swt-exporter/src/main/java/ru/spcex/clearing/swt/exporter/services/exportimpl/DF12Exporter.java @@ -1,5 +1,9 @@ package ru.spcex.clearing.swt.exporter.services.exportimpl; +import java.io.PrintWriter; +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.Objects; import com.hazelcast.aws.utility.StringUtil; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.misc.Session; @@ -15,11 +19,7 @@ import ru.spcex.platform.enumeration.Section; import ru.spcex.platform.enumeration.SessionType; import ru.spcex.platform.enumeration.SwtTable; import ru.spcex.platform.imdg.api.ImdgProvider; - -import java.io.PrintWriter; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.Objects; +import ru.spcex.platform.utils.enumeration.IEnumKey; @Service @@ -41,10 +41,10 @@ public class DF12Exporter extends AbstractExporterService { @Override protected String sectionForFileName(SwtExporterRequest req) { Session session = session(req); - if (!Section.FOND.equalsByKey(session.getSection())) { - throw new IllegalStateException("%s is only processed for FOND section".formatted(typeForFileName())); + if (!IEnumKey.contains(session.getSection(), Section.FOND, Section.MULT)) { + throw new IllegalStateException("%s is only processed for FOND/MULT section".formatted(typeForFileName())); } - if (SessionType.TRDT.equalsByKey(session.getSessionType())) { + if (SessionType.TRDT.equalsByKey(session.getSessionType()) || SessionType.UNIT.equalsByKey(session.getSessionType())) { return "fund"; } return "bond"; diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/localization/SpringPropertiesLocalizer.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/localization/SpringPropertiesLocalizer.java new file mode 100644 index 000000000..02c21d1f4 --- /dev/null +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/localization/SpringPropertiesLocalizer.java @@ -0,0 +1,41 @@ +package ru.spcex.platform.utils.localization; + +import java.util.Locale; +import org.springframework.context.support.ResourceBundleMessageSource; +import ru.spcex.platform.utils.enumeration.IEnumKey; + +/** + * Если в зависимостях не будет spring-context, кинет NoClassDefFound + */ +public class SpringPropertiesLocalizer { + private final ResourceBundleMessageSource errorMessages; + private Locale defaultLocale; + + public SpringPropertiesLocalizer(ResourceBundleMessageSource errorMessages) { + this.errorMessages = errorMessages; + this.defaultLocale = Locale.ENGLISH; + } + + public void setDefaultLocale(String defaultLocale) { + this.defaultLocale = new Locale(defaultLocale); + } + + public String resolve(IEnumKey msg, Locale locale, Object... args) { + return errorMessages.getMessage(msg.getKey(), args, locale); + } + + public String resolve(IEnumKey msg, Object... args) { + return errorMessages.getMessage(msg.getKey(), args, defaultLocale); + } + +// public String resolve(EnumMessage errorMessage, Locale locale) { +// Long id = errorMessage.getSubject().getId(); +// return errorMessages.getMessage(id.toString(), errorMessage.getArgs(), locale); + //String messageTemplate = +// if (errorMessage.getArgs().length > 0) +// return String.format(messageTemplate, errorMessage.getArgs()); +// else { +// return messageTemplate; +// } +// } +}