Compare commits
No commits in common. "af824c7d07e9742b81a4c097009ef716c3f152c1" and "021d7e861570784ab572eafc6ed04dd50103668c" have entirely different histories.
af824c7d07
...
021d7e8615
18 changed files with 360 additions and 1110 deletions
|
|
@ -8,9 +8,9 @@ server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b
|
||||||
# datasources
|
# datasources
|
||||||
# indic
|
# indic
|
||||||
ct.indic-data-source-settings.driver=com.ibm.db2.jcc.DB2Driver
|
ct.indic-data-source-settings.driver=com.ibm.db2.jcc.DB2Driver
|
||||||
ct.indic-data-source-settings.url=${DB_URL_INDIC:jdbc:db2://10.230.227.100:2668/cprosd22:currentSchema=INDIC;}
|
ct.indic-data-source-settings.url=${DB_URL_INDIC:jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=INDIC;}
|
||||||
ct.indic-data-source-settings.username=${USERNAME_INDIC:ros9appl}
|
ct.indic-data-source-settings.username=${USERNAME_INDIC:tester}
|
||||||
ct.indic-data-source-settings.password=${PASSWORD_INDIC:R0s9Appl}
|
ct.indic-data-source-settings.password=${PASSWORD_INDIC:tester}
|
||||||
|
|
||||||
# signal
|
# signal
|
||||||
ct.signal-data-source-settings.driver=org.postgresql.Driver
|
ct.signal-data-source-settings.driver=org.postgresql.Driver
|
||||||
|
|
|
||||||
5
pom.xml
5
pom.xml
|
|
@ -126,11 +126,6 @@
|
||||||
<version>3.0.4</version>
|
<version>3.0.4</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-junit-jupiter</artifactId>
|
<artifactId>mockito-junit-jupiter</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
@ -48,10 +47,5 @@ public class IndicDataSourceConfig extends DatabaseConfig {
|
||||||
sqlSessionFactoryBean.setTypeHandlersPackage("ru.nbch.credit_tracker.config.datasource.handlers");
|
sqlSessionFactoryBean.setTypeHandlersPackage("ru.nbch.credit_tracker.config.datasource.handlers");
|
||||||
return sqlSessionFactoryBean.getObject();
|
return sqlSessionFactoryBean.getObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "jdbcTemplateIndic")
|
|
||||||
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(@Qualifier("indicDataSource") DataSource dataSource) {
|
|
||||||
return new NamedParameterJdbcTemplate(dataSource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,18 @@ import java.util.List;
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface FlagsMapper {
|
public interface FlagsMapper {
|
||||||
|
|
||||||
List<FlagsService.RuPastDuarearData> findRuPastDuarearData(@Param("fids") List<Integer> fids);
|
List<FlagsService.FlagFidData> findFlagsDebt5000(@Param("fids") List<Integer> fids);
|
||||||
|
|
||||||
List<FlagsService.RuPaymtData> findRuPaymtData(@Param("fids") List<Integer> fids, @Param("reportedDate") LocalDate reportedDate);
|
List<FlagsService.FlagFidData> findFlag90ByPastDueArrear(@Param("fids") List<Integer> fids, @Param("reportedDate") LocalDate reportedDate);
|
||||||
|
|
||||||
|
List<FlagsService.FlagFidData> findFlag90ByRuPaymt(@Param("fids") List<Integer> fids, @Param("reportedDate") LocalDate reportedDate);
|
||||||
|
|
||||||
|
|
||||||
|
List<FlagsService.Debt5000Data> findFlagsDebt5000NewWithOrderBy(@Param("fids") List<Integer> fids);
|
||||||
|
|
||||||
|
|
||||||
|
List<FlagsService.Flag90DaysData> findFlag90ByPastDueArrearNewWithOrderBy(@Param("fids") List<Integer> fids);
|
||||||
|
|
||||||
|
|
||||||
|
List<FlagsService.Flag90DaysData> findFlag90ByRuPaymtNewWithOrderBy(@Param("fids") List<Integer> fids);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ public interface PhoneFidMapMapper {
|
||||||
List<PhoneFidMap> findFullPhoneFidMap(@Param("packageId") Integer packageId, @Param("offset") int offset, @Param("limit") int limit);
|
List<PhoneFidMap> findFullPhoneFidMap(@Param("packageId") Integer packageId, @Param("offset") int offset, @Param("limit") int limit);
|
||||||
|
|
||||||
void updatePhoneFidMaps(@Param("subjects") List<PhoneFidMap> subjects);
|
void updatePhoneFidMaps(@Param("subjects") List<PhoneFidMap> subjects);
|
||||||
|
void updatePhoneFid(@Param("subject") PhoneFidMap subject);
|
||||||
|
|
||||||
void updatePhoneFidMapsErrors(@Param("subjects") List<PhoneFidMap> subjects);
|
void updatePhoneFidMapsErrors(@Param("subjects") List<PhoneFidMap> subjects);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,22 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.dto.Hit;
|
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||||
|
|
@ -22,21 +36,6 @@ import ru.nbch.credit_tracker.service.xml.stax.MonitoringSignalResponseStaxXmlWr
|
||||||
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сервис периодического опроса официального сервиса сигналов на наличие новых отчетов по пакетам находящимся в статусе ON_MONITORING
|
* Сервис периодического опроса официального сервиса сигналов на наличие новых отчетов по пакетам находящимся в статусе ON_MONITORING
|
||||||
*/
|
*/
|
||||||
|
|
@ -60,9 +59,9 @@ public class MonitoringService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("monitoring-"));
|
// ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("monitoring-"));
|
||||||
long period = config.getMonitoringInterval() != null ? config.getMonitoringInterval() : 15;
|
// long period = config.getMonitoringInterval() != null ? config.getMonitoringInterval() : 15;
|
||||||
scheduler.scheduleAtFixedRate(this::monitor, 0, period, TimeUnit.MINUTES);
|
// scheduler.scheduleAtFixedRate(this::monitor, 0, period, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void monitor() {
|
private void monitor() {
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,10 @@ import ru.nbch.credit_tracker.entities.external_request.signals.Signals;
|
||||||
import ru.nbch.credit_tracker.entities.external_response.monitoring_report_error.MonitoringReportErrors;
|
import ru.nbch.credit_tracker.entities.external_response.monitoring_report_error.MonitoringReportErrors;
|
||||||
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
|
import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper;
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService2;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.PersonService;
|
import ru.nbch.credit_tracker.service.indic.PersonService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService2;
|
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||||
import ru.nbch.credit_tracker.service.signal.HitsService;
|
import ru.nbch.credit_tracker.service.signal.HitsService;
|
||||||
import ru.nbch.credit_tracker.service.signal.PhoneFidMapService;
|
import ru.nbch.credit_tracker.service.signal.PhoneFidMapService;
|
||||||
import ru.nbch.credit_tracker.service.signal.UserPackageService;
|
import ru.nbch.credit_tracker.service.signal.UserPackageService;
|
||||||
|
|
@ -44,8 +44,9 @@ public class SignalService {
|
||||||
private final HitsService hitsService;
|
private final HitsService hitsService;
|
||||||
private final UserPackageService userPackageService;
|
private final UserPackageService userPackageService;
|
||||||
private final PhoneFidMapService phoneFidMapService;
|
private final PhoneFidMapService phoneFidMapService;
|
||||||
private final PhoneService2 phoneService;
|
private final PhoneFidMapMapper phoneFidMapMapper;
|
||||||
private final FlagsService2 flagsService;
|
private final PhoneService phoneService;
|
||||||
|
private final FlagsService flagsService;
|
||||||
private final PersonService personService;
|
private final PersonService personService;
|
||||||
private final StaxXmlProcessor staxXmlProcessor;
|
private final StaxXmlProcessor staxXmlProcessor;
|
||||||
|
|
||||||
|
|
@ -55,14 +56,16 @@ public class SignalService {
|
||||||
HitsService hitsService,
|
HitsService hitsService,
|
||||||
UserPackageService userPackageService,
|
UserPackageService userPackageService,
|
||||||
PhoneFidMapService phoneFidMapService,
|
PhoneFidMapService phoneFidMapService,
|
||||||
PhoneService2 phoneService,
|
PhoneFidMapMapper mapper,
|
||||||
FlagsService2 flagsService,
|
PhoneService phoneService,
|
||||||
|
FlagsService flagsService,
|
||||||
PersonService personService,
|
PersonService personService,
|
||||||
StaxXmlProcessor staxXmlProcessor) {
|
StaxXmlProcessor staxXmlProcessor) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.hitsService = hitsService;
|
this.hitsService = hitsService;
|
||||||
this.userPackageService = userPackageService;
|
this.userPackageService = userPackageService;
|
||||||
this.phoneFidMapService = phoneFidMapService;
|
this.phoneFidMapService = phoneFidMapService;
|
||||||
|
this.phoneFidMapMapper = mapper;
|
||||||
this.phoneService = phoneService;
|
this.phoneService = phoneService;
|
||||||
this.flagsService = flagsService;
|
this.flagsService = flagsService;
|
||||||
this.personService = personService;
|
this.personService = personService;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,9 @@ package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сервис для завершения обработки пакетов находящихся в статусе PROCESSING
|
* Сервис для завершения обработки пакетов находящихся в статусе PROCESSING
|
||||||
* Запускается при старте приложения и отрабатывает 1 раз
|
* Запускается при старте приложения и отрабатывает 1 раз
|
||||||
|
|
@ -29,13 +26,13 @@ public class UpdateProcessingPackagesService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
log.info("Start updating processing packages");
|
// log.info("Start updating processing packages");
|
||||||
List<UserPackage> packages = signalService.findPackagesOnProcessing();
|
// List<UserPackage> packages = signalService.findPackagesOnProcessing();
|
||||||
for (UserPackage userPackage : packages) {
|
// for (UserPackage userPackage : packages) {
|
||||||
log.info("Updating flags for Package {}", userPackage.getPackageName());
|
// log.info("Updating flags for Package {}", userPackage.getPackageName());
|
||||||
process(userPackage.getId(), userPackage.getPackageName());
|
// process(userPackage.getId(), userPackage.getPackageName());
|
||||||
}
|
// }
|
||||||
log.info("Finish updating processing packages");
|
// log.info("Finish updating processing packages");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process(Integer packageId, String packageName) {
|
private void process(Integer packageId, String packageName) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
|
|
@ -9,14 +12,6 @@ import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сервис периодического обновления фидов и флагов просрочек по пакетам находящимся в статусе ON_MONITORING
|
* Сервис периодического обновления фидов и флагов просрочек по пакетам находящимся в статусе ON_MONITORING
|
||||||
* По обновленным пакетам формируется новый запрос постановки на мониторинг в официальный сервис сигналов
|
* По обновленным пакетам формируется новый запрос постановки на мониторинг в официальный сервис сигналов
|
||||||
|
|
@ -43,8 +38,8 @@ public class UpdatingFlagsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("updating-flags-"));
|
// ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("updating-flags-"));
|
||||||
scheduler.scheduleAtFixedRate(this::update, 0, updateFlagsInterval, TimeUnit.DAYS);
|
// scheduler.scheduleAtFixedRate(this::update, 0, updateFlagsInterval, TimeUnit.DAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package ru.nbch.credit_tracker.service.indic;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
@ -12,7 +11,9 @@ import ru.nbch.credit_tracker.mapper.indic.FlagsMapper;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class FlagsService {
|
public class FlagsService {
|
||||||
|
|
@ -28,17 +29,14 @@ public class FlagsService {
|
||||||
if (fids.isEmpty()) {
|
if (fids.isEmpty()) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
List<Integer> distinctFids = fids.stream()
|
List<Integer> distinctFids = fids.stream().distinct().toList();
|
||||||
.distinct()
|
|
||||||
.sorted(Comparator.naturalOrder())
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
log.debug("Fids count: {}", distinctFids.size());
|
log.debug("Fids count: {}", distinctFids.size());
|
||||||
Map<Integer, Integer> flags5000 = new HashMap<>();
|
Map<Integer, Integer> flags5000 = calcFlag5000(distinctFids);
|
||||||
Map<Integer, Integer> flags90DaysByPastDueArrear = new HashMap<>();
|
calcFlag500Test(distinctFids);
|
||||||
Map<Integer, Integer> flags90DaysByRuPaymt = new HashMap<>();
|
Map<Integer, Integer> flags90DaysByPastDueArrear = calcFlag90DaysByPastDueArrear(distinctFids);
|
||||||
findFlagsRuPastDueArrear(distinctFids, flags5000, flags90DaysByPastDueArrear);
|
calcFlag90DaysByPastDueArrearTest(distinctFids);
|
||||||
findFlagsRuPaymt(distinctFids, flags90DaysByRuPaymt);
|
Map<Integer, Integer> flags90DaysByRuPaymt = calcFlag90DaysByRuPaymt(distinctFids);
|
||||||
|
calcFlag90DaysByRuPaymtTest(distinctFids);
|
||||||
|
|
||||||
Map<Integer, FlagsData> result = new HashMap<>();
|
Map<Integer, FlagsData> result = new HashMap<>();
|
||||||
fids.forEach(fid -> {
|
fids.forEach(fid -> {
|
||||||
|
|
@ -48,7 +46,7 @@ public class FlagsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer flag90days = flags90DaysByPastDueArrear.get(fid);
|
Integer flag90days = flags90DaysByPastDueArrear.get(fid);
|
||||||
if (flag90days == null || flag90days == 0) {
|
if (flag90days == null) {
|
||||||
flag90days = flags90DaysByRuPaymt.get(fid);
|
flag90days = flags90DaysByRuPaymt.get(fid);
|
||||||
if (flag90days == null) {
|
if (flag90days == null) {
|
||||||
flag90days = 0;
|
flag90days = 0;
|
||||||
|
|
@ -61,118 +59,68 @@ public class FlagsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Выбирает данные из RU_PASTDUEARREAR и ищет по ним флаги просрочек
|
|
||||||
* По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT.
|
* По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT.
|
||||||
* Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то flag500 устанавливается в 1.
|
* Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то флаг устанавливается в 1.
|
||||||
* Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0.
|
* Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0.
|
||||||
*
|
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PASTDUEARREAR у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag5000Map - рещультирующая мапа флагов просрочек debt5000
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
*/
|
||||||
private void findFlagsRuPastDueArrear(List<Integer> fids, Map<Integer, Integer> flag5000Map, Map<Integer, Integer> flag90Days) {
|
private Map<Integer, Integer> calcFlag5000(List<Integer> fids) {
|
||||||
log.debug("Start calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
log.debug("Start calculating flag 5000");
|
||||||
List<RuPastDuarearData> ruPastDuarearDataList = mapper.findRuPastDuarearData(fids);
|
List<FlagFidData> rows = mapper.findFlagsDebt5000(fids);
|
||||||
|
Map<Integer, Integer> res = makeFidFlagMapByRs(fids, rows);
|
||||||
ruPastDuarearDataList.sort(Comparator.comparing(FlagsService.RuPastDuarearData::getFid) // сортируем сначала по фиду
|
log.debug("Complete calculating flag 5000");
|
||||||
.thenComparing(FlagsService.RuPastDuarearData::getReportedDate, Comparator.reverseOrder())); // Затем сортируем по REPORTED_DT по убыванию
|
return res;
|
||||||
|
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
|
||||||
|
|
||||||
for (Integer fid : fids) {
|
|
||||||
Iterator<RuPastDuarearData> iterator = ruPastDuarearDataList.iterator();
|
|
||||||
BigInteger prevAccSerialNum = null;
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
FlagsService.RuPastDuarearData data = iterator.next();
|
|
||||||
if (fid.equals(data.getFid())) {
|
|
||||||
if (flag5000Map.get(fid) == null) { // Первая запись в списке с макс REPORTED_DT. Нас интересует только она для флага 5000
|
|
||||||
if (prevAccSerialNum == null || !prevAccSerialNum.equals(data.getAccSerialNum())) {
|
|
||||||
if (data.getAmtPastDue() != null && data.getAmtPastDue().compareTo(BigDecimal.valueOf(5000)) >= 0) {
|
|
||||||
flag5000Map.put(fid, 1);
|
|
||||||
}
|
|
||||||
prevAccSerialNum = data.getAccSerialNum();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer flag90 = flag90Days.get(fid);
|
private void calcFlag500Test(List<Integer> fids) {
|
||||||
if (flag90 != null && flag90 == 1) {
|
log.debug("Start findFlagsDebt5000NewWithOrderBy");
|
||||||
iterator.remove();
|
mapper.findFlagsDebt5000NewWithOrderBy(fids);
|
||||||
break;
|
log.debug("Complete findFlagsDebt5000NewWithOrderBy");
|
||||||
}
|
|
||||||
|
|
||||||
if (flag90 == null || flag90 == 0) {
|
|
||||||
if (data.getDaysPastDue() != null) {
|
|
||||||
boolean has90daysFlag = data.getDaysPastDue().compareTo(BigInteger.valueOf(90)) >= 0 && !data.getReportedDate().isBefore(yearAgo);
|
|
||||||
if (has90daysFlag) {
|
|
||||||
flag90Days.put(fid, 1);
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// если мы так и не нашли флаги для этих фидов - выставляем их в 0
|
|
||||||
flag5000Map.putIfAbsent(fid, 0);
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
log.debug("Complete calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Выбирает данные из RU_PAYMT и ищет по ним флаги просрочек 90Days
|
* Флаг = 1, если выполняется хотя бы одно из условий:
|
||||||
*
|
* В INDIC.RU_PASTDUEARREAR или RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
*/
|
||||||
private void findFlagsRuPaymt(List<Integer> fids, Map<Integer, Integer> flag90Days) {
|
private Map<Integer, Integer> calcFlag90DaysByPastDueArrear(List<Integer> fids) {
|
||||||
log.debug("Start calculating flag 90 days by RU_PAPAYMT");
|
log.debug("Start calculating flag 90 by PastDueArrear");
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
||||||
List<RuPaymtData> ruPaymtDataList = mapper.findRuPaymtData(fids, yearAgo);
|
List<FlagFidData> rows = mapper.findFlag90ByPastDueArrear(fids, yearAgo);
|
||||||
ruPaymtDataList.sort(Comparator.comparing(RuPaymtData::getFid, Comparator.naturalOrder()));
|
Map<Integer, Integer> res = makeFidFlagMapByRs(fids, rows);
|
||||||
|
log.debug("Complete calculating flag 90 by PastDueArrear");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calcFlag90DaysByPastDueArrearTest(List<Integer> fids) {
|
||||||
|
log.debug("Start findFlag90ByPastDueArrearNewWithOrderBy");
|
||||||
|
mapper.findFlag90ByPastDueArrearNewWithOrderBy(fids);
|
||||||
|
log.debug("Complete findFlag90ByPastDueArrearNewWithOrderBy");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Integer, Integer> calcFlag90DaysByRuPaymt(List<Integer> fids) {
|
||||||
|
log.debug("Start calculating flag 90 by ruPaymt");
|
||||||
|
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
||||||
|
List<FlagFidData> rows = mapper.findFlag90ByRuPaymt(fids, yearAgo);
|
||||||
|
Map<Integer, Integer> res = makeFidFlagMapByRs(fids, rows);
|
||||||
|
log.debug("Complete calculating flag 90 by ruPaymt");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calcFlag90DaysByRuPaymtTest(List<Integer> fids) {
|
||||||
|
log.debug("Start findFlag90ByRuPaymtNewWithOrderBy");
|
||||||
|
mapper.findFlag90ByRuPaymtNewWithOrderBy(fids);
|
||||||
|
log.debug("Complete findFlag90ByRuPaymtNewWithOrderBy");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Integer, Integer> makeFidFlagMapByRs(List<Integer> fids, List<FlagFidData> rows) {
|
||||||
|
Map<Integer, Integer> result = new HashMap<>();
|
||||||
for (Integer fid : fids) {
|
for (Integer fid : fids) {
|
||||||
Iterator<RuPaymtData> iterator = ruPaymtDataList.iterator();
|
result.put(fid, 0);
|
||||||
while (iterator.hasNext()) {
|
|
||||||
RuPaymtData data = iterator.next();
|
|
||||||
if (fid.equals(data.getFid())) {
|
|
||||||
Integer flag90 = flag90Days.get(fid);
|
|
||||||
if (flag90 != null && flag90 == 1) {
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
for (FlagFidData row : rows) {
|
||||||
if (flag90 == null || flag90 == 0) {
|
result.put(row.getFid(), row.getFlag() != null ? row.getFlag() : 0);
|
||||||
if (data.getDaysPastDue() != null) {
|
|
||||||
boolean has90daysFlag = data.getDaysPastDue().compareTo(BigInteger.valueOf(90)) >= 0 && !data.getReportedDate().isBefore(yearAgo);
|
|
||||||
if (has90daysFlag) {
|
|
||||||
flag90Days.put(fid, 1);
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
iterator.remove();
|
|
||||||
}
|
}
|
||||||
} else {
|
return result;
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
log.debug("Complete calculating flag 90 days by RU_PAPAYMT");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -185,21 +133,23 @@ public class FlagsService {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
public static class FlagFidData {
|
||||||
@NoArgsConstructor
|
|
||||||
public static class RuPastDuarearData {
|
|
||||||
private Integer fid;
|
private Integer fid;
|
||||||
private BigInteger accSerialNum;
|
private Integer flag;
|
||||||
private LocalDate reportedDate;
|
|
||||||
private BigDecimal amtPastDue;
|
|
||||||
private BigInteger daysPastDue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
public static class Debt5000Data {
|
||||||
@NoArgsConstructor
|
private Integer fid;
|
||||||
public static class RuPaymtData {
|
private BigInteger accSerialNum;
|
||||||
|
private LocalDate reportedDate;
|
||||||
|
private BigDecimal amtPastDue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class Flag90DaysData {
|
||||||
private Integer fid;
|
private Integer fid;
|
||||||
private BigInteger daysPastDue;
|
private BigInteger daysPastDue;
|
||||||
private LocalDate reportedDate;
|
private LocalDate reportedDate;
|
||||||
|
|
|
||||||
|
|
@ -1,256 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service.indic;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class FlagsService2 {
|
|
||||||
|
|
||||||
private static final String SELECT_RU_PASDUEARREAR_DATA =
|
|
||||||
"SELECT FID, ACC_SERIAL_NUM, REPORTED_DT, AMT_PAST_DUE, DAYS_PAST_DUE " +
|
|
||||||
"FROM RU_PASTDUEARREAR " +
|
|
||||||
"WHERE FID IN (:fids) " +
|
|
||||||
"ORDER BY FID, REPORTED_DT DESC " +
|
|
||||||
"WITH UR";
|
|
||||||
|
|
||||||
private static final String SELECT_RU_PAYMT_DATA =
|
|
||||||
"SELECT FID, DAYS_PAST_DUE, REPORTED_DT " +
|
|
||||||
"FROM RU_PAYMT " +
|
|
||||||
"WHERE FID IN (:fids) " +
|
|
||||||
"AND REPORTED_DT >= :reportedDate " +
|
|
||||||
"WITH UR";
|
|
||||||
|
|
||||||
private final NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
public FlagsService2(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) {
|
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, FlagsService.FlagsData> findFlags(List<Integer> fids) {
|
|
||||||
if (fids.isEmpty()) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
List<Integer> distinctFids = fids.stream()
|
|
||||||
.distinct()
|
|
||||||
.sorted(Comparator.naturalOrder())
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
log.debug("Fids count: {}", distinctFids.size());
|
|
||||||
Map<Integer, Integer> flags5000 = new HashMap<>();
|
|
||||||
Map<Integer, Integer> flags90DaysByPastDueArrear = new HashMap<>();
|
|
||||||
Map<Integer, Integer> flags90DaysByRuPaymt = new HashMap<>();
|
|
||||||
findFlagsRuPastDueArrear(distinctFids, flags5000, flags90DaysByPastDueArrear);
|
|
||||||
findFlagsRuPaymt(distinctFids, flags90DaysByRuPaymt);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> result = new HashMap<>();
|
|
||||||
fids.forEach(fid -> {
|
|
||||||
Integer flagDebt5000 = flags5000.get(fid);
|
|
||||||
if (flagDebt5000 == null) {
|
|
||||||
flagDebt5000 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Integer flag90days = flags90DaysByPastDueArrear.get(fid);
|
|
||||||
if (flag90days == null || flag90days == 0) {
|
|
||||||
flag90days = flags90DaysByRuPaymt.get(fid);
|
|
||||||
if (flag90days == null) {
|
|
||||||
flag90days = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.put(fid, new FlagsService.FlagsData(flagDebt5000, flag90days));
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Выбирает данные из RU_PASTDUEARREAR и ищет по ним флаги просрочек
|
|
||||||
* По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT.
|
|
||||||
* Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то flag500 устанавливается в 1.
|
|
||||||
* Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0.
|
|
||||||
* <p>
|
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PASTDUEARREAR у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
|
||||||
*
|
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag5000Map - рещультирующая мапа флагов просрочек debt5000
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
|
||||||
private void findFlagsRuPastDueArrear(List<Integer> fids, Map<Integer, Integer> flag5000Map, Map<Integer, Integer> flag90Days) {
|
|
||||||
log.debug("Start calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
|
||||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
|
||||||
params.addValue("fids", fids);
|
|
||||||
|
|
||||||
jdbcTemplate.query(SELECT_RU_PASDUEARREAR_DATA, params, (ResultSet rs) -> {
|
|
||||||
Integer currentFid = null;
|
|
||||||
BigInteger prevAccSerialNum = null;
|
|
||||||
boolean processed5000ForCurrentId = false;
|
|
||||||
boolean processed90DaysForCurrentId = false;
|
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
Integer fid = rs.getInt("FID");
|
|
||||||
|
|
||||||
// Переход к новому fid. Сброс состояния
|
|
||||||
if (!fid.equals(currentFid)) {
|
|
||||||
currentFid = fid;
|
|
||||||
prevAccSerialNum = null;
|
|
||||||
processed5000ForCurrentId = false;
|
|
||||||
processed90DaysForCurrentId = false;
|
|
||||||
|
|
||||||
// Инициализируем значения по умолчанию
|
|
||||||
flag5000Map.putIfAbsent(fid, 0);
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если для текущего FID уже обработали оба флага, пропускаем остальные записи
|
|
||||||
if (processed5000ForCurrentId && processed90DaysForCurrentId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка флага 5000
|
|
||||||
if (!processed5000ForCurrentId && flag5000Map.get(fid) == 0) {
|
|
||||||
BigInteger currentAccSerialNum = getBigInteger(rs, "ACC_SERIAL_NUM");
|
|
||||||
BigDecimal amtPastDue = getBigDecimal(rs, "AMT_PAST_DUE");
|
|
||||||
|
|
||||||
if (prevAccSerialNum == null || !prevAccSerialNum.equals(currentAccSerialNum)) {
|
|
||||||
if (amtPastDue != null && amtPastDue.compareTo(BigDecimal.valueOf(5000)) >= 0) {
|
|
||||||
flag5000Map.put(fid, 1);
|
|
||||||
processed5000ForCurrentId = true;
|
|
||||||
}
|
|
||||||
prevAccSerialNum = currentAccSerialNum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка флага 90 дней
|
|
||||||
if (!processed90DaysForCurrentId) {
|
|
||||||
Integer currentFlag90 = flag90Days.get(fid);
|
|
||||||
|
|
||||||
if (currentFlag90 != null && currentFlag90 == 1) {
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFlag90 == null || currentFlag90 == 0) {
|
|
||||||
BigInteger days = getBigInteger(rs, "DAYS_PAST_DUE");
|
|
||||||
LocalDate reportedDate = rs.getObject("REPORTED_DT", LocalDate.class);
|
|
||||||
|
|
||||||
if (days != null) {
|
|
||||||
boolean has90daysFlag = days.compareTo(BigInteger.valueOf(90)) >= 0
|
|
||||||
&& reportedDate != null && !reportedDate.isBefore(yearAgo);
|
|
||||||
|
|
||||||
if (has90daysFlag) {
|
|
||||||
flag90Days.put(fid, 1);
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
log.debug("Complete calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Выбирает данные из RU_PAYMT и ищет по ним флаги просрочек 90Days
|
|
||||||
* <p>
|
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
|
||||||
*
|
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
|
||||||
private void findFlagsRuPaymt(List<Integer> fids, Map<Integer, Integer> flag90Days) {
|
|
||||||
log.debug("Start calculating flag 90 days by RU_PAPAYMT");
|
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
|
||||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
|
||||||
params.addValue("fids", fids);
|
|
||||||
params.addValue("reportedDate", yearAgo);
|
|
||||||
jdbcTemplate.query(SELECT_RU_PAYMT_DATA, params, rs -> {
|
|
||||||
Integer currentFid = null;
|
|
||||||
boolean processed90DaysForCurrentId = false;
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
Integer fid = rs.getInt("FID");
|
|
||||||
|
|
||||||
// Переход к новому fid. Сброс состояния
|
|
||||||
if (!fid.equals(currentFid)) {
|
|
||||||
currentFid = fid;
|
|
||||||
processed90DaysForCurrentId = false;
|
|
||||||
|
|
||||||
// Инициализируем значения по умолчанию
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка флага 90 дней
|
|
||||||
if (!processed90DaysForCurrentId) {
|
|
||||||
Integer currentFlag90 = flag90Days.get(fid);
|
|
||||||
|
|
||||||
if (currentFlag90 != null && currentFlag90 == 1) {
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFlag90 == null || currentFlag90 == 0) {
|
|
||||||
BigInteger days = getBigInteger(rs, "DAYS_PAST_DUE");
|
|
||||||
LocalDate date = rs.getObject("REPORTED_DT", LocalDate.class);
|
|
||||||
|
|
||||||
if (days != null) {
|
|
||||||
boolean has90daysFlag = days.compareTo(BigInteger.valueOf(90)) >= 0
|
|
||||||
&& date != null && !date.isBefore(yearAgo);
|
|
||||||
|
|
||||||
if (has90daysFlag) {
|
|
||||||
flag90Days.put(fid, 1);
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
log.debug("Complete calculating flag 90 days by RU_PAPAYMT");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private BigInteger getBigInteger(ResultSet rs, String columnName) {
|
|
||||||
try {
|
|
||||||
String value = rs.getString(columnName);
|
|
||||||
return value != null ? new BigInteger(value) : null;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal getBigDecimal(ResultSet rs, String columnName) {
|
|
||||||
try {
|
|
||||||
return rs.getBigDecimal(columnName);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -11,6 +11,7 @@ import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
|
@ -24,8 +25,13 @@ public class PhoneService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ищет фиды по номерам телефона
|
* Ищет фиды по номерам телефона
|
||||||
* @return Map: key - fid; value - {@link PhoneFidMap}
|
* @return Map: key - номер телефона; value - fid
|
||||||
*/
|
*/
|
||||||
|
public Map<String, Integer> findFidsPhoneData(List<PhoneFidMap> subjects) {
|
||||||
|
List<String> phones = subjects.stream().map(subject -> "9" + subject.getPhone()).toList();
|
||||||
|
return convertFidsDataToMap(mapper.findFids(phones));
|
||||||
|
}
|
||||||
|
|
||||||
public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) {
|
public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) {
|
||||||
Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();
|
Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();
|
||||||
List<String> phones = subjects.stream().
|
List<String> phones = subjects.stream().
|
||||||
|
|
@ -59,6 +65,23 @@ public class PhoneService {
|
||||||
return phoneFidMap;
|
return phoneFidMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, Integer> convertFidsDataToMap(List<FidsData> fidsData) {
|
||||||
|
if (fidsData == null || fidsData.isEmpty()) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
return fidsData.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
FidsData::getPhone,
|
||||||
|
Collectors.collectingAndThen(
|
||||||
|
Collectors.maxBy(
|
||||||
|
Comparator.comparing(FidsData::getFileSinceDate)
|
||||||
|
.thenComparing(FidsData::getFid)
|
||||||
|
),
|
||||||
|
data -> data.map(FidsData::getFid).orElse(null)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service.indic;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class PhoneService2 {
|
|
||||||
|
|
||||||
private static final String SELCT_FIDS = """
|
|
||||||
SELECT
|
|
||||||
pn.number,
|
|
||||||
pn.fid,
|
|
||||||
pn.file_since_dt
|
|
||||||
FROM PHONE_NORM pn
|
|
||||||
JOIN (SELECT DISTINCT fid FROM NAME) nf
|
|
||||||
ON nf.fid = pn.fid
|
|
||||||
WHERE number in (:phones)
|
|
||||||
ORDER BY
|
|
||||||
pn.number ASC,
|
|
||||||
pn.file_since_dt DESC,
|
|
||||||
pn.fid DESC
|
|
||||||
WITH UR
|
|
||||||
""";
|
|
||||||
|
|
||||||
private final NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
public PhoneService2(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) {
|
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ищет фиды по номерам телефона
|
|
||||||
*
|
|
||||||
* @return Map: key - fid; value - {@link PhoneFidMap}
|
|
||||||
*/
|
|
||||||
public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) {
|
|
||||||
Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();
|
|
||||||
|
|
||||||
List<String> phones = subjects.stream().
|
|
||||||
map(subject -> "9" + subject.getPhone())
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
subjects.sort(
|
|
||||||
Comparator.comparing(
|
|
||||||
PhoneFidMap::getPhone,
|
|
||||||
Comparator.naturalOrder()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
|
||||||
params.addValue("phones", phones);
|
|
||||||
|
|
||||||
List<FidsData> phonesByFid = jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) ->
|
|
||||||
new FidsData(rs.getInt("fid"), rs.getString("number"), rs.getObject("file_since_dt", LocalDate.class))
|
|
||||||
);
|
|
||||||
|
|
||||||
log.debug("Start merging fids");
|
|
||||||
for (PhoneFidMap phoneFid : subjects) {
|
|
||||||
Iterator<FidsData> iterator = phonesByFid.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
FidsData fidsData = iterator.next();
|
|
||||||
if (fidsData.getPhone().equals(9 + phoneFid.getPhone())) {
|
|
||||||
//fixme доступ по ссылке, страшно, придумать что-то еще
|
|
||||||
phoneFidMap.put(fidsData.getFid(), phoneFid);
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.debug("End merging fids");
|
|
||||||
|
|
||||||
return phoneFidMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public static class FidsData {
|
|
||||||
private Integer fid;
|
|
||||||
private String phone;
|
|
||||||
private LocalDate fileSinceDate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,22 +5,157 @@
|
||||||
|
|
||||||
<mapper namespace="ru.nbch.credit_tracker.mapper.indic.FlagsMapper">
|
<mapper namespace="ru.nbch.credit_tracker.mapper.indic.FlagsMapper">
|
||||||
|
|
||||||
<resultMap id="RuPastDuarearResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$RuPastDuarearData">
|
<resultMap id="FlagsFidDataResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$FlagFidData">
|
||||||
|
<result property="fid" column="fid" />
|
||||||
|
<result property="flag" column="flag" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="findFlagsDebt5000" resultMap="FlagsFidDataResultMap">
|
||||||
|
WITH latest AS (
|
||||||
|
SELECT
|
||||||
|
fid,
|
||||||
|
acc_serial_num,
|
||||||
|
amt_past_due,
|
||||||
|
ROW_NUMBER() OVER (PARTITION BY fid, acc_serial_num ORDER BY reported_dt DESC) AS rn
|
||||||
|
FROM RU_PASTDUEARREAR
|
||||||
|
WHERE fid IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
fid,
|
||||||
|
CASE WHEN SUM(CASE WHEN amt_past_due > 5000 THEN 1 ELSE 0 END) > 0
|
||||||
|
THEN 1 ELSE 0
|
||||||
|
END AS flag
|
||||||
|
FROM latest WHERE rn = 1
|
||||||
|
GROUP BY fid
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByPastDueArrear" resultMap="FlagsFidDataResultMap">
|
||||||
|
WITH latest AS (
|
||||||
|
SELECT
|
||||||
|
r.fid,
|
||||||
|
r.days_past_due,
|
||||||
|
ROW_NUMBER() OVER (PARTITION BY r.fid ORDER BY r.reported_dt DESC) AS rn
|
||||||
|
FROM RU_PASTDUEARREAR r
|
||||||
|
WHERE r.fid IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
AND r.reported_dt >= #{reportedDate}
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
fid,
|
||||||
|
CASE WHEN MAX(CASE WHEN days_past_due > 90 THEN 1 ELSE 0 END) = 1
|
||||||
|
THEN 1 ELSE 0
|
||||||
|
END AS flag
|
||||||
|
FROM latest WHERE rn = 1
|
||||||
|
GROUP BY fid
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByRuPaymt" resultMap="FlagsFidDataResultMap">
|
||||||
|
WITH latest AS (
|
||||||
|
SELECT
|
||||||
|
r.fid,
|
||||||
|
r.days_past_due,
|
||||||
|
ROW_NUMBER() OVER (PARTITION BY r.fid ORDER BY r.reported_dt DESC) AS rn
|
||||||
|
FROM RU_PAYMT r
|
||||||
|
WHERE r.fid IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
AND r.reported_dt >= #{reportedDate}
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
fid,
|
||||||
|
CASE WHEN MAX(CASE WHEN days_past_due > 90 THEN 1 ELSE 0 END) = 1
|
||||||
|
THEN 1 ELSE 0
|
||||||
|
END AS flag
|
||||||
|
FROM latest WHERE rn = 1
|
||||||
|
GROUP BY fid
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlagsDebt5000Old" resultMap="FlagsFidDataResultMap">
|
||||||
|
SELECT rp.FID as fid,
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1
|
||||||
|
FROM RU_PASTDUEARREAR rp2
|
||||||
|
WHERE rp2.FID = rp.FID
|
||||||
|
AND rp2.ACC_SERIAL_NUM = rp.ACC_SERIAL_NUM
|
||||||
|
AND rp2.REPORTED_DT = rp.MAX_REP_DATE
|
||||||
|
AND rp2.AMT_PAST_DUE > 5000) THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END as flag
|
||||||
|
FROM (SELECT FID,
|
||||||
|
ACC_SERIAL_NUM,
|
||||||
|
MAX(REPORTED_DT) as MAX_REP_DATE
|
||||||
|
FROM RU_PASTDUEARREAR
|
||||||
|
WHERE FID IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
GROUP BY FID, ACC_SERIAL_NUM) rp
|
||||||
|
GROUP BY rp.FID, rp.ACC_SERIAL_NUM, rp.MAX_REP_DATE
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByPastDueArrearOld" resultMap="FlagsFidDataResultMap">
|
||||||
|
SELECT rp.FID as fid,
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1
|
||||||
|
FROM RU_PASTDUEARREAR rp2
|
||||||
|
WHERE rp2.FID = rp.FID
|
||||||
|
AND rp2.REPORTED_DT >= #{reportedDate}
|
||||||
|
AND rp2.DAYS_PAST_DUE > 90) THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END as flag
|
||||||
|
FROM (SELECT FID,
|
||||||
|
DAYS_PAST_DUE
|
||||||
|
FROM RU_PASTDUEARREAR
|
||||||
|
WHERE FID IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
GROUP BY FID, DAYS_PAST_DUE) rp
|
||||||
|
GROUP BY rp.FID, rp.DAYS_PAST_DUE
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByRuPaymtOld" resultMap="FlagsFidDataResultMap">
|
||||||
|
SELECT rp.FID as fid,
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1
|
||||||
|
FROM RU_PAYMT rp2
|
||||||
|
WHERE rp2.FID = rp.FID
|
||||||
|
AND rp2.REPORTED_DT >= #{reportedDate}
|
||||||
|
AND rp2.DAYS_PAST_DUE > 90) THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END as flag
|
||||||
|
FROM (SELECT FID,
|
||||||
|
DAYS_PAST_DUE
|
||||||
|
FROM RU_PAYMT
|
||||||
|
WHERE FID IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
GROUP BY FID, DAYS_PAST_DUE) rp
|
||||||
|
GROUP BY rp.FID, rp.DAYS_PAST_DUE
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<resultMap id="Debt500ResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$Debt5000Data">
|
||||||
<result property="fid" column="fid" />
|
<result property="fid" column="fid" />
|
||||||
<result property="accSerialNum" column="ACC_SERIAL_NUM" />
|
<result property="accSerialNum" column="ACC_SERIAL_NUM" />
|
||||||
<result property="reportedDate" column="REPORTED_DT" />
|
<result property="reportedDate" column="REPORTED_DT" />
|
||||||
<result property="amtPastDue" column="AMT_PAST_DUE" />
|
<result property="amtPastDue" column="AMT_PAST_DUE" />
|
||||||
<result property="daysPastDue" column="DAYS_PAST_DUE" />
|
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap id="RuPaymtResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$RuPaymtData">
|
<select id="findFlagsDebt5000New" resultMap="Debt500ResultMap">
|
||||||
<result property="fid" column="fid" />
|
SELECT FID, ACC_SERIAL_NUM, REPORTED_DT, AMT_PAST_DUE
|
||||||
<result property="daysPastDue" column="DAYS_PAST_DUE" />
|
|
||||||
<result property="reportedDate" column="REPORTED_DT" />
|
|
||||||
</resultMap>
|
|
||||||
|
|
||||||
<select id="findRuPastDuarearData" resultMap="RuPastDuarearResultMap">
|
|
||||||
SELECT FID, ACC_SERIAL_NUM, REPORTED_DT, AMT_PAST_DUE, DAYS_PAST_DUE
|
|
||||||
FROM RU_PASTDUEARREAR
|
FROM RU_PASTDUEARREAR
|
||||||
WHERE FID IN
|
WHERE FID IN
|
||||||
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
|
@ -29,15 +164,65 @@
|
||||||
with UR
|
with UR
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="findRuPaymtData" resultMap="RuPaymtResultMap">
|
<select id="findFlagsDebt5000NewWithOrderBy" resultMap="Debt500ResultMap">
|
||||||
|
SELECT FID, ACC_SERIAL_NUM, REPORTED_DT, AMT_PAST_DUE
|
||||||
|
FROM RU_PASTDUEARREAR
|
||||||
|
WHERE fid IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
ORDER BY FID DESC
|
||||||
|
with UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<resultMap id="Flag90ByPastDueArrearResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$Flag90DaysData">
|
||||||
|
<result property="fid" column="fid" />
|
||||||
|
<result property="daysPastDue" column="DAYS_PAST_DUE" />
|
||||||
|
<result property="daysPastDue" column="REPORTED_DT" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="findFlag90ByPastDueArrearNew" resultMap="Flag90ByPastDueArrearResultMap">
|
||||||
|
SELECT FID, DAYS_PAST_DUE
|
||||||
|
FROM RU_PASTDUEARREAR
|
||||||
|
WHERE FID IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
AND REPORTED_DT >= #{reportedDate}
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByPastDueArrearNewWithOrderBy">
|
||||||
SELECT FID, DAYS_PAST_DUE, REPORTED_DT
|
SELECT FID, DAYS_PAST_DUE, REPORTED_DT
|
||||||
|
FROM RU_PASTDUEARREAR
|
||||||
|
WHERE FID IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
ORDER BY FID DESC
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByRuPaymtNew">
|
||||||
|
SELECT FID, DAYS_PAST_DUE
|
||||||
FROM RU_PAYMT
|
FROM RU_PAYMT
|
||||||
WHERE FID IN
|
WHERE FID IN
|
||||||
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
#{fid}
|
#{fid}
|
||||||
</foreach>
|
</foreach>
|
||||||
AND REPORTED_DT >= #{reportedDate}
|
AND REPORTED_DT >= #{reportedDate}
|
||||||
with UR
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByRuPaymtNewWithOrderBy">
|
||||||
|
SELECT FID, DAYS_PAST_DUE, REPORTED_DT
|
||||||
|
FROM RU_PAYMT
|
||||||
|
WHERE FID IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
ORDER BY FID DESC
|
||||||
|
WITH UR
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -42,6 +42,17 @@
|
||||||
</foreach>
|
</foreach>
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<update id="updatePhoneFid" parameterType="ru.nbch.credit_tracker.entities.dto.PhoneFidMap">
|
||||||
|
UPDATE signals_phone_fid_map
|
||||||
|
SET
|
||||||
|
fid = #{subject.fid},
|
||||||
|
flag_debt5000 = #{subject.flagDebt5000},
|
||||||
|
flag_90_12 = #{subject.flag90days},
|
||||||
|
calculated_at = #{subject.calculatedAt},
|
||||||
|
error_text = #{subject.errorText}
|
||||||
|
WHERE id = #{subject.id}
|
||||||
|
</update>
|
||||||
|
|
||||||
<update id="updatePhoneFidMapsErrors" parameterType="java.util.List">
|
<update id="updatePhoneFidMapsErrors" parameterType="java.util.List">
|
||||||
<foreach collection="subjects" item="subject" separator=";">
|
<foreach collection="subjects" item="subject" separator=";">
|
||||||
UPDATE signals_phone_fid_map
|
UPDATE signals_phone_fid_map
|
||||||
|
|
|
||||||
|
|
@ -1,280 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService2;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class FlagsService2Test {
|
|
||||||
|
|
||||||
private static final LocalDate INITIAL_DATE = LocalDate.parse("2025-09-25");
|
|
||||||
|
|
||||||
private static final String RU_PASTDUEAREAR_CREATE = """
|
|
||||||
create table RU_PASTDUEARREAR
|
|
||||||
(
|
|
||||||
FID INTEGER not null,
|
|
||||||
SERIAL_NUM BIGINT not null primary key,
|
|
||||||
ACC_SERIAL_NUM BIGINT not null,
|
|
||||||
REPORTED_DT DATE not null,
|
|
||||||
AMT_PAST_DUE DECIMAL(17, 2),
|
|
||||||
DAYS_PAST_DUE BIGINT
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String RU_PASTDUEAREAR_DROP = """
|
|
||||||
DROP TABLE IF EXISTS RU_PASTDUEARREAR;
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String RU_PAYMT_DROP = """
|
|
||||||
DROP TABLE IF EXISTS RU_PAYMT;
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String RU_PAYMT_CREATE = """
|
|
||||||
create table RU_PAYMT
|
|
||||||
(
|
|
||||||
FID INTEGER not null,
|
|
||||||
SERIAL_NUM BIGINT not null primary key,
|
|
||||||
DAYS_PAST_DUE INTEGER,
|
|
||||||
REPORTED_DT DATE not null
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String FILL_RU_PASTDUEARREAR = String.format("""
|
|
||||||
INSERT INTO RU_PASTDUEARREAR VALUES
|
|
||||||
(1, 1, 1, '%s', 36000.00, 159), -- просрочка 5000 и 90_days по этой записи
|
|
||||||
(2, 2, 2, '%s', 3200.00, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(2, 3, 2, '%s', 6700.00, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(2, 4, 2, '%s', 5700.00, null), -- просрочка 5000 по этой записи
|
|
||||||
(3, 5, 3, '%s', 300000000000.00, null),
|
|
||||||
(2, 6, 2, '%s', 0.00, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(4, 7, 4, '%s', 4000.00, null), -- нет просрочек
|
|
||||||
(5, 8, 5, '%s', 2000.31, 182), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 9, 5, '%s', 2000.31, 212), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 10, 5, '%s', 2000.31, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 11, 5, '%s', 2000.31, 273), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 12, 5, '%s', 2000.31, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 13, 5, '%s', 7000.31, 307), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 14, 5, '%s', 2000.31, 338), -- не макс reported_date для того же acc_serial_num, просрочка 90_days будет взята у этой записи
|
|
||||||
(5, 15, 5, '%s', 7000.31, 368), -- Просрочка 5000 будет взята у этой записи. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
(5, 16, 5, '%s', 2000.31, 399), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 17, 5, '%s', 5000.31, 5), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(6, 18, 6, '%s', 3000, null), -- Нет просрочки 5000, нет просрочки 90_days (90_days будет в RU_PAYMT)
|
|
||||||
(7, 19, 7, '%s', 5500, 90), -- не макс reported_date для того же acc_serial_num. 90_days будет взята отсюда
|
|
||||||
(7, 20, 7, '%s', 3000, null) -- Нет просрочки 5000. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
""",
|
|
||||||
calcLocalDateFromInitialDate("2025-05-31"),
|
|
||||||
calcLocalDateFromInitialDate("2021-12-29"),
|
|
||||||
calcLocalDateFromInitialDate("2022-01-28"),
|
|
||||||
calcLocalDateFromInitialDate("2025-04-06"),
|
|
||||||
calcLocalDateFromInitialDate("2025-01-14"),
|
|
||||||
calcLocalDateFromInitialDate("2021-11-29"),
|
|
||||||
calcLocalDateFromInitialDate("2025-12-06"),
|
|
||||||
calcLocalDateFromInitialDate("2021-04-01"),
|
|
||||||
calcLocalDateFromInitialDate("2021-05-01"),
|
|
||||||
calcLocalDateFromInitialDate("2021-05-31"),
|
|
||||||
calcLocalDateFromInitialDate("2021-07-01"),
|
|
||||||
calcLocalDateFromInitialDate("2021-07-31"),
|
|
||||||
calcLocalDateFromInitialDate("2021-08-04"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-08"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-09"),
|
|
||||||
calcLocalDateFromInitialDate("2021-11-04"),
|
|
||||||
calcLocalDateFromInitialDate("2022-01-04"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-09"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-09"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-10"));
|
|
||||||
|
|
||||||
private static final String FILL_RU_PAYMT = String.format("""
|
|
||||||
INSERT INTO RU_PAYMT VALUES
|
|
||||||
(1, 1, null, '%s'),
|
|
||||||
(2, 2, 30, '%s'),
|
|
||||||
(3, 3, null, '%s'),
|
|
||||||
(3, 4, 100, '%s'),
|
|
||||||
(4, 5, 10, '%s'),
|
|
||||||
(5, 6, 10, '%s'),
|
|
||||||
(6, 7, 90, '%s'),
|
|
||||||
(6, 8, 80, '%s'),
|
|
||||||
(7, 9, null, '%s'),
|
|
||||||
(8, 10, null, '%s'),
|
|
||||||
(8, 11, 83, '%s'),
|
|
||||||
(8, 12, 91, '%s'),
|
|
||||||
(9, 13, 100, '%s')
|
|
||||||
""",
|
|
||||||
calcLocalDateFromInitialDate("2024-11-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-10"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-15"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-15"),
|
|
||||||
calcLocalDateFromInitialDate("2023-11-15"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"));
|
|
||||||
|
|
||||||
|
|
||||||
private DataSource dataSource;
|
|
||||||
private NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
private FlagsService2 flagsService;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
dataSource = DataSourceBuilder.create()
|
|
||||||
.url("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=DB2;DATABASE_TO_LOWER=TRUE")
|
|
||||||
.driverClassName("org.h2.Driver")
|
|
||||||
.username("sa")
|
|
||||||
.password("")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
|
||||||
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PASTDUEAREAR_DROP);
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PAYMT_DROP);
|
|
||||||
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PASTDUEAREAR_CREATE);
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PAYMT_CREATE);
|
|
||||||
|
|
||||||
flagsService = new FlagsService2(jdbcTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlags() {
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PASTDUEARREAR);
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PAYMT);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPaymt() {
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PASTDUEARREAR);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPastduearreae() {
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PAYMT);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static LocalDate calcLocalDateFromInitialDate(String date) {
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
long daysPassed = ChronoUnit.DAYS.between(INITIAL_DATE, now);
|
|
||||||
return LocalDate.parse(date).plusDays(daysPassed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,218 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import ru.nbch.credit_tracker.mapper.indic.FlagsMapper;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
public class FlagsServiceTest {
|
|
||||||
|
|
||||||
private static final LocalDate INITIAL_DATE = LocalDate.parse("2025-09-25");
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
FlagsMapper flagsMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlags() {
|
|
||||||
FlagsService flagsService = new FlagsService(flagsMapper);
|
|
||||||
|
|
||||||
when(flagsMapper.findRuPastDuarearData(Mockito.anyList())).thenReturn(ruPastDuarearDataList);
|
|
||||||
when(flagsMapper.findRuPaymtData(Mockito.anyList(), Mockito.any())).thenReturn(ruPaymtDataList);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPaymt() {
|
|
||||||
FlagsService flagsService = new FlagsService(flagsMapper);
|
|
||||||
|
|
||||||
when(flagsMapper.findRuPastDuarearData(Mockito.anyList())).thenReturn(ruPastDuarearDataList);
|
|
||||||
when(flagsMapper.findRuPaymtData(Mockito.anyList(), Mockito.any())).thenReturn(new ArrayList<>());
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPastduearreae() {
|
|
||||||
FlagsService flagsService = new FlagsService(flagsMapper);
|
|
||||||
|
|
||||||
when(flagsMapper.findRuPastDuarearData(Mockito.anyList())).thenReturn(new ArrayList<>());
|
|
||||||
when(flagsMapper.findRuPaymtData(Mockito.anyList(), Mockito.any())).thenReturn(ruPaymtDataList);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private final List<FlagsService.RuPastDuarearData> ruPastDuarearDataList = new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
new FlagsService.RuPastDuarearData(1, BigInteger.valueOf(1), calcLocalDateFromInitialDate("2025-05-31"), BigDecimal.valueOf(36000.00), BigInteger.valueOf(159)), // просрочка 5000 и 90_days по этой записи
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2021-12-29"), BigDecimal.valueOf(3200.00), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2022-01-28"), BigDecimal.valueOf(6700.00), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2025-04-06"), BigDecimal.valueOf(5700.00), null), // просрочка 5000 по этой записи
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(3, BigInteger.valueOf(3), calcLocalDateFromInitialDate("2025-01-14"), BigDecimal.valueOf(300000000000.00), null),
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2021-11-29"), BigDecimal.valueOf(0.00), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(4, BigInteger.valueOf(4), calcLocalDateFromInitialDate("2025-12-06"), BigDecimal.valueOf(4000.00), null), // нет просрочек
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-04-01"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(182)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-05-01"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(212)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-05-31"), BigDecimal.valueOf(2000.31), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-07-01"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(273)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-07-31"), BigDecimal.valueOf(2000.31), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-08-04"), BigDecimal.valueOf(7000.31), BigInteger.valueOf(307)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2025-09-08"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(338)), // не макс reported_date для того же acc_serial_num, просрочка 90_days будет взята у этой записи
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(51), calcLocalDateFromInitialDate("2025-09-09"), BigDecimal.valueOf(7000.31), BigInteger.valueOf(368)), // Просрочка 5000 будет взята у этой записи. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-11-04"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(399)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2022-01-04"), BigDecimal.valueOf(5000.31), BigInteger.valueOf(5)), // не макс reported_date для того же acc_serial_num
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(6, BigInteger.valueOf(6), calcLocalDateFromInitialDate("2025-09-09"), BigDecimal.valueOf(3000), null), // Нет просрочки 5000, нет просрочки 90_days (90_days будет в RU_PAYMT)
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(7, BigInteger.valueOf(7), calcLocalDateFromInitialDate("2025-09-09"), BigDecimal.valueOf(5500), BigInteger.valueOf(90)), // не макс reported_date для того же acc_serial_num. 90_days будет взята отсюда
|
|
||||||
new FlagsService.RuPastDuarearData(7, BigInteger.valueOf(7), calcLocalDateFromInitialDate("2025-09-10"), BigDecimal.valueOf(3000), null) // Нет просрочки 5000. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
private final List<FlagsService.RuPaymtData> ruPaymtDataList = new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
new FlagsService.RuPaymtData(1, null, calcLocalDateFromInitialDate("2024-11-09")),
|
|
||||||
new FlagsService.RuPaymtData(2, BigInteger.valueOf(30), calcLocalDateFromInitialDate("2024-11-09")),
|
|
||||||
new FlagsService.RuPaymtData(3, null, calcLocalDateFromInitialDate("2024-11-10")),
|
|
||||||
new FlagsService.RuPaymtData(3, BigInteger.valueOf(100), calcLocalDateFromInitialDate("2024-11-15")),
|
|
||||||
new FlagsService.RuPaymtData(4, BigInteger.valueOf(10), calcLocalDateFromInitialDate("2024-11-15")),
|
|
||||||
new FlagsService.RuPaymtData(5, BigInteger.valueOf(10), calcLocalDateFromInitialDate("2023-11-15")),
|
|
||||||
new FlagsService.RuPaymtData(6, BigInteger.valueOf(90), calcLocalDateFromInitialDate("2024-11-09")),
|
|
||||||
new FlagsService.RuPaymtData(6, BigInteger.valueOf(80), calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(7, null, calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(8, null, calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(8, BigInteger.valueOf(83), calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(8, BigInteger.valueOf(91), calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(9, BigInteger.valueOf(100), calcLocalDateFromInitialDate("2024-10-09"))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
private LocalDate calcLocalDateFromInitialDate(String date) {
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
long daysPassed = ChronoUnit.DAYS.between(INITIAL_DATE, now);
|
|
||||||
return LocalDate.parse(date).plusDays(daysPassed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
|
||||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService2;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
public class PhoneService2Test {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void defineFidByPhoneTest() {
|
|
||||||
PhoneService2 phoneService = new PhoneService2(jdbcTemplate);
|
|
||||||
|
|
||||||
fidsDataWithEqualSinceDt.sort(byDbOrder);
|
|
||||||
when(jdbcTemplate.query(anyString(), any(MapSqlParameterSource.class), any(RowMapper.class))).thenReturn(fidsDataWithEqualSinceDt);
|
|
||||||
|
|
||||||
List<PhoneFidMap> phoneFidMap = new ArrayList<>();
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1111").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1112").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1113").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1114").build());
|
|
||||||
|
|
||||||
Map<Integer, PhoneFidMap> res = phoneService.defineFidByPhone(phoneFidMap);
|
|
||||||
Assertions.assertEquals(3, res.size());
|
|
||||||
Assertions.assertEquals("1111", res.get(124).getPhone());
|
|
||||||
Assertions.assertEquals("1112", res.get(125).getPhone());
|
|
||||||
Assertions.assertEquals("1114", res.get(126).getPhone());
|
|
||||||
}
|
|
||||||
|
|
||||||
private final List<PhoneService2.FidsData> fidsDataWithEqualSinceDt = new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
new PhoneService2.FidsData(123, "91111", LocalDate.of(2025, 9, 10)),
|
|
||||||
new PhoneService2.FidsData(124, "91111", LocalDate.of(2025, 9, 10)),
|
|
||||||
new PhoneService2.FidsData(125, "91112", LocalDate.of(2024, 10, 10)),
|
|
||||||
new PhoneService2.FidsData(126, "91114", LocalDate.of(2024, 10, 11))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Comparator<PhoneService2.FidsData> byDbOrder =
|
|
||||||
Comparator.comparing(PhoneService2.FidsData::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC
|
|
||||||
.thenComparing(PhoneService2.FidsData::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC
|
|
||||||
.thenComparing(PhoneService2.FidsData::getFid, Comparator.reverseOrder());
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue