counterparty 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- counterparty/__init__.py +29 -0
- counterparty/extraction/__init__.py +0 -0
- counterparty/extraction/clean.py +124 -0
- counterparty/extraction/extract_payer_payee.py +160 -0
- counterparty/extraction/infer_counterparty.py +17 -0
- counterparty/key_engine/__init__.py +0 -0
- counterparty/key_engine/canonical_keys.json +326 -0
- counterparty/key_engine/key_detector.py +335 -0
- counterparty/key_engine/keys.py +332 -0
- counterparty/parsers/LAT_AM/LAT_AM_Entry.py +91 -0
- counterparty/parsers/LAT_AM/__init__.py +0 -0
- counterparty/parsers/LAT_AM/pattern1.py +169 -0
- counterparty/parsers/LAT_AM/pattern10.py +76 -0
- counterparty/parsers/LAT_AM/pattern11.py +76 -0
- counterparty/parsers/LAT_AM/pattern12.py +99 -0
- counterparty/parsers/LAT_AM/pattern2.py +102 -0
- counterparty/parsers/LAT_AM/pattern3.py +75 -0
- counterparty/parsers/LAT_AM/pattern4.py +128 -0
- counterparty/parsers/LAT_AM/pattern5.py +54 -0
- counterparty/parsers/LAT_AM/pattern6.py +141 -0
- counterparty/parsers/LAT_AM/pattern7.py +116 -0
- counterparty/parsers/LAT_AM/pattern8.py +134 -0
- counterparty/parsers/LAT_AM/pattern9.py +86 -0
- counterparty/parsers/__init__.py +0 -0
- counterparty/parsers/ach/__init__.py +0 -0
- counterparty/parsers/ach/ach_parser.py +190 -0
- counterparty/parsers/avidpay/__init__.py +0 -0
- counterparty/parsers/avidpay/avidp_check_parser.py +82 -0
- counterparty/parsers/avidpay/avidp_gen_parser.py +59 -0
- counterparty/parsers/directdebit/__init__.py +0 -0
- counterparty/parsers/directdebit/directdeb.py +80 -0
- counterparty/parsers/disbursement/__init__.py +0 -0
- counterparty/parsers/disbursement/disb_parser.py +72 -0
- counterparty/parsers/fundsTransfer/__init__.py +0 -0
- counterparty/parsers/fundsTransfer/fundsTrans_parser.py +80 -0
- counterparty/parsers/generic/__init__.py +0 -0
- counterparty/parsers/generic/all_parser.py +91 -0
- counterparty/parsers/merchref/__init__.py +0 -0
- counterparty/parsers/merchref/merch_ref_parser.py +47 -0
- counterparty/parsers/misc/__init__.py +0 -0
- counterparty/parsers/misc/cardp.py +61 -0
- counterparty/parsers/misc/invo.py +78 -0
- counterparty/parsers/misc/webt.py +55 -0
- counterparty/parsers/paypal/__init__.py +0 -0
- counterparty/parsers/paypal/paypal.py +118 -0
- counterparty/parsers/processor_eft/__init__.py +0 -0
- counterparty/parsers/processor_eft/peft.py +110 -0
- counterparty/parsers/remittance/__init__.py +0 -0
- counterparty/parsers/remittance/remi.py +79 -0
- counterparty/parsers/swift/__init__.py +0 -0
- counterparty/parsers/swift/swift_parser.py +97 -0
- counterparty/parsers/vendorpay/__init__.py +0 -0
- counterparty/parsers/vendorpay/vp_parser.py +54 -0
- counterparty/parsers/vendorpymt/__init__.py +0 -0
- counterparty/parsers/vendorpymt/vpymt_parser.py +132 -0
- counterparty/parsers/wire/__init__.py +0 -0
- counterparty/parsers/wire/wire_parser.py +137 -0
- counterparty/route.py +116 -0
- counterparty/routines.py +72 -0
- counterparty/util.py +40 -0
- counterparty-0.1.6.dist-info/METADATA +9 -0
- counterparty-0.1.6.dist-info/RECORD +64 -0
- counterparty-0.1.6.dist-info/WHEEL +5 -0
- counterparty-0.1.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from rapidfuzz import fuzz
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
BASE_DIR = Path(__file__).parent
|
|
8
|
+
CANONICAL_FILE = BASE_DIR / "canonical_keys.json"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class KeyDetector:
|
|
12
|
+
def __init__(self, threshold: int = 85, max_words: int = 7):
|
|
13
|
+
self.threshold = threshold
|
|
14
|
+
self.max_words = max_words
|
|
15
|
+
self._load_keys()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# LOAD CANONICAL KEYS
|
|
19
|
+
|
|
20
|
+
def _load_keys(self):
|
|
21
|
+
with open(CANONICAL_FILE, "r", encoding="utf-8") as f:
|
|
22
|
+
self.canonical_map = json.load(f)
|
|
23
|
+
|
|
24
|
+
self.match_keys = []
|
|
25
|
+
self.all_variants = set()
|
|
26
|
+
|
|
27
|
+
for canon, variants in self.canonical_map.items():
|
|
28
|
+
for v in variants:
|
|
29
|
+
self.match_keys.append((canon, v))
|
|
30
|
+
self.all_variants.add(self._clean(v))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# PUBLIC ENTRY
|
|
34
|
+
|
|
35
|
+
def rewrite(self, text: str):
|
|
36
|
+
text = self._normalize_text(text)
|
|
37
|
+
|
|
38
|
+
windows = self._generate_windows(text)
|
|
39
|
+
candidates = self._match_windows(text, windows)
|
|
40
|
+
accepted = self._resolve_conflicts(candidates)
|
|
41
|
+
|
|
42
|
+
rewritten_text = self._rewrite_text(text, accepted)
|
|
43
|
+
|
|
44
|
+
unknown_hitl = self._collect_unknown_keys_for_hitl(text, windows, accepted)
|
|
45
|
+
|
|
46
|
+
if unknown_hitl:
|
|
47
|
+
return rewritten_text.upper(), (True, unknown_hitl)
|
|
48
|
+
else:
|
|
49
|
+
return rewritten_text.upper(), False
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# NORMALIZATION
|
|
54
|
+
|
|
55
|
+
def _normalize_text(self, text: str) -> str:
|
|
56
|
+
text = text.lower()
|
|
57
|
+
text = re.sub(r"\s+", " ", text)
|
|
58
|
+
return text
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# CLEAN STRING
|
|
62
|
+
|
|
63
|
+
def _clean(self, s: str) -> str:
|
|
64
|
+
return re.sub(r"[^a-z0-9]", "", s)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# WINDOW GENERATION
|
|
68
|
+
|
|
69
|
+
def _generate_windows(self, text: str):
|
|
70
|
+
tokens = []
|
|
71
|
+
for m in re.finditer(r"[a-z0-9]+", text):
|
|
72
|
+
tokens.append((m.group(), m.start(), m.end()))
|
|
73
|
+
|
|
74
|
+
windows = []
|
|
75
|
+
for i in range(len(tokens)):
|
|
76
|
+
for w in range(1, self.max_words + 1):
|
|
77
|
+
if i + w <= len(tokens):
|
|
78
|
+
phrase = " ".join(tokens[j][0] for j in range(i, i + w))
|
|
79
|
+
start = tokens[i][1]
|
|
80
|
+
end = tokens[i + w - 1][2]
|
|
81
|
+
windows.append((phrase, start, end))
|
|
82
|
+
|
|
83
|
+
return windows
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# DELIMITER CHECK
|
|
87
|
+
def _has_delimiter_after(self, text: str, end: int) -> bool:
|
|
88
|
+
tail = text[end:]
|
|
89
|
+
|
|
90
|
+
i = 0
|
|
91
|
+
while i < len(tail) and tail[i].isspace():
|
|
92
|
+
i += 1
|
|
93
|
+
|
|
94
|
+
# delimiter immediately → OK
|
|
95
|
+
if i < len(tail) and tail[i] in ":=":
|
|
96
|
+
return True
|
|
97
|
+
|
|
98
|
+
# word continues → NOT a key end
|
|
99
|
+
if i < len(tail) and tail[i].isalnum():
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
# skip punctuation, but stop on word
|
|
103
|
+
while i < len(tail):
|
|
104
|
+
if tail[i] in ":=":
|
|
105
|
+
return True
|
|
106
|
+
if tail[i].isalnum():
|
|
107
|
+
return False
|
|
108
|
+
i += 1
|
|
109
|
+
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# MATCH WINDOWS AGAINST CANONICAL VARIANTS
|
|
114
|
+
def _match_windows(self, text, windows):
|
|
115
|
+
candidates = []
|
|
116
|
+
|
|
117
|
+
for phrase, start, end in windows:
|
|
118
|
+
if not self._has_delimiter_after(text, end):
|
|
119
|
+
continue
|
|
120
|
+
|
|
121
|
+
phrase_clean = self._clean(phrase)
|
|
122
|
+
|
|
123
|
+
best_canon = None
|
|
124
|
+
best_score = 0
|
|
125
|
+
|
|
126
|
+
for canon, variant in self.match_keys:
|
|
127
|
+
score = fuzz.ratio(phrase_clean, self._clean(variant))
|
|
128
|
+
if score >= self.threshold and score > best_score:
|
|
129
|
+
best_canon = variant
|
|
130
|
+
best_score = score
|
|
131
|
+
|
|
132
|
+
if best_canon:
|
|
133
|
+
candidates.append({
|
|
134
|
+
"raw": phrase,
|
|
135
|
+
"canonical": best_canon,
|
|
136
|
+
"score": best_score,
|
|
137
|
+
"start": start,
|
|
138
|
+
"end": end,
|
|
139
|
+
"tokens": len(phrase.split())
|
|
140
|
+
})
|
|
141
|
+
# print(json.dumps(candidates,indent=3))
|
|
142
|
+
return candidates
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# CONFLICT RESOLUTION
|
|
148
|
+
def _resolve_conflicts(self, candidates):
|
|
149
|
+
"""
|
|
150
|
+
Conflict resolution rules:
|
|
151
|
+
1. Higher fuzzy score wins
|
|
152
|
+
2. If score ties, longer (more tokens) wins
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
# sort by start position only (grouping purpose)
|
|
156
|
+
candidates.sort(key=lambda c: c["start"])
|
|
157
|
+
|
|
158
|
+
accepted = []
|
|
159
|
+
|
|
160
|
+
for c in candidates:
|
|
161
|
+
keep = True
|
|
162
|
+
|
|
163
|
+
for a in accepted[:]:
|
|
164
|
+
overlap = not (c["end"] <= a["start"] or c["start"] >= a["end"])
|
|
165
|
+
|
|
166
|
+
if not overlap:
|
|
167
|
+
continue
|
|
168
|
+
|
|
169
|
+
# -------- conflict detected --------
|
|
170
|
+
|
|
171
|
+
# Rule 1: higher score wins
|
|
172
|
+
if c["score"] > a["score"]:
|
|
173
|
+
accepted.remove(a)
|
|
174
|
+
continue
|
|
175
|
+
|
|
176
|
+
if c["score"] < a["score"]:
|
|
177
|
+
keep = False
|
|
178
|
+
break
|
|
179
|
+
|
|
180
|
+
# Rule 2: score tie → more tokens wins
|
|
181
|
+
if c["tokens"] > a["tokens"]:
|
|
182
|
+
accepted.remove(a)
|
|
183
|
+
continue
|
|
184
|
+
else:
|
|
185
|
+
keep = False
|
|
186
|
+
break
|
|
187
|
+
|
|
188
|
+
if keep:
|
|
189
|
+
accepted.append(c)
|
|
190
|
+
|
|
191
|
+
# optional debug
|
|
192
|
+
# print(json.dumps(accepted, indent=2))
|
|
193
|
+
|
|
194
|
+
return accepted
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
# REWRITE TEXT
|
|
200
|
+
|
|
201
|
+
def _rewrite_text(self, text: str, accepted):
|
|
202
|
+
accepted.sort(key=lambda c: c["start"], reverse=True)
|
|
203
|
+
|
|
204
|
+
for c in accepted:
|
|
205
|
+
text = text[:c["start"]] + c["canonical"] + text[c["end"]:]
|
|
206
|
+
|
|
207
|
+
return text
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
# HITL — AMBIGUOUS MATCHES
|
|
211
|
+
|
|
212
|
+
def _collect_hitl(self, candidates, accepted, text):
|
|
213
|
+
accepted_spans = [(a["start"], a["end"]) for a in accepted]
|
|
214
|
+
hitl = []
|
|
215
|
+
|
|
216
|
+
for phrase, start, end in self._generate_windows(text):
|
|
217
|
+
# must be followed by delimiter
|
|
218
|
+
if not self._has_delimiter_after(text, end):
|
|
219
|
+
continue
|
|
220
|
+
|
|
221
|
+
# ignore single-word junk
|
|
222
|
+
if len(phrase.split()) < 2:
|
|
223
|
+
continue
|
|
224
|
+
|
|
225
|
+
# ignore non-alpha phrases
|
|
226
|
+
if not re.search(r"[a-z]", phrase):
|
|
227
|
+
continue
|
|
228
|
+
|
|
229
|
+
# ignore if fully inside accepted key
|
|
230
|
+
inside = False
|
|
231
|
+
for a_start, a_end in accepted_spans:
|
|
232
|
+
if start >= a_start and end <= a_end:
|
|
233
|
+
inside = True
|
|
234
|
+
break
|
|
235
|
+
if inside:
|
|
236
|
+
continue
|
|
237
|
+
|
|
238
|
+
# check if this phrase matched ANY canonical key
|
|
239
|
+
matched = False
|
|
240
|
+
phrase_clean = self._clean(phrase)
|
|
241
|
+
|
|
242
|
+
for _, variant in self.match_keys:
|
|
243
|
+
if fuzz.ratio(phrase_clean, self._clean(variant)) >= self.threshold:
|
|
244
|
+
matched = True
|
|
245
|
+
break
|
|
246
|
+
|
|
247
|
+
if matched:
|
|
248
|
+
continue
|
|
249
|
+
|
|
250
|
+
# REAL HITL CASE
|
|
251
|
+
hitl.append({
|
|
252
|
+
"type": "NEW_KEY",
|
|
253
|
+
"raw_phrase": phrase.upper(),
|
|
254
|
+
"suggested": None,
|
|
255
|
+
"confidence": None
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
return hitl
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
# HITL — COMPLETELY UNKNOWN KEYS
|
|
263
|
+
|
|
264
|
+
def _collect_unknown_keys_for_hitl(self, text, windows, accepted):
|
|
265
|
+
accepted_spans = [(a["start"], a["end"]) for a in accepted]
|
|
266
|
+
hitl = {}
|
|
267
|
+
|
|
268
|
+
# all canonical words flattened (for NAME vs CUST NAME)
|
|
269
|
+
canonical_tokens = set()
|
|
270
|
+
for v in self.all_variants:
|
|
271
|
+
canonical_tokens.update(re.findall(r"[a-z]+", v))
|
|
272
|
+
|
|
273
|
+
for m in re.finditer(r"\b([a-z][a-z0-9]*)\s*[:=]", text):
|
|
274
|
+
key_start, key_end = m.span(1)
|
|
275
|
+
raw_key = m.group(1)
|
|
276
|
+
|
|
277
|
+
# ❌ numeric or starts with digit → ignore
|
|
278
|
+
if raw_key[0].isdigit():
|
|
279
|
+
continue
|
|
280
|
+
|
|
281
|
+
clean_key = self._clean(raw_key)
|
|
282
|
+
|
|
283
|
+
# ❌ already known or part of known key
|
|
284
|
+
if clean_key in self.all_variants:
|
|
285
|
+
continue
|
|
286
|
+
if raw_key in canonical_tokens:
|
|
287
|
+
continue
|
|
288
|
+
|
|
289
|
+
# ❌ overlaps accepted canonical match
|
|
290
|
+
overlap = False
|
|
291
|
+
for a_start, a_end in accepted_spans:
|
|
292
|
+
if not (key_end <= a_start or key_start >= a_end):
|
|
293
|
+
overlap = True
|
|
294
|
+
break
|
|
295
|
+
if overlap:
|
|
296
|
+
continue
|
|
297
|
+
|
|
298
|
+
# tokenize safely
|
|
299
|
+
words = list(re.finditer(r"[a-z0-9]+|[:=]", text))
|
|
300
|
+
idx = None
|
|
301
|
+
for i, w in enumerate(words):
|
|
302
|
+
if w.start() == key_start:
|
|
303
|
+
idx = i
|
|
304
|
+
break
|
|
305
|
+
if idx is None:
|
|
306
|
+
continue
|
|
307
|
+
|
|
308
|
+
variants = [raw_key]
|
|
309
|
+
|
|
310
|
+
# look back max 4 words, stop at delimiter
|
|
311
|
+
back = 0
|
|
312
|
+
j = idx - 1
|
|
313
|
+
while j >= 0 and back < 4:
|
|
314
|
+
if words[j].group() in {":", "="}:
|
|
315
|
+
break
|
|
316
|
+
variants.append(
|
|
317
|
+
text[words[j].start():words[idx].end()]
|
|
318
|
+
)
|
|
319
|
+
back += 1
|
|
320
|
+
j -= 1
|
|
321
|
+
|
|
322
|
+
# normalize + dedupe
|
|
323
|
+
variants = [
|
|
324
|
+
re.sub(r"\s+", " ", v.strip()).upper()
|
|
325
|
+
for v in variants
|
|
326
|
+
]
|
|
327
|
+
variants = list(dict.fromkeys(variants))
|
|
328
|
+
|
|
329
|
+
hitl[raw_key.upper()] = variants
|
|
330
|
+
|
|
331
|
+
return hitl
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
if __name__=='__main__':
|
|
335
|
+
pass
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# All keys
|
|
2
|
+
|
|
3
|
+
# these keys are used to separate key-value pair from delimiter based narratives and parse them (like ach,wire,swift)
|
|
4
|
+
|
|
5
|
+
KEYS = [
|
|
6
|
+
"INDIVIDUAL OR RECEIVING COMPANY NAME",
|
|
7
|
+
"SWEEP TRANSFR FROM INVESTMENT ACCT",
|
|
8
|
+
"CREDITOR FINANCIAL INSTITUTION ID",
|
|
9
|
+
"RECEIVER FINANCIAL INSTITUTION ID",
|
|
10
|
+
"DEBTOR FINANCIAL INSTITUTION ID",
|
|
11
|
+
"SENDER FINANCIAL INSTITUTION ID",
|
|
12
|
+
"INSTRUCTION FOR CREDITOR AGENT",
|
|
13
|
+
"COMPANY DISCRETIONARY DATA",
|
|
14
|
+
"SWEEP TO INVESTMENT ACCT",
|
|
15
|
+
"INITIATING PARTY ORG ID",
|
|
16
|
+
"ADDITIONAL INFORMATION",
|
|
17
|
+
"REMITTANCE INFORMATION",
|
|
18
|
+
"ACCOUNT TRANSFER FROM",
|
|
19
|
+
"ACTUAL DEPOSIT AMOUNT",
|
|
20
|
+
"ORIGINATING BANK NAME",
|
|
21
|
+
"DAILY INTEREST SWEEP",
|
|
22
|
+
"EFFECTIVE ENTRY DATE",
|
|
23
|
+
"ITEM SEQUENCE NUMBER",
|
|
24
|
+
"ACCOUNT TRANSFER TO",
|
|
25
|
+
"CREDITOR CR ADDRESS",
|
|
26
|
+
"DATE/TIME COMPLETED",
|
|
27
|
+
"FDMS-SETTLEMENT FEE",
|
|
28
|
+
"MERCHANT CHARGEBACK",
|
|
29
|
+
"DATE/TIME RECEIVED",
|
|
30
|
+
"DISCRETIONARY DATA",
|
|
31
|
+
"MERCHANT INTERCHNG",
|
|
32
|
+
"PURPOSE OF PAYMENT",
|
|
33
|
+
"TRANSACTION REF NO",
|
|
34
|
+
"Transaction Ref No",
|
|
35
|
+
"CORRECTION REASON",
|
|
36
|
+
"DEBTOR CR ADDRESS",
|
|
37
|
+
"ENTRY DESCRIPTION",
|
|
38
|
+
"INSTRUCTED AMOUNT",
|
|
39
|
+
"INSTRUCTING AGENT",
|
|
40
|
+
"MERCHANT DISCOUNT",
|
|
41
|
+
"RECEIVER ACCT NUM",
|
|
42
|
+
"SENDERS REFERENCE",
|
|
43
|
+
"STANDBY L/C DEBIT",
|
|
44
|
+
"ALOK HEMANT SIDD",
|
|
45
|
+
"BANK DESCRIPTION",
|
|
46
|
+
"BILLING LOCATION",
|
|
47
|
+
"CREDITOR ACCOUNT",
|
|
48
|
+
"INSTRUCTED AGENT",
|
|
49
|
+
"MERCHANT DEPOSIT",
|
|
50
|
+
"ORIGINATING BANK",
|
|
51
|
+
"RECEIVER ABA NUM",
|
|
52
|
+
"RECEIVER ACCOUNT",
|
|
53
|
+
"RECEIVER ADDRESS",
|
|
54
|
+
"TRANSACTION CODE",
|
|
55
|
+
"ADVANCE DEPOSIT",
|
|
56
|
+
"CHARGING OPTION",
|
|
57
|
+
"EXCHANGE AMOUNT",
|
|
58
|
+
"FULL REFERENCE#",
|
|
59
|
+
"MORE DAY FLOATT",
|
|
60
|
+
"PAYMENT DETAILS",
|
|
61
|
+
"SENDER BANK REF",
|
|
62
|
+
"SENDING CO NAME",
|
|
63
|
+
"TRANSACTION REF",
|
|
64
|
+
"BANK TRACE NUM",
|
|
65
|
+
"BBKBENEFICIARY",
|
|
66
|
+
"CONTROL NUMBER",
|
|
67
|
+
"CREDITOR AGENT",
|
|
68
|
+
"DEBTOR ACCOUNT",
|
|
69
|
+
"EFFECTIVE DATE",
|
|
70
|
+
"FULL REFERENCE",
|
|
71
|
+
"PAYMENT METHOD",
|
|
72
|
+
"RECEIVING BANK",
|
|
73
|
+
"REMOTE CAPTURE",
|
|
74
|
+
"SENDER ACCOUNT",
|
|
75
|
+
"SENDER ADDRESS",
|
|
76
|
+
"SUBSTITUTE CHK",
|
|
77
|
+
"SWEEP INTEREST",
|
|
78
|
+
"CO DISCR DATA",
|
|
79
|
+
"CREDITOR NAME",
|
|
80
|
+
"CURRENCY DESC",
|
|
81
|
+
"CUSTOMER NAME",
|
|
82
|
+
"EXCHANGE RATE",
|
|
83
|
+
"IMAGE DEPOSIT",
|
|
84
|
+
"INDIVIDUAL ID",
|
|
85
|
+
"ORIG BANK ABA",
|
|
86
|
+
"Ordering Bank",
|
|
87
|
+
"Ordering Cust",
|
|
88
|
+
"RECEIVER NAME",
|
|
89
|
+
"REMIT DETAILS",
|
|
90
|
+
"RETURN REASON",
|
|
91
|
+
"WIRE CURRENCY",
|
|
92
|
+
"B/O CUSTOMER",
|
|
93
|
+
"BBKCUST NAME",
|
|
94
|
+
"CASHED CHECK",
|
|
95
|
+
"COMPANY DATA",
|
|
96
|
+
"COMPANY NAME",
|
|
97
|
+
"CREDITOR REF",
|
|
98
|
+
"DEBTOR AGENT",
|
|
99
|
+
"DEPOSIT DATE",
|
|
100
|
+
"DISBURSEMENT",
|
|
101
|
+
"ENTRY DESC R",
|
|
102
|
+
"INITIATED BY",
|
|
103
|
+
"MAIL DEPOSIT",
|
|
104
|
+
"MERCHANT FEE",
|
|
105
|
+
"NJ LOAN PMTS",
|
|
106
|
+
"ORIG CO NAME",
|
|
107
|
+
"PAYMENT DATE",
|
|
108
|
+
"PAYMENT/PURP",
|
|
109
|
+
"Payment Type",
|
|
110
|
+
"REC BANK ABA",
|
|
111
|
+
"REMIT METHOD",
|
|
112
|
+
"SRFCUST NAME",
|
|
113
|
+
"TRACE NUMBER",
|
|
114
|
+
"1 DAY FLOAT",
|
|
115
|
+
"2 DAY FLOAT",
|
|
116
|
+
"ACCT NUMBER",
|
|
117
|
+
"APPROVED BY",
|
|
118
|
+
"BATCH DISCR",
|
|
119
|
+
"BENEFICIARY",
|
|
120
|
+
"BILLING LOC",
|
|
121
|
+
"COMM CHARGE",
|
|
122
|
+
"DEBTOR NAME",
|
|
123
|
+
"DESCRIPTION",
|
|
124
|
+
"DR BANK REF",
|
|
125
|
+
"DR CUST REF",
|
|
126
|
+
"DR TRANS ID",
|
|
127
|
+
"Description",
|
|
128
|
+
"ENTRY CLASS",
|
|
129
|
+
"ENTRY DESCR",
|
|
130
|
+
"FEES LIFTED",
|
|
131
|
+
"FX CURRENCY",
|
|
132
|
+
"NJ FEE PMTS",
|
|
133
|
+
"ORG DEP AMT",
|
|
134
|
+
"RCV BK NAME",
|
|
135
|
+
"RECEIVED AT",
|
|
136
|
+
"RECEIVER ID",
|
|
137
|
+
"RELATED REF",
|
|
138
|
+
"SENDER NAME",
|
|
139
|
+
"SERVICE REF",
|
|
140
|
+
"SND BK NAME",
|
|
141
|
+
"WIRE AMOUNT",
|
|
142
|
+
"ACCT PARTY",
|
|
143
|
+
"BILL LOCAL",
|
|
144
|
+
"BNF STREET",
|
|
145
|
+
"BNK STREET",
|
|
146
|
+
"CLASS CODE",
|
|
147
|
+
"COMPANY ID",
|
|
148
|
+
"CR ADDRESS",
|
|
149
|
+
"CR BANK ID",
|
|
150
|
+
"DR BANK ID",
|
|
151
|
+
"ENTRY DATE",
|
|
152
|
+
"FED REF NO",
|
|
153
|
+
"Fed Ref No",
|
|
154
|
+
"IND I D NO",
|
|
155
|
+
"INTRMY BNK",
|
|
156
|
+
"ITEM TRACE",
|
|
157
|
+
"MISC DEBIT",
|
|
158
|
+
"ORG STREET",
|
|
159
|
+
"ORIG BA NK",
|
|
160
|
+
"ORIGINATOR",
|
|
161
|
+
"PAR NUMBER",
|
|
162
|
+
"PARTIALREF",
|
|
163
|
+
"PAY METHOD",
|
|
164
|
+
"RCV BK ABA",
|
|
165
|
+
"RECV ID NO",
|
|
166
|
+
"RETURN REF",
|
|
167
|
+
"SENDER REF",
|
|
168
|
+
"SND BK ABA",
|
|
169
|
+
"TRANS TYPE",
|
|
170
|
+
"USD AMOUNT",
|
|
171
|
+
"VALUE DATE",
|
|
172
|
+
"ACC PARTY",
|
|
173
|
+
"ACCT TYPE",
|
|
174
|
+
"CHECK NUM",
|
|
175
|
+
"COMP NAME",
|
|
176
|
+
"CUST NAME",
|
|
177
|
+
"DATE/TIME",
|
|
178
|
+
"DEBIT REF",
|
|
179
|
+
"DESC DATE",
|
|
180
|
+
"FILE NAME",
|
|
181
|
+
"FROM ACCT",
|
|
182
|
+
"IND ID NO",
|
|
183
|
+
"INSTG BNK",
|
|
184
|
+
"LISTED AS",
|
|
185
|
+
"ORIG BANK",
|
|
186
|
+
"RECV BANK",
|
|
187
|
+
"RECV NAME",
|
|
188
|
+
"RECVID NO",
|
|
189
|
+
"REFERENCE",
|
|
190
|
+
"RMT USTRD",
|
|
191
|
+
"Reference",
|
|
192
|
+
"SENDER AC",
|
|
193
|
+
"SHIP DATE",
|
|
194
|
+
"SHOULD BE",
|
|
195
|
+
"SWIFT REF",
|
|
196
|
+
"TRACE NUM",
|
|
197
|
+
"ULTI BENE",
|
|
198
|
+
"WIRE TYPE",
|
|
199
|
+
"B/O BANK",
|
|
200
|
+
"BATCH ID",
|
|
201
|
+
"CHECK NO",
|
|
202
|
+
"CHIP REF",
|
|
203
|
+
"CHIP SEQ",
|
|
204
|
+
"CREDITOR",
|
|
205
|
+
"CUST RRN",
|
|
206
|
+
"FED IMAD",
|
|
207
|
+
"IND NAME",
|
|
208
|
+
"REC BANK",
|
|
209
|
+
"REC FROM",
|
|
210
|
+
"REC G FP",
|
|
211
|
+
"RECV BNK",
|
|
212
|
+
"SEC CODE",
|
|
213
|
+
"SNDR REF",
|
|
214
|
+
"TRACE NO",
|
|
215
|
+
"YOUR REF",
|
|
216
|
+
"ACCOUNT",
|
|
217
|
+
"ADDENDA",
|
|
218
|
+
"AMT/CUR",
|
|
219
|
+
"BANK ID",
|
|
220
|
+
"BENEBNK",
|
|
221
|
+
"COMP ID",
|
|
222
|
+
"CONFIRM",
|
|
223
|
+
"CR ACCT",
|
|
224
|
+
"CR NAME",
|
|
225
|
+
"CREATED",
|
|
226
|
+
"CUST ID",
|
|
227
|
+
"DEP AMT",
|
|
228
|
+
"DEPDATE",
|
|
229
|
+
"DEPOSIT",
|
|
230
|
+
"DR ACCT",
|
|
231
|
+
"DR NAME",
|
|
232
|
+
"FED REF",
|
|
233
|
+
"INVOICE",
|
|
234
|
+
"ISO AMT",
|
|
235
|
+
"LBX DEP",
|
|
236
|
+
"MRN SEQ",
|
|
237
|
+
"ORG BNK",
|
|
238
|
+
"ORIG ID",
|
|
239
|
+
"ORIGIN#",
|
|
240
|
+
"PAID TO",
|
|
241
|
+
"R EMARK",
|
|
242
|
+
"REC GFP",
|
|
243
|
+
"RECV BK",
|
|
244
|
+
"RECVBNK",
|
|
245
|
+
"REMA RK",
|
|
246
|
+
"REMAR K",
|
|
247
|
+
"SENT AT",
|
|
248
|
+
"SND BNK",
|
|
249
|
+
"AMOUNT",
|
|
250
|
+
"BNF BK",
|
|
251
|
+
"Branch",
|
|
252
|
+
"CO EFF",
|
|
253
|
+
"CR BNK",
|
|
254
|
+
"DB BNK",
|
|
255
|
+
"DEBTOR",
|
|
256
|
+
"DR BNK",
|
|
257
|
+
"FED ID",
|
|
258
|
+
"INS BK",
|
|
259
|
+
"INT BK",
|
|
260
|
+
"ORG BK",
|
|
261
|
+
"ORG ID",
|
|
262
|
+
"ORIGIN",
|
|
263
|
+
"REASON",
|
|
264
|
+
"REF NO",
|
|
265
|
+
"REMARK",
|
|
266
|
+
"SND BK",
|
|
267
|
+
"SOURCE",
|
|
268
|
+
"AS OF",
|
|
269
|
+
"CHECK",
|
|
270
|
+
"PAYER",
|
|
271
|
+
"PSTCD",
|
|
272
|
+
"VLTID",
|
|
273
|
+
"ACCT",
|
|
274
|
+
"ADDR",
|
|
275
|
+
"BN F",
|
|
276
|
+
"CTRY",
|
|
277
|
+
"DATE",
|
|
278
|
+
"DESC",
|
|
279
|
+
"IMAD",
|
|
280
|
+
"INDN",
|
|
281
|
+
"INFO",
|
|
282
|
+
"OMAD",
|
|
283
|
+
"ORIG",
|
|
284
|
+
"PLAN",
|
|
285
|
+
"RATE",
|
|
286
|
+
"S AC",
|
|
287
|
+
"SETT",
|
|
288
|
+
"TIME",
|
|
289
|
+
"TYPE",
|
|
290
|
+
"UETR",
|
|
291
|
+
"ULID",
|
|
292
|
+
"ABA",
|
|
293
|
+
"ADV",
|
|
294
|
+
"BAG",
|
|
295
|
+
"BBI",
|
|
296
|
+
"BBK",
|
|
297
|
+
"BIC",
|
|
298
|
+
"BLK",
|
|
299
|
+
"BNF",
|
|
300
|
+
"CHG",
|
|
301
|
+
"CTY",
|
|
302
|
+
"DOB",
|
|
303
|
+
"IBK",
|
|
304
|
+
"INS",
|
|
305
|
+
"LTN",
|
|
306
|
+
"OBI",
|
|
307
|
+
"OBK",
|
|
308
|
+
"OGB",
|
|
309
|
+
"ORF",
|
|
310
|
+
"ORG",
|
|
311
|
+
"POB",
|
|
312
|
+
"QID",
|
|
313
|
+
"REF",
|
|
314
|
+
"RFB",
|
|
315
|
+
"SBK",
|
|
316
|
+
"SBR",
|
|
317
|
+
"SEC",
|
|
318
|
+
"SRC",
|
|
319
|
+
"SRF",
|
|
320
|
+
"TCN",
|
|
321
|
+
"TRN",
|
|
322
|
+
"TTM",
|
|
323
|
+
"TYP",
|
|
324
|
+
"BC",
|
|
325
|
+
"PR",
|
|
326
|
+
]
|
|
327
|
+
|
|
328
|
+
INLINE_KEYS = ["ID","PURPOSE CODE","PURPOSE","AC"]
|
|
329
|
+
|
|
330
|
+
if __name__=='__main__':
|
|
331
|
+
print(sorted(KEYS,key=len,reverse=True))
|
|
332
|
+
pass
|