Untitled
unknown
plain_text
a year ago
28 kB
0
Indexable
Never
package com.lwo.processing.issuingservice.util.document; import com.lwo.processing.commonapi.bean.cache.DimensionCache; import com.lwo.processing.commonapi.dim.dto.DimItemDto; import com.lwo.processing.issuingservice.model.CardEntity; import com.lwo.processing.issuingservice.model.EventEntity; import com.lwo.processing.issuingservice.model.TransactionEntity; import com.lwo.processing.issuingservice.repository.EventRepository; import com.lwo.processing.issuingservice.service.CommissionService; import com.lwo.processing.issuingservice.util.cache.IssuingServiceCache; import com.lwo.processing.springcore.config.exception.BaseRestResponseException; import lombok.RequiredArgsConstructor; import org.springframework.context.MessageSource; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.*; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; import static org.springframework.context.i18n.LocaleContextHolder.getLocale; @Component @RequiredArgsConstructor public class StatementPreparation { private final EventRepository eventRepository; private final CommissionService commissionService; private final IssuingServiceCache issuingServiceCache; private final DimensionCache<DimItemDto> dimensionCache; private final MessageSource messageSource; private static final String NO_CARD_TRANSACTIONS_KEY = "NoCardTransactions"; private static final String ACCOUNT_STATEMENT_DATE_FORMAT = "dd.MM.yyyy"; public Map<String, String> groupAccountTransactionsByCards(List<TransactionEntity> accountTransactions, List<TransactionEntity> financialCommissionsTransactions, List<CardEntity> accountCards, Long accountId, ZonedDateTime startTime, ZonedDateTime endTime) { Map<String, String> cardTransactions = new HashMap<>(); List<TransactionEntity> transactionsWithNoCard; List<EventEntity> eventsBySpecificCard; String stringValueOfTransactionsWithNoCard; List<TransactionEntity> transactionsBySpecificCard; List<TransactionEntity> financialCommissionsTransactionsBySpecificCard; String stringValueOfTransactionsBySpecificCard; for (CardEntity accountCard : accountCards) { transactionsBySpecificCard = accountTransactions.stream() .filter(transaction -> Objects.equals(transaction.getCardId(), accountCard.getCardId())) .toList(); financialCommissionsTransactionsBySpecificCard = financialCommissionsTransactions.stream() .filter(transaction -> Objects.equals(transaction.getCardId(), accountCard.getCardId())) .toList(); eventsBySpecificCard = eventRepository.findAllByAccountIdAndCardIdAndRequestTimeBetweenAndUnblockingTypeIdIsNullOrderByRequestTimeDesc(accountId, accountCard.getCardId(), startTime, endTime); stringValueOfTransactionsBySpecificCard = writeTransactionsBySpecificCardAsString(transactionsBySpecificCard, financialCommissionsTransactionsBySpecificCard, eventsBySpecificCard, accountCard); cardTransactions.put(accountCard.getCardNumberTruncated(), stringValueOfTransactionsBySpecificCard); } transactionsWithNoCard = accountTransactions.stream() .filter(transaction -> transaction.getCardId() == null) .toList(); stringValueOfTransactionsWithNoCard = writeTransactionsWithNoCardsString(transactionsWithNoCard); cardTransactions.put(NO_CARD_TRANSACTIONS_KEY, stringValueOfTransactionsWithNoCard); return cardTransactions; } public Map<String, String> groupTransactionsByCards(List<TransactionEntity> accountTransactions, List<TransactionEntity> financialCommissionsTransactions, List<CardEntity> accountCards, Long accountId, ZonedDateTime startTime, ZonedDateTime endTime) { Map<String, String> cardTransactions = new HashMap<>(); List<EventEntity> eventsBySpecificCard; List<TransactionEntity> transactionsBySpecificCard; List<TransactionEntity> financialCommissionsTransactionsBySpecificCard; String stringValueOfTransactionsBySpecificCard; for (CardEntity accountCard : accountCards) { transactionsBySpecificCard = accountTransactions.stream() .filter(transaction -> Objects.equals(transaction.getCardId(), accountCard.getCardId())) .toList(); financialCommissionsTransactionsBySpecificCard = financialCommissionsTransactions.stream() .filter(transaction -> Objects.equals(transaction.getCardId(), accountCard.getCardId())) .toList(); eventsBySpecificCard = eventRepository.findAllByAccountIdAndCardIdAndRequestTimeBetweenAndUnblockingTypeIdIsNullOrderByRequestTimeDesc(accountId, accountCard.getCardId(), startTime, endTime); stringValueOfTransactionsBySpecificCard = writeTransactionsBySpecificCardAsString(transactionsBySpecificCard, financialCommissionsTransactionsBySpecificCard, eventsBySpecificCard, accountCard); cardTransactions.put(accountCard.getCardNumberTruncated(), stringValueOfTransactionsBySpecificCard); } System.out.println(cardTransactions); return cardTransactions; } public void clearCardTransaction(Map<String, String> cardTransactions) { List<String> emptyCardNumbers = new ArrayList<>(); for (Map.Entry<String, String> card : cardTransactions.entrySet()) { if (card.getKey().equals("NoCardTransactions")) { continue; } String[] cardHolderNameAndTransactions = card.getValue().split("\n"); if (cardHolderNameAndTransactions.length == 1) { emptyCardNumbers.add(card.getKey()); } } for (String emptyCardNumber : emptyCardNumbers) { cardTransactions.remove(emptyCardNumber); } } public void checkPeriod(LocalDate startDate, LocalDate endDate) { if (startDate.isAfter(endDate)) { throw new BaseRestResponseException("ISSUING_37", "ISSUING_37", "ISSUING_37", messageSource.getMessage("ISSUING_37", null, getLocale())); } if (startDate.plusDays(90).isBefore(endDate)) { throw new BaseRestResponseException("ISSUING_38", "ISSUING_38", "ISSUING_38", messageSource.getMessage("ISSUING_38", null, getLocale())); } } private String writeTransactionsWithNoCardsString(List<TransactionEntity> transactionsWithNoCard) { StringBuilder stringValueOfTransactionsWithNoCard = new StringBuilder(); String amount; String description; for (TransactionEntity transaction : transactionsWithNoCard) { amount = processAmountForCustomerReadability(transaction.getAmount()); description = Objects.nonNull(transaction.getDescription()) ? transaction.getDescription() : ""; stringValueOfTransactionsWithNoCard .append(transaction.getBusinessDate().format(DateTimeFormatter.ofPattern(ACCOUNT_STATEMENT_DATE_FORMAT))) .append("|") .append(amount) .append("|") .append(description) .append("\n"); } return stringValueOfTransactionsWithNoCard.toString(); } private String writeTransactionsBySpecificCardAsString(List<TransactionEntity> transactionsBySpecificCard, List<TransactionEntity> commissionsTransactionsBySpecificCard, List<EventEntity> eventsBySpecificCard, CardEntity specificCard) { StringBuilder stringValueOfTransactionsBySpecificCard = new StringBuilder(); stringValueOfTransactionsBySpecificCard.append(specificCard.getPrintedName()).append("\n"); /* String amount; String notFormattedDateTime; String formattedDateTime; String description; for (TransactionEntity transaction : transactionsBySpecificCard) { amount = processAmountForCustomerReadability(transaction.getAmount()); if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("Date")) && Objects.nonNull(transaction.getTransactionDate().get("Time"))) { notFormattedDateTime = String.valueOf(transaction.getTransactionDate().get("Date")).concat(String.valueOf(transaction.getTransactionDate().get("Time"))); formattedDateTime = formatDateAndTime(notFormattedDateTime); } else { formattedDateTime = ""; } } else { formattedDateTime = ""; } description = Objects.nonNull(transaction.getDescription()) ? transaction.getDescription() : ""; stringValueOfTransactionsBySpecificCard .append(transaction.getTransactionTime().format(DateTimeFormatter.ofPattern(ACCOUNT_STATEMENT_DATE_FORMAT))) .append("|") .append(amount) .append("|") .append(formattedDateTime) .append("|") .append(description) .append("\n"); } */ String iterator; String procDate; String status; String transactionDateTime; String description; String mcc; String place; String rrn; String authCode; String currency; String currencyAmount; String commission; String amount; List<Long> commissionsTransactionTypes = commissionService.getCommissionTransactionTypes() .stream() .map(DimItemDto::getDimId) .collect(Collectors.toList()); List<ZonedDateTime> transactionDates = transactionsBySpecificCard.stream().map(TransactionEntity::getTransactionTime).toList(); List<ZonedDateTime> eventDates = eventsBySpecificCard.stream().map(EventEntity::getRequestTime).toList(); List<ZonedDateTime> allDates = new ArrayList<>(); eventDates = eventDates.stream().sorted(Comparator.reverseOrder()).distinct().collect(Collectors.toList()); transactionDates = transactionDates.stream().sorted(Comparator.reverseOrder()).distinct().collect(Collectors.toList()); allDates.addAll(eventDates); allDates.addAll(transactionDates); // allDates = allDates.stream().sorted(Comparator.reverseOrder()).distinct().collect(Collectors.toList()); //DimItemDto nonFinFeeDimDimension = dimensionCache.dimCodeToItem("TRANSACTION_TYPE", "NONFIN_FEE"); int iteratorValue = 0; for (ZonedDateTime date : allDates) { List<TransactionEntity> transactionsByDate = transactionsBySpecificCard.stream().filter(transaction -> transaction.getTransactionTime().isEqual(date)).toList(); List<EventEntity> eventsByDate = eventsBySpecificCard.stream().filter(event -> event.getRequestTime().isEqual(date)).toList(); for (TransactionEntity transaction : transactionsByDate) { List<TransactionEntity> commissionsByTransaction = commissionsTransactionsBySpecificCard.stream() .filter(commissionTransaction -> transaction.getTransactionId().equals(commissionTransaction.getMainTransactionId())) .collect(Collectors.toList()); iteratorValue++; stringValueOfTransactionsBySpecificCard.append(generateStatementByTransaction(iteratorValue, transaction, commissionsTransactionTypes)); if (!commissionsByTransaction.isEmpty()) for (TransactionEntity commissionTransaction : commissionsByTransaction) { stringValueOfTransactionsBySpecificCard.append(generateStatementByTransaction(null, commissionTransaction, commissionsTransactionTypes)); } } for (EventEntity event : eventsByDate) { iteratorValue++; iterator = String.valueOf(iteratorValue); procDate = ""; status = "ЗАБЛОКИРОВАНА"; /*nonFormattedTransactionDateTime = String.valueOf(event.getRequestTime()); transactionDateTime = formatDateAndTime(nonFormattedTransactionDateTime);*/ transactionDateTime = event.getRequestTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss")); description = ""; if (Objects.nonNull(event.getMsgType()) && Objects.nonNull(event.getFld003())) { Integer isReversal; if (event.getMsgType().startsWith("14")) { isReversal = 1; } else { isReversal = 0; } DimItemDto eventTransactionType = issuingServiceCache.getTransactionTypeByProcCodeAndReversalAttr( event.getFld003().substring(0, 2), isReversal ); if (Objects.nonNull(eventTransactionType)) { description = eventTransactionType.getName(); } } BigDecimal eventAmountSign = getAmountSign(event); if (Objects.nonNull(event.getEventData())) { if (Objects.nonNull(event.getEventData().get("fld026"))) { mcc = (String) event.getEventData().get("fld026"); } else { mcc = ""; } } else { mcc = ""; } if (Objects.nonNull(event.getEventData())) { if (Objects.nonNull(event.getEventData().get("fld043"))) { place = (String) event.getEventData().get("fld043"); } else { place = ""; } } else { place = ""; } if (Objects.nonNull(event.getEventData())) { if (Objects.nonNull(event.getEventData().get("fld037"))) { rrn = (String) event.getEventData().get("fld037"); } else { rrn = ""; } } else { rrn = ""; } if (Objects.nonNull(event.getEventData())) { if (Objects.nonNull(event.getEventData().get("fld038"))) { authCode = (String) event.getEventData().get("fld038"); } else { authCode = ""; } } else { authCode = ""; } DimItemDto eventTransactionCurrency = null; if (Objects.nonNull(event.getEventData())) { if (Objects.nonNull(event.getEventData().get("fld049"))) { eventTransactionCurrency = issuingServiceCache.getCurrencyByNumericCode(event.getEventData().get("fld049").toString()); currency = eventTransactionCurrency.getCode(); } else { currency = ""; } } else { currency = ""; } if (Objects.nonNull(event.getEventData())) { if (Objects.nonNull(event.getEventData().get("fld004"))) { Integer exponent = eventTransactionCurrency.getAttributes().get("EXPONENT").getIntValue(); BigDecimal eventAmountWithExponent = new BigDecimal(event.getEventData().get("fld004").toString()) .movePointLeft(exponent) .setScale(exponent, RoundingMode.HALF_UP); eventAmountWithExponent = eventAmountWithExponent.multiply(eventAmountSign); currencyAmount = processAmountForCustomerReadability(eventAmountWithExponent); } else { currencyAmount = ""; } } else { currencyAmount = ""; } commission = ""; if (Objects.nonNull(event.getEventData())) { if (Objects.nonNull(event.getEventData().get("fld006"))) { DimItemDto eventCurrency = issuingServiceCache.getCurrencyByNumericCode(event.getEventData().get("fld051").toString()); Integer exponent = eventCurrency.getAttributes().get("EXPONENT").getIntValue(); BigDecimal eventAmount = new BigDecimal(event.getEventData().get("fld006").toString()) .movePointLeft(exponent) .setScale(exponent, RoundingMode.HALF_UP); eventAmount = eventAmount.multiply(eventAmountSign); amount = processAmountForCustomerReadability(eventAmount); } else { amount = ""; } } else { amount = ""; } stringValueOfTransactionsBySpecificCard .append(iterator) .append("|") .append(procDate) .append("|") .append(status) .append("|") .append(transactionDateTime) .append("|") .append(description) .append("|") .append(mcc) .append("|") .append(place) .append("|") .append(rrn) .append("|") .append(authCode) .append("|") .append(currency) .append("|") .append(currencyAmount) .append("|") .append(commission) .append("|") .append(amount) .append("\n"); } } return stringValueOfTransactionsBySpecificCard.toString(); } private String generateStatementByTransaction(Integer iteratorValue, TransactionEntity transaction, List<Long> commissionTransactionsTypes) { String status; String nonFormattedTransactionDateTime; String rrn; String transactionDateTime; String commission; String place; String description; String amount; String procDate; String mcc; String currency; String iterator; String authCode; String currencyAmount; iterator = iteratorValue != null ? String.valueOf(iteratorValue) : ""; if (Objects.nonNull(transaction.getTransactionDate())) { //if (Objects.nonNull(transaction.getTransactionDate().get("Date"))) { // nonFormattedProcDate = String.valueOf(transaction.getTransactionDate().get("Date")); procDate = transaction.getBusinessDate().format(DateTimeFormatter.ofPattern("dd.MM.yyyy")); //} } else { procDate = ""; } status = "ПРОВЕДЕНА"; if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("Date")) && Objects.nonNull(transaction.getTransactionDate().get("Time"))) { nonFormattedTransactionDateTime = String.valueOf(transaction.getTransactionDate().get("Date")).concat(String.valueOf(transaction.getTransactionDate().get("Time"))); transactionDateTime = formatDateAndTime(nonFormattedTransactionDateTime); } else { transactionDateTime = ""; } } else { transactionDateTime = ""; } if (!commissionTransactionsTypes.contains(transaction.getTransactionTypeId())) { description = Objects.nonNull(transaction.getDescription()) ? transaction.getDescription() : ""; } else { description = dimensionCache.dimIdToItem(Long.valueOf((Integer) transaction.getTransactionDate().get("FEE_commission_LCIS_code_id"))).getName(); } if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("MCC_code"))) { mcc = (String) transaction.getTransactionDate().get("MCC_code"); } else { mcc = ""; } } else { mcc = ""; } if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("Abvr_name"))) { place = (String) transaction.getTransactionDate().get("Abvr_name"); } else { place = ""; } } else { place = ""; } if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("Ref_number"))) { rrn = (String) transaction.getTransactionDate().get("Ref_number"); } else { rrn = ""; } } else { rrn = ""; } if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("Appr_code"))) { authCode = (String) transaction.getTransactionDate().get("Appr_code"); } else { authCode = ""; } } else { authCode = ""; } if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("Currency"))) { currency = (String) transaction.getTransactionDate().get("Currency"); } else { currency = ""; } } else { currency = ""; } if (Objects.nonNull(transaction.getTransactionDate())) { if (Objects.nonNull(transaction.getTransactionDate().get("Amount")) && Objects.nonNull(transaction.getTransactionDate().get("Currency"))) { currencyAmount = processCurrencyAmount(transaction.getTransactionDate().get("Amount").toString(), dimensionCache.dimCodeToItem("CURRENCY", currency).getAttributes().get("EXPONENT").getIntValue()); currencyAmount = processAmountForCustomerReadability(currencyAmount, dimensionCache.dimIdToItem(transaction.getTransactionTypeId())); } else { currencyAmount = ""; } } else { currencyAmount = ""; } commission = ""; amount = ""; if (commissionTransactionsTypes.contains(transaction.getTransactionTypeId())) { commission = processAmountForCustomerReadability(transaction.getAmount()); } else { amount = processAmountForCustomerReadability(transaction.getAmount()); } return iterator + "|" + procDate + "|" + status + "|" + transactionDateTime + "|" + description + "|" + mcc + "|" + place + "|" + rrn + "|" + authCode + "|" + currency + "|" + currencyAmount + "|" + commission + "|" + amount + "|" + "end" + "\n"; } private String processCurrencyAmount(String amount, Integer exponent) { BigDecimal bdAmount = new BigDecimal(amount); bdAmount = bdAmount.setScale(exponent, RoundingMode.HALF_UP); return bdAmount.toString(); } private String processAmountForCustomerReadability(String amount, DimItemDto transactionType) { if (transactionType.getAttributes().containsKey("DEBIT_CREDIT")){ if ("C".equals(transactionType.getAttributes().get("DEBIT_CREDIT").getStringValue())) { return amount + "+"; } else if ("D".equals(transactionType.getAttributes().get("DEBIT_CREDIT").getStringValue())) { return amount + "-"; } else { return ""; } } else { return ""; } } private String formatDateAndTime(String notFormattedDateTime) { DateTimeFormatter toStringParser = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); DateTimeFormatter toDateParser = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); ZonedDateTime dateValue; try { dateValue = LocalDateTime.parse(notFormattedDateTime, toDateParser).atZone(ZoneId.systemDefault()); } catch (Exception e) { dateValue = ZonedDateTime.of(LocalDate.parse(notFormattedDateTime, toDateParser), LocalTime.MIN, ZoneId.systemDefault()); } return dateValue.format(toStringParser); } private BigDecimal getAmountSign(EventEntity event) { if (event.getMsgType().startsWith("11")) { if (event.getFld003().startsWith("00") || event.getFld003().startsWith("01") || event.getFld003().startsWith("10") || event.getFld003().startsWith("11")) { return BigDecimal.ONE.negate(); } else if (event.getFld003().startsWith("21") || event.getFld003().startsWith("26")) { return BigDecimal.ONE; } else { return BigDecimal.ONE; } } else if (event.getMsgType().startsWith("14")) { if (event.getFld003().startsWith("21") || event.getFld003().startsWith("26")) { return BigDecimal.ONE.negate(); } else if (event.getFld003().startsWith("00") || event.getFld003().startsWith("01") || event.getFld003().startsWith("10") || event.getFld003().startsWith("11")) { return BigDecimal.ONE; } else { return BigDecimal.ONE; } } else { return BigDecimal.ONE; } } private String processAmountForCustomerReadability(BigDecimal amount) { if (amount.toString().startsWith("-")) { return amount.toString().replaceAll("-", "").concat("-"); } return amount.toString().concat("+"); } }