mirror of
https://github.com/wahyd4/afterpay-creditcard.git
synced 2026-08-09 05:15:52 +10:00
Refactor the code
This commit is contained in:
@@ -11,10 +11,11 @@ public class FraudChecker {
|
||||
|
||||
public static final int TWENTY_FOUR_HOURS = 24;
|
||||
private final TransactionRecordParser parser;
|
||||
Map<String, Boolean> fraudulentCards = new HashMap<String, Boolean>();
|
||||
Map<String, Boolean> fraudulentCards;
|
||||
|
||||
public FraudChecker(TransactionRecordParser parser) {
|
||||
this.parser = parser;
|
||||
this.fraudulentCards = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,60 +27,60 @@ public class FraudChecker {
|
||||
*/
|
||||
public List<String> fraudulentCreditCards(List<String> transactionStrings, BigDecimal threshold) {
|
||||
List<TransactionEntry> transactionEntries = parser.parseTransactionEntries(transactionStrings);
|
||||
|
||||
Map<String, List<TransactionEntry>> transactionsGroupByCard = new HashMap<String, List<TransactionEntry>>();
|
||||
for (TransactionEntry entry : transactionEntries) {
|
||||
Map<String, List<TransactionEntry>> transactionsGroupByCard = new HashMap<>();
|
||||
|
||||
String hashedCreditCard = entry.getHashedCreditCard();
|
||||
transactionEntries.forEach(entry -> processTransactionEntry(threshold, transactionsGroupByCard, entry));
|
||||
|
||||
List<TransactionEntry> entriesForCard = transactionsGroupByCard.get(hashedCreditCard);
|
||||
if (entriesForCard == null) {
|
||||
entriesForCard = new ArrayList<TransactionEntry>();
|
||||
}
|
||||
|
||||
entriesForCard.add(entry);
|
||||
transactionsGroupByCard.put(hashedCreditCard, entriesForCard);
|
||||
|
||||
if (!fraudulentCards.containsKey(hashedCreditCard)) {
|
||||
analyse(entriesForCard, hashedCreditCard, threshold);
|
||||
}
|
||||
}
|
||||
return collectFraudulentCards();
|
||||
return getFraudulentCards();
|
||||
}
|
||||
|
||||
private void analyse(List<TransactionEntry> entriesForCard, String hashedCard, BigDecimal threshold) {
|
||||
int entriesSize = entriesForCard.size();
|
||||
TransactionEntry oldestEntry = entriesForCard.get(0);
|
||||
TransactionEntry latestEntry = entriesForCard.get(entriesSize - 1);
|
||||
private void processTransactionEntry(BigDecimal threshold, Map<String, List<TransactionEntry>> transactionsByCard, TransactionEntry entry) {
|
||||
String hashedCreditCard = entry.getHashedCreditCard();
|
||||
|
||||
if (latestEntry.getDateTime().minusHours(TWENTY_FOUR_HOURS).isAfter(oldestEntry.getDateTime())) {
|
||||
entriesForCard = filterEntriesBySlidingWindow(entriesForCard, latestEntry).collect(Collectors.toList());
|
||||
addTransactionEntryToMap(transactionsByCard, entry, transactionsByCard.get(hashedCreditCard));
|
||||
|
||||
if (!isTheCreditCardMarkedAsFraudulent(hashedCreditCard)) {
|
||||
analyseCreditCardAgainstTheCurrentTimeWindow(transactionsByCard.get(hashedCreditCard), hashedCreditCard, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyseCreditCardAgainstTheCurrentTimeWindow(List<TransactionEntry> entriesForCard, String hashedCard, BigDecimal threshold) {
|
||||
TransactionEntry oldestEntry = entriesForCard.get(0);
|
||||
TransactionEntry latestEntry = entriesForCard.get(entriesForCard.size() - 1);
|
||||
|
||||
if (areTheEntriesOverCurrentTimeWindow(oldestEntry, latestEntry)) {
|
||||
entriesForCard = filterEntriesBySlidingTimeWindow(entriesForCard, latestEntry).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
if (ifCreditCardExceedsThreshold(entriesForCard, threshold)) {
|
||||
fraudulentCards.put(hashedCard, true);
|
||||
markFraudulentCreditCard(hashedCard);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the total money from all the records a single credit card exceeds the threshold
|
||||
*
|
||||
* @param transactionsOfACard
|
||||
* @param threshold
|
||||
* @return
|
||||
*/
|
||||
private List<String> getFraudulentCards() {
|
||||
return fraudulentCards.keySet().stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean areTheEntriesOverCurrentTimeWindow(TransactionEntry oldestEntry, TransactionEntry latestEntry) {
|
||||
return latestEntry.getDateTime().minusHours(TWENTY_FOUR_HOURS).isAfter(oldestEntry.getDateTime());
|
||||
}
|
||||
|
||||
private void markFraudulentCreditCard(String hashedCard) {
|
||||
fraudulentCards.put(hashedCard, true);
|
||||
}
|
||||
|
||||
private boolean ifCreditCardExceedsThreshold(List<TransactionEntry> transactionsOfACard, BigDecimal threshold) {
|
||||
return ifExceedsThreshold(threshold, calculateTotalMoney(transactionsOfACard.stream()));
|
||||
}
|
||||
|
||||
private Stream<TransactionEntry> filterEntriesBySlidingWindow(List<TransactionEntry> transactionsOfACard, TransactionEntry latestEntry) {
|
||||
private Stream<TransactionEntry> filterEntriesBySlidingTimeWindow(List<TransactionEntry> transactionsOfACard, TransactionEntry latestEntry) {
|
||||
return transactionsOfACard
|
||||
.stream()
|
||||
.filter(entry -> isTheEntryWithinTwentyHourWindow(latestEntry, entry));
|
||||
}
|
||||
|
||||
private BigDecimal calculateTotalMoney(Stream<TransactionEntry> filteredTransactions) {
|
||||
return filteredTransactions
|
||||
private BigDecimal calculateTotalMoney(Stream<TransactionEntry> transactionEntries) {
|
||||
return transactionEntries
|
||||
.map(entry -> entry.getMoney())
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
@@ -92,7 +93,16 @@ public class FraudChecker {
|
||||
return !entry.getDateTime().plusHours(TWENTY_FOUR_HOURS).isBefore(latestEntry.getDateTime());
|
||||
}
|
||||
|
||||
private List<String> collectFraudulentCards() {
|
||||
return fraudulentCards.keySet().stream().collect(Collectors.toList());
|
||||
private boolean isTheCreditCardMarkedAsFraudulent(String hashedCreditCard) {
|
||||
return fraudulentCards.containsKey(hashedCreditCard);
|
||||
}
|
||||
|
||||
private void addTransactionEntryToMap(Map<String, List<TransactionEntry>> transactionsGroupByCard, TransactionEntry entry, List<TransactionEntry> entriesForCard) {
|
||||
if (entriesForCard == null) {
|
||||
entriesForCard = new ArrayList<>();
|
||||
}
|
||||
|
||||
entriesForCard.add(entry);
|
||||
transactionsGroupByCard.put(entry.getHashedCreditCard(), entriesForCard);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user