diff --git a/src/main/java/ru/nbch/credit_tracker/CreditTrackerApplication.java b/src/main/java/ru/nbch/credit_tracker/CreditTrackerApplication.java index 3dc981c..891ec93 100644 --- a/src/main/java/ru/nbch/credit_tracker/CreditTrackerApplication.java +++ b/src/main/java/ru/nbch/credit_tracker/CreditTrackerApplication.java @@ -3,39 +3,12 @@ package ru.nbch.credit_tracker; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; -import ru.nbch.credit_tracker.service.indic.FlagsService; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; @SpringBootApplication public class CreditTrackerApplication { public static void main(String[] args) { ConfigurableApplicationContext ctx = SpringApplication.run(CreditTrackerApplication.class, args); - List fids = new ArrayList<>(); - fids.add(11085548); - fids.add(16442833); - fids.add(109128766); - fids.add(115150769); - fids.add(16442929); - fids.add(114429070); - fids.add(108696892); - FlagsService flagService = ctx.getBean(FlagsService.class); - Map oldMap = flagService.findFlags(fids); - Map newMap = flagService.findFlags2(fids); - System.out.println(oldMap); - System.out.println(newMap); - for (Integer fid : fids) { - FlagsService.FlagsData oldValue = oldMap.get(fid); - FlagsService.FlagsData newValue = newMap.get(fid); - System.out.println("FID: " + fid); - System.out.println("OLD: " + oldValue.getFlagDebt5000() +"|" +oldValue.getFlag90days()); - System.out.println("NEW: " + newValue.getFlagDebt5000() +"|" +newValue.getFlag90days()); - System.out.println("_________________________________"); - } - System.exit(0); // UpdateProcessingPackagesService updateProcessingPackagesService = ctx.getBean(UpdateProcessingPackagesService.class); // MonitoringService monitoringService = ctx.getBean(MonitoringService.class); // UpdatingFlagsService updatingFlagsService = ctx.getBean(UpdatingFlagsService.class); diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/indic/FlagsMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/indic/FlagsMapper.java index 1aa12be..a8c768b 100644 --- a/src/main/java/ru/nbch/credit_tracker/mapper/indic/FlagsMapper.java +++ b/src/main/java/ru/nbch/credit_tracker/mapper/indic/FlagsMapper.java @@ -10,12 +10,8 @@ import java.util.List; @Mapper public interface FlagsMapper { - List findFlagsDebt5000(@Param("fids") List fids); - - List findFlag90ByPastDueArrear(@Param("fids") List fids, @Param("reportedDate") LocalDate reportedDate); - - List findFlag90ByRuPaymt(@Param("fids") List fids, @Param("reportedDate") LocalDate reportedDate); - List findRuPastDuarearData(@Param("fids") List fids); + List findRuPaymtData(@Param("fids") List fids, @Param("reportedDate") LocalDate reportedDate); + } diff --git a/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java b/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java index 4157c93..12a2134 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java @@ -25,36 +25,6 @@ public class FlagsService { } public Map findFlags(List fids) { - if (fids.isEmpty()) { - return new HashMap<>(); - } - List distinctFids = fids.stream().distinct().toList(); - log.debug("Fids count: {}", distinctFids.size()); - Map flags5000 = calcFlag5000(distinctFids); - Map flags90DaysByPastDueArrear = calcFlag90DaysByPastDueArrear(distinctFids); - Map flags90DaysByRuPaymt = calcFlag90DaysByRuPaymt(distinctFids); - - Map 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 FlagsData(flagDebt5000, flag90days)); - }); - - return result; - } - - public Map findFlags2(List fids) { if (fids.isEmpty()) { return new HashMap<>(); } @@ -66,8 +36,9 @@ public class FlagsService { log.debug("Fids count: {}", distinctFids.size()); Map flags5000 = new HashMap<>(); Map flags90DaysByPastDueArrear = new HashMap<>(); + Map flags90DaysByRuPaymt = new HashMap<>(); findFlagsRuPastDueArrear(distinctFids, flags5000, flags90DaysByPastDueArrear); - Map flags90DaysByRuPaymt = calcFlag90DaysByRuPaymt(distinctFids); + findFlagsRuPaymt(distinctFids, flags90DaysByRuPaymt); Map result = new HashMap<>(); fids.forEach(fid -> { @@ -90,10 +61,17 @@ public class FlagsService { } /** - * Выбирает дату из RU_PASTDUEARREAR и ищет по ним флаги просрочек - * @param fids - отсортирован по возрастанию фидов + * Выбирает данные из RU_PASTDUEARREAR и ищет по ним флаги просрочек + * По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT. + * Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то flag500 устанавливается в 1. + * Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0. + * + * flag90Days = 1, если выполняется хотя бы одно из условий: + * В INDIC.RU_PASTDUEARREAR у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев. + * Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0. + * @param fids - отсортирован по возрастанию фидов * @param flag5000Map - рещультирующая мапа флагов просрочек debt5000 - * @param flag90Days - рещультирующая мапа флагов просрочек 90_days + * @param flag90Days - рещультирующая мапа флагов просрочек 90_days */ private void findFlagsRuPastDueArrear(List fids, Map flag5000Map, Map flag90Days) { log.debug("Start calculating flag 5000 and 90 days by RU_PASTDUEARREAR"); @@ -150,50 +128,49 @@ public class FlagsService { } /** - * По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT. - * Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то флаг устанавливается в 1. - * Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0. - */ - private Map calcFlag5000(List fids) { - log.debug("Start calculating flag 5000"); - List rows = mapper.findFlagsDebt5000(fids); - Map res = makeFidFlagMapByRs(fids, rows); - log.debug("Complete calculating flag 5000"); - return res; - } - - /** - * Флаг = 1, если выполняется хотя бы одно из условий: - * В INDIC.RU_PASTDUEARREAR или RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев. + * Выбирает данные из RU_PAYMT и ищет по ним флаги просрочек 90Days + * + * flag90Days = 1, если выполняется хотя бы одно из условий: + * В INDIC.RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев. * Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0. + * @param fids - отсортирован по возрастанию фидов + * @param flag90Days - рещультирующая мапа флагов просрочек 90_days */ - private Map calcFlag90DaysByPastDueArrear(List fids) { - log.debug("Start calculating flag 90 by PastDueArrear"); + private void findFlagsRuPaymt(List fids, Map flag90Days) { LocalDate yearAgo = LocalDate.now().minusYears(1); - List rows = mapper.findFlag90ByPastDueArrear(fids, yearAgo); - Map res = makeFidFlagMapByRs(fids, rows); - log.debug("Complete calculating flag 90 by PastDueArrear"); - return res; - } + List ruPaymtDataList = mapper.findRuPaymtData(fids, yearAgo); + ruPaymtDataList.sort(Comparator.comparing(RuPaymtData::getFid, Comparator.naturalOrder())); - private Map calcFlag90DaysByRuPaymt(List fids) { - log.debug("Start calculating flag 90 by ruPaymt"); - LocalDate yearAgo = LocalDate.now().minusYears(1); - List rows = mapper.findFlag90ByRuPaymt(fids, yearAgo); - Map res = makeFidFlagMapByRs(fids, rows); - log.debug("Complete calculating flag 90 by ruPaymt"); - return res; - } - - private Map makeFidFlagMapByRs(List fids, List rows) { - Map result = new HashMap<>(); for (Integer fid : fids) { - result.put(fid, 0); + Iterator iterator = ruPaymtDataList.iterator(); + 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; + } + + 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(); + } + } + } + } + flag90Days.putIfAbsent(fid, 0); } - for (FlagFidData row : rows) { - result.put(row.getFid(), row.getFlag() != null ? row.getFlag() : 0); - } - return result; } @Getter @@ -204,13 +181,6 @@ public class FlagsService { private Integer flag90days; } - @Getter - @Setter - public static class FlagFidData { - private Integer fid; - private Integer flag; - } - @Getter @Setter @AllArgsConstructor @@ -225,7 +195,9 @@ public class FlagsService { @Getter @Setter - public static class Flag90DaysData { + @AllArgsConstructor + @NoArgsConstructor + public static class RuPaymtData { private Integer fid; private BigInteger daysPastDue; private LocalDate reportedDate; diff --git a/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml b/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml index ab3bb98..a186744 100644 --- a/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml +++ b/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml @@ -5,11 +5,6 @@ - - - - - @@ -18,6 +13,12 @@ + + + + + + - - - - - + SELECT FID, DAYS_PAST_DUE, REPORTED_DT + FROM RU_PAYMT + WHERE FID IN + + #{fid} + + AND REPORTED_DT >= #{reportedDate} + with UR \ No newline at end of file diff --git a/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java b/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java index 3191a7c..2284db9 100644 --- a/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java +++ b/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java @@ -29,12 +29,11 @@ public class FlagsServiceTest { FlagsMapper flagsMapper; @Test - public void testfindFlagsWithoutRuPaymt() { - + public void testfindFlags() { FlagsService flagsService = new FlagsService(flagsMapper); when(flagsMapper.findRuPastDuarearData(Mockito.anyList())).thenReturn(ruPastDuarearDataList); - when(flagsMapper.findFlag90ByRuPaymt(Mockito.anyList(), Mockito.any())).thenReturn(new ArrayList<>()); + when(flagsMapper.findRuPaymtData(Mockito.anyList(), Mockito.any())).thenReturn(ruPaymtDataList); List fids = new ArrayList<>(List.of( 1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR @@ -48,7 +47,50 @@ public class FlagsServiceTest { 9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT ); - Map resultMap = flagsService.findFlags2(fids); + Map 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 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 resultMap = flagsService.findFlags(fids); Assertions.assertEquals(9, resultMap.size()); Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000()); @@ -73,6 +115,50 @@ public class FlagsServiceTest { } + @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 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 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 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 по этой записи @@ -106,6 +192,24 @@ public class FlagsServiceTest { ) ); + private final List 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);