| 37330 |
amit |
1 |
package com.smartdukaan.cron.offercircular;
|
|
|
2 |
|
|
|
3 |
import java.util.ArrayList;
|
|
|
4 |
import java.util.List;
|
|
|
5 |
import java.util.Map;
|
|
|
6 |
import java.util.regex.Pattern;
|
|
|
7 |
|
|
|
8 |
/**
|
|
|
9 |
* Resolves the "Credit cards" / "Debit Cards" cells to bank ids.
|
|
|
10 |
*
|
|
|
11 |
* The alias map must be supplied by the caller (built from offers.bank +
|
|
|
12 |
* offers.bank_alias) because the circular spells the same bank several ways across
|
|
|
13 |
* pages: IDFC / IDFC BANK / IDFC FIRST BANK, Indusind / Indusland (a typo in the
|
|
|
14 |
* source), AU / AU Bank / Au Small Finance Bank. Without aliasing, ingest creates
|
|
|
15 |
* four IDFCs.
|
|
|
16 |
*
|
|
|
17 |
* Note that UPI appears in these columns but is a payment mode, not an issuer, so it
|
|
|
18 |
* is reported as a flag rather than resolved as a bank.
|
|
|
19 |
*/
|
|
|
20 |
public final class BankTextParser {
|
|
|
21 |
|
|
|
22 |
/** Card-type and qualifier words that are not bank names. J and K are the halves
|
|
|
23 |
* of "J&K" left behind by splitting on '&'; J&K is deliberately out of scope. */
|
|
|
24 |
private static final Pattern NOISE = Pattern.compile(
|
|
|
25 |
"^(CC|DC|EMI|CARD|CARDS|BANK|ONLY|LFR|FINANCIAL|CREDIT|DEBIT|REG|FULL"
|
|
|
26 |
+ "|SWIPE|AND|OR|THE|SELECTED|SELECTIVE|CARDLESS|CARDLESS EMI|CARDLES S"
|
|
|
27 |
+ "|CARDLES|J|K|K BANK)$");
|
|
|
28 |
|
|
|
29 |
private static final Pattern ALL_BANKS = Pattern.compile("ALL\\s*BANKS?");
|
|
|
30 |
private static final Pattern ALL_BANKS_CLAUSE = Pattern.compile("ALL\\s*BANKS?\\s*(EXCEPT)?");
|
|
|
31 |
private static final Pattern UPI = Pattern.compile("\\bUPI\\b");
|
|
|
32 |
private static final Pattern PARENTHETICAL = Pattern.compile("\\(.*?\\)");
|
|
|
33 |
private static final Pattern SEPARATOR = Pattern.compile("[,/&]| AND ");
|
|
|
34 |
private static final Pattern WHITESPACE = Pattern.compile("\\s+");
|
|
|
35 |
|
|
|
36 |
public static final class Result {
|
|
|
37 |
private final List<Integer> bankIds = new ArrayList<>();
|
|
|
38 |
private final List<String> unresolved = new ArrayList<>();
|
|
|
39 |
private boolean allBanks;
|
|
|
40 |
private boolean upi;
|
|
|
41 |
public List<Integer> getBankIds() { return bankIds; }
|
|
|
42 |
public List<String> getUnresolved() { return unresolved; }
|
|
|
43 |
public boolean isAllBanks() { return allBanks; }
|
|
|
44 |
public boolean isUpi() { return upi; }
|
|
|
45 |
}
|
|
|
46 |
|
|
|
47 |
private BankTextParser() { }
|
|
|
48 |
|
|
|
49 |
public static Result parse(String cell, Map<String, Integer> aliasToBankId) {
|
|
|
50 |
Result result = new Result();
|
|
|
51 |
if (cell == null) {
|
|
|
52 |
return result;
|
|
|
53 |
}
|
|
|
54 |
String text = cell.trim();
|
|
|
55 |
if (text.isEmpty() || "-".equals(text) || "NA".equals(text) || "N/A".equals(text)) {
|
|
|
56 |
return result;
|
|
|
57 |
}
|
|
|
58 |
String upper = text.toUpperCase();
|
|
|
59 |
result.allBanks = ALL_BANKS.matcher(upper).find();
|
|
|
60 |
result.upi = UPI.matcher(upper).find();
|
|
|
61 |
|
|
|
62 |
// parentheticals are qualifiers ("(DC & CC)", "(LFR Only)"), not bank names
|
|
|
63 |
String body = PARENTHETICAL.matcher(upper).replaceAll(" ");
|
|
|
64 |
body = ALL_BANKS_CLAUSE.matcher(body).replaceAll(" ");
|
|
|
65 |
|
|
|
66 |
for (String token : SEPARATOR.split(body)) {
|
|
|
67 |
String name = strip(WHITESPACE.matcher(token).replaceAll(" "), " .-");
|
|
|
68 |
if (name.isEmpty() || NOISE.matcher(name).matches() || "UPI".equals(name)) {
|
|
|
69 |
continue;
|
|
|
70 |
}
|
|
|
71 |
Integer bankId = aliasToBankId.get(name);
|
|
|
72 |
if (bankId == null) {
|
|
|
73 |
// progressively shorter prefixes: "HDFC DEBIT" -> "HDFC"
|
|
|
74 |
for (int cut = name.length(); cut > 2; cut--) {
|
|
|
75 |
bankId = aliasToBankId.get(name.substring(0, cut).trim());
|
|
|
76 |
if (bankId != null) {
|
|
|
77 |
break;
|
|
|
78 |
}
|
|
|
79 |
}
|
|
|
80 |
}
|
|
|
81 |
if (bankId != null) {
|
|
|
82 |
if (!result.bankIds.contains(bankId)) {
|
|
|
83 |
result.bankIds.add(bankId);
|
|
|
84 |
}
|
|
|
85 |
} else {
|
|
|
86 |
result.unresolved.add(name);
|
|
|
87 |
}
|
|
|
88 |
}
|
|
|
89 |
return result;
|
|
|
90 |
}
|
|
|
91 |
|
|
|
92 |
private static String strip(String s, String chars) {
|
|
|
93 |
int from = 0;
|
|
|
94 |
int to = s.length();
|
|
|
95 |
while (from < to && chars.indexOf(s.charAt(from)) >= 0) { from++; }
|
|
|
96 |
while (to > from && chars.indexOf(s.charAt(to - 1)) >= 0) { to--; }
|
|
|
97 |
return s.substring(from, to);
|
|
|
98 |
}
|
|
|
99 |
}
|