ekylibre-ofx-parser 1.2.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6c544df27ac669391390610586894417f96db85a
4
+ data.tar.gz: de9425a7659732a011e8bd8687d4bd6c6551ac94
5
+ SHA512:
6
+ metadata.gz: 9b7e6e6694bbef0b5d35d0d827ae4ec6ff2f26888a435a916d9c52a7177787c247d15c4728ca63253e2bd4aa25a5f157d609fb659333f8df6d43afd0a65bfd60
7
+ data.tar.gz: b267f6862965eda3038d7bd530f37e4e1387c05d621a5ffed20e24d0a3bb5753129a8e4efff44e08a74ee4a4214982a1f7951ee52265f4d341f030ca691840a9
data/README.rdoc ADDED
@@ -0,0 +1,105 @@
1
+ == ofx-parser
2
+ by Andrew A. Smith
3
+
4
+ http://ofx-parser.rubyforge.org/
5
+ http://rubyforge.org/projects/ofx-parser/
6
+
7
+ == DESCRIPTION:
8
+
9
+ ofx-parser is a ruby library to parse a realistic subset of the lengthy OFX 1.x specification.
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * Reads OFX responses - i.e. those downloaded from financial institutions and
14
+ puts it into a usable object graph.
15
+ * Supports the 3 main message sets: banking, credit card and investment
16
+ accounts, as well as the required 'sign on' set.
17
+ * Knows about SIC codes - if your institution provides them.
18
+ See http://www.eeoc.gov/stats/jobpat/siccodes.html
19
+ * Monetary amounts can be retrieved either as a raw string, or in pennies.
20
+ * Supports OFX timestamps.
21
+
22
+ == SYNOPSIS:
23
+
24
+ Supports bank accounts:
25
+
26
+ require 'rubygems'
27
+ require 'ofx-parser'
28
+
29
+ ofx = OfxParser::OfxParser.parse(open("bank-statement.ofx"))
30
+ bank_acct = ofx.bank_accounts.first
31
+
32
+ bank_acct.number # => '103333333333'
33
+ bank_acct.routing_number # => '033000033'
34
+ bank_acct.balance # => '123.45'
35
+ bank_acct.balance_in_pennies # => 12345
36
+
37
+ bank_acct.statement.start_date # => DateTime
38
+ bank_acct.statement.end_date # => DateTime
39
+
40
+ bank_acct.statement.transactions.size # => 4
41
+
42
+ bank_acct.statement.transactions.first.payee # => "FOO, INC."
43
+ bank_acct.statement.transactions.first.type # => :DEBIT
44
+ bank_acct.statement.transactions.first.amount # => '-11.11'
45
+ bank_acct.statement.transactions.first.amount_in_pennies # => -1111
46
+
47
+ Also supports credit cards...
48
+
49
+ ofx = OfxParser::OfxParser.parse(open("creditcard-statement.ofx"))
50
+ credit_card = ofx.credit_accounts.first
51
+
52
+ credit_card.remaining_credit # => '19000.0'
53
+ credit_card.remaining_credit_in_pennies # => '1900000'
54
+
55
+ credit_card.statement.start_date # => DateTime
56
+ credit_card.statement.end_date # => DateTime
57
+
58
+ credit_card.statement.transactions.size # => 10
59
+
60
+ credit_card.statement.transactions.first.type # => :DEBIT
61
+ credit_card.statement.transactions.first.amount # => '-19.17'
62
+ credit_card.statement.transactions.first.amount_in_pennies # => '-1917'
63
+ credit_card.statement.transactions.first.sic # => '7933'
64
+ credit_card.statement.transactions.first.sic_desc # => 'BOWLING CENTERS'
65
+ credit_card.statement.transactions.first.payee # => 'SUNSET BOWLING'
66
+
67
+ Working on investment accounts...
68
+
69
+ == REQUIREMENTS:
70
+
71
+ * hpricot >= 0.6
72
+
73
+ == INSTALL:
74
+
75
+ * gem install ofx-parser
76
+
77
+ == LICENSE:
78
+
79
+ Copyright (c) 2007, Andrew A. Smith
80
+ All rights reserved.
81
+
82
+ Redistribution and use in source and binary forms, with or without modification,
83
+ are permitted provided that the following conditions are met:
84
+
85
+ * Redistributions of source code must retain the above copyright notice,
86
+ this list of conditions and the following disclaimer.
87
+
88
+ * Redistributions in binary form must reproduce the above copyright notice,
89
+ this list of conditions and the following disclaimer in the documentation
90
+ and/or other materials provided with the distribution.
91
+
92
+ * Neither the name of the copyright owner nor the names of its contributors
93
+ may be used to endorse or promote products derived from this software
94
+ without specific prior written permission.
95
+
96
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
97
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
100
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
103
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/lib/mcc.rb ADDED
@@ -0,0 +1,670 @@
1
+ module OfxParser
2
+ # MCC: Merchant Category Codes from
3
+ # * http://www.purchasing.colostate.edu/pages/pdf/MCCS.pdf
4
+ # * http://www.ctlr.msu.edu/cashiers/MC%20IC%20Apr%2007.pdf
5
+ # * http://usa.visa.com/download/corporate/resources/mcc_booklet.pdf
6
+ module Mcc
7
+ CODES = {
8
+ '0742' => 'VETERINARY SERVICES',
9
+ '0763' => 'AGRICULTURAL COOPERATIVES',
10
+ '2741' => 'MISCELLANEOUS PUBLISHING AND PRINTING',
11
+ '2791' => 'TYPESETTING PLATE MAKING + RELATED SERVICES',
12
+ '2842' => 'SPECIALTY CLEANING POLISHING + SANITATION PREP.',
13
+ '4215' => 'COURIER SVC-AIR + GROUND FREIGHT FORWARDERS',
14
+ '4468' => 'MARINAS MARINE SERVICE-SUPPLIES',
15
+ '4812' => 'TELECOMMUNICATION EQUIPMENT INCL TELEPHONE SALES',
16
+ '4813' => 'KEY-ENTER TELECOM MERCHANT- (NO MAG STRIPE READ)',
17
+ '4814' => 'TELECOM SVC-LOC-LONG DIST CR CD + MAG STRIPE FAX',
18
+ '4815' => 'MONTHLY SUMMARY TELEPHONE CHARGES',
19
+ '4816' => 'COMPUTER NETWORK-INFORMATION SERVICES',
20
+ '4821' => 'TELEGRAPH SERVICES',
21
+ '4899' => 'CABLE SERVICES',
22
+ '4900' => 'UTILITIES-ELECTRIC GAS WATER SANITARY',
23
+ '5013' => 'MOTOR VEHICLE SUPPLIES AND NEW PARTS',
24
+ '5021' => 'OFFICE AND COMMERCIAL FURNITURE',
25
+ '5039' => 'CONSTRUCTION MATERIALS NOT ELSEWHERE CLASSIFIED',
26
+ '5044' => 'OFFICE PHOTOGRAPHIC PHOTOCOPY + MICROFILM EQUIPMT.',
27
+ '5045' => 'COMPUTERS COMPUTER PERIPHERAL EQUIPMENT SOFTWARE',
28
+ '5046' => 'COMMERCIAL EQUIPMENT NOT ELSEWHERE CLASSIFIED',
29
+ '5047' => 'LABORATORY-MEDICAL-DENTAL-OPHTHALMIC HOS. EQUI-SUP',
30
+ '5051' => 'METAL SERVICE CENTERS AND OFFICES',
31
+ '5065' => 'ELECTRICAL PARTS AND EQUIPMENT',
32
+ '5072' => 'HARDWARE EQUIPMENT AND SUPPLIES',
33
+ '5074' => 'PLUMBING AND HEATING EQUIPMENT',
34
+ '5085' => 'INDUSTRIAL SUPPLIES NOT ELSEWHERE CLASSIFIED',
35
+ '5094' => 'PRECIOUS STONES AND METALS WATCHES AND JEWELRY',
36
+ '5099' => 'DURABLE GOODS NOT ELSEWHERE CLASSIFIED',
37
+ '5111' => 'STATIONERY-OFFICE SUPPLIES-PRINTING + WRITING PAP.',
38
+ '5122' => 'DRUGS DRUG PROPRIETARIES AND DRUGGIST\'S SUPPLIES',
39
+ '5131' => 'PIECE GOODS NOTIONS AND OTHER DRY GOODS',
40
+ '5137' => 'MEN\'S-WOMEN\'S-CHILDREN\'S UNIFORMS-COMMERCIAL CLOTH',
41
+ '5139' => 'COMMERCIAL FOOTWEAR',
42
+ '5169' => 'CHEMICALS-ALLIED PRODUCTS NOT ELSEWHERE CLASSIFIED',
43
+ '5172' => 'PETROLEUM AND PETROLEUM PRODUCTS',
44
+ '5192' => 'BOOKS PERIODICALS AND NEWSPAPERS',
45
+ '5193' => 'FLORIST SUPPLIES NURSERY STOCK + FLOWERS',
46
+ '5198' => 'PAINTS VARNISHES AND SUPPLIES',
47
+ '5199' => 'NONDURABLE GOODS (NOT ELSEWHERE CLASSIFIED)',
48
+ '5200' => 'HOME SUPPLY WAREHOUSE',
49
+ '5211' => 'LUMBER BUILDING MATERIALS STORES',
50
+ '5231' => 'GLASS PAINT WALLPAPER STORES',
51
+ '5251' => 'HARDWARE STORES',
52
+ '5261' => 'NURSERIES LAWN GARDEN SUPPLY STORES',
53
+ '5300' => 'WHOLESALE CLUBS',
54
+ '5310' => 'DISCOUNT STORES',
55
+ '5311' => 'DEPARTMENT STORES',
56
+ '5331' => 'VARIETY STORES',
57
+ '5399' => 'MISCELLANEOUS GENERAL MERCHANDISE STORES',
58
+ '5411' => 'GROCERY STORES SUPERMARKETS',
59
+ '5422' => 'FREEZER LOCKER MEAT PROVISIONERS',
60
+ '5441' => 'CANDY NUT CONFECTIONERY STORES',
61
+ '5451' => 'DAIRY PRODUCTS STORES',
62
+ '5462' => 'BAKERIES',
63
+ '5499' => 'MISC FOOD STORES SPECIALTY MARKETS CONVENIENCE',
64
+ '5511' => 'AUTO + TRUCK DLRS NEW + USED SALES SVC PARTS',
65
+ '5531' => 'AUTO STORE HOME SUPPLY STORES',
66
+ '5532' => 'AUTOMOTIVE TIRE STORES',
67
+ '5533' => 'AUTOMOTIVE PARTS ACCESSORIES STORES',
68
+ '5541' => 'SERVICE STATIONS WITH OR WITHOUT ANCILLARY SERVICE',
69
+ '5551' => 'BOAT DEALERS',
70
+ '5561' => 'RECREATIONAL + UTILITY TRAILERS CAMPER DEALERS',
71
+ '5571' => 'MOTORCYCLE SHOPS AND DEALERS',
72
+ '5598' => 'SNOWMOBILE DEALERS',
73
+ '5599' => 'MISC-AUTO-AIRCRAFT-FARM EQUIP NOT ELSEWHERE CLASS',
74
+ '5611' => 'MEN\'S AND BOY\'S CLOTHING AND FURNISHINGS STORE',
75
+ '5621' => 'WOMEN\'S READY TO WEAR STORES',
76
+ '5631' => 'WOMEN\'S ACCESSORY AND SPECIALTY STORES',
77
+ '5641' => 'CHILDREN\'S AND INFANT\'S WEAR STORES',
78
+ '5651' => 'FAMILY CLOTHING STORES',
79
+ '5655' => 'SPORTS APPAREL RIDING APPAREL STORES',
80
+ '5661' => 'SHOE STORES',
81
+ '5691' => 'MEN\'S AND WOMEN\'S CLOTHING STORES',
82
+ '5697' => 'TAILORS SEAMSTRESSES MENDING ALTERATIONS',
83
+ '5698' => 'WIG AND TOUPEE SHOPS',
84
+ '5699' => 'MISCELLANEOUS APPAREL AND ACCESSORY STORES',
85
+ '5712' => 'FURNITURE HOME FURNISH + EQUIP EXCL APPLIANCES',
86
+ '5713' => 'FLOOR COVERING STORES',
87
+ '5714' => 'DRAPERY WINDOW COVERINGS AND UPHOLSTERY STORES',
88
+ '5718' => 'FIREPLACE FIREPLACE SCREENS + ACCESSORIES STORES',
89
+ '5719' => 'MISCELLANEOUS HOUSE FURNISHING SPECIALTY SHOPS',
90
+ '5722' => 'HOUSEHOLD APPLIANCE STORES',
91
+ '5732' => 'ELECTRONIC SALES',
92
+ '5733' => 'MUSIC STORES-INSTRUMENTS PIANOS SHEET MUSIC',
93
+ '5734' => 'COMPUTER SOFTWARE STORES',
94
+ '5735' => 'RECORD SHOPS',
95
+ '5912' => 'DRUG STORES PHARMACIES',
96
+ '5931' => 'USED MERCHANDISE STORES SECOND HAND STORES',
97
+ '5932' => 'ANTIQUE SHOPS-SALES REPAIRS RESTORATION SERVICES',
98
+ '5933' => 'PAWN SHOPS',
99
+ '5935' => 'WRECKING AND SALVAGE YARDS',
100
+ '5937' => 'ANTIQUE REPRODUCTION STORES',
101
+ '5940' => 'BICYCLE SHOPS-SALES AND SERVICE',
102
+ '5941' => 'SPORTING GOODS STORES',
103
+ '5942' => 'BOOK STORES',
104
+ '5943' => 'STATIONERY OFFICE AND SCHOOL SUPPLY STORES',
105
+ '5944' => 'JEWELRY-WATCHES CLOCKS AND SILVERWARE STORES',
106
+ '5945' => 'HOBBY TOY AND GAME SHOPS',
107
+ '5946' => 'CAMERA AND PHOTOGRAPHIC SUPPLY STORES',
108
+ '5947' => 'GIFT CARD NOVELTY AND SOUVENIR SHOPS',
109
+ '5948' => 'LUGGAGE AND LEATHER GOODS STORES',
110
+ '5949' => 'SEWING NEEDLEWORK FABRIC AND PIECE GOODS STORES',
111
+ '5950' => 'GLASSWARE AND CRYSTAL STORES',
112
+ '5964' => 'DIRECT MARKETING-CATALOG MERCHANTS',
113
+ '5965' => 'DIRECT MARKETING-COMBINATION CATALOG-RETAIL MERCH.',
114
+ '5966' => 'DIRECT MARKETING-OUTBOUND TELEMARKETING MERCHANTS',
115
+ '5967' => 'DIRECT MARKETING-INBOUND TELEMARKETING MERCHANTS',
116
+ '5968' => 'DIRECT MARKETING-CONTINUITY-SUBSCRIPTION MERCHANTS',
117
+ '5969' => 'DIRECT MARKETING-OTHER DIRECT MARKETERS-NOT ELSEW.',
118
+ '5970' => 'ARTIST SUPPLY STORES CRAFT SHOPS',
119
+ '5971' => 'ART DEALERS AND GALLERIES',
120
+ '5973' => 'RELIGIOUS GOODS STORES',
121
+ '5975' => 'HEARING AIDS-SALES SERVICE SUPPLY STORES',
122
+ '5976' => 'ORTHOPEDIC GOODS-ARTIFICIAL LIMB STORES',
123
+ '5977' => 'COSMETIC STORES',
124
+ '5978' => 'TYPEWRITER STORES-SALES SERVICE RENTALS',
125
+ '5983' => 'FUEL DEALERS-OIL WOOD COAL LIQUEFIED PETROLEUM',
126
+ '5992' => 'FLORISTS',
127
+ '5994' => 'NEWS DEALERS AND NEWSSTANDS',
128
+ '5995' => 'PET SHOPS - PET FOODS AND SUPPLIES',
129
+ '5996' => 'SWIMMING POOLS - SALES AND SUPPLIES',
130
+ '5997' => 'ELECTRIC RAZOR STORES - SALES AND SERVICE',
131
+ '5998' => 'TENT AND AWNING SHOPS',
132
+ '5999' => 'MISCELLANEOUS AND SPECIALTY RETAIL STORES',
133
+ '7032' => 'SPORTING AND RECREATIONAL CAMPS',
134
+ '7033' => 'TRAILER PARKS AND CAMPGROUNDS',
135
+ '7210' => 'LAUNDRY CLEANING AND GARMENT SERVICES',
136
+ '7211' => 'LAUNDRY SERVICES - FAMILY AND COMMERICAL',
137
+ '7216' => 'DRY CLEANERS',
138
+ '7217' => 'CARPET AND UPHOLSTERY CLEANING',
139
+ '7221' => 'PHOTOGRAPHIC STUDIOS',
140
+ '7230' => 'BEAUTY SHOPS AND BARBER SHOPS',
141
+ '7251' => 'SHOE REPAIR SHOPS SHOE SHINE HAT CLEANING',
142
+ '7278' => 'BUYING-SHOPPING SERVICES CLUBS',
143
+ '7296' => 'CLOTHING RENTAL-COSTUMES UNIFORMS FORMAL WEAR',
144
+ '7299' => 'OTHER SERVICES (NOT ELSEWHERE CLASSIFIED)',
145
+ '7311' => 'ADVERTISING SERVICES',
146
+ '7332' => 'BLUEPRINTING AND PHOTOCOPYING SERVICES',
147
+ '7333' => 'COMMERCIAL PHOTOGRAPHY ART GRAPHICS',
148
+ '7338' => 'QUICK COPY REPRODUCTION AND BLUEPRINTING SERVICES',
149
+ '7339' => 'STENOGRAPHIC AND SECRETARIAL SUPPORT SERVICES',
150
+ '7342' => 'EXTERMINATING AND DISINFECTING SERVICES',
151
+ '7349' => 'CLEANING AND MAINTENANCE JANITORIAL SERVICES',
152
+ '7361' => 'EMPLOYMENT AGENCIES TEMPORARY HELP SERVICES',
153
+ '7372' => 'COMPUTER AND DATA PROCESSING SERVICES',
154
+ '7375' => 'INFORMATION RETRIEVAL SERVICES',
155
+ '7379' => 'COMPUTER MAIN.-REPAIR-SERVICES NOT ELSEWHERE CLASS',
156
+ '7392' => 'MANAGEMENT CONSULTING AND PUBLIC RELATIONS SVCS',
157
+ '7393' => 'DETECTIVE + PROTECTIVE AGENCIES SECURITY SERVICES',
158
+ '7394' => 'EQUIP RENTAL + LEASING TOOL + FURNITURE RENTAL',
159
+ '7395' => 'PHOTOFINISHING LABORATORIES PHOTO DEVELOPING',
160
+ '7399' => 'BUSINESS SERVICES-NOT ELSEWHERE CLASSIFIED',
161
+ '7513' => 'TRUCK AND UTILITY TRAILER RENTAL',
162
+ '7519' => 'MOTOR HOME AND RECREATIONAL VEHICLE RENTAL',
163
+ '7523' => 'AUTOMOBILE PARKING LOTS AND GARAGES',
164
+ '7542' => 'CAR WASHES',
165
+ '7549' => 'TOWING SERVICES',
166
+ '7622' => 'ELECTRONIC REPAIR SHOPS',
167
+ '7623' => 'AIR CONDITIONING AND REFRIGERATION REPAIR SHOPS',
168
+ '7629' => 'ELECTRICAL AND SMALL APPLIANCE REPAIR SHOPS',
169
+ '7631' => 'WATCH CLOCK AND JEWELRY REPAIR SHOPS',
170
+ '7641' => 'REUPHOLSTERY AND FURNITURE REPAIR REFINISHING',
171
+ '7692' => 'WELDING REPAIR',
172
+ '7699' => 'MISCELLANEOUS REPAIR SHOPS AND RELATED SERVICES',
173
+ '7829' => 'MOTION PICTURE-VIDEO TAPE PRODUCTION-DISTRIBUTION',
174
+ '7832' => 'MOTION PICTURE THEATERS',
175
+ '7841' => 'VIDEO TAPE RENTAL STORES',
176
+ '7911' => 'DANCE HALLS STUDIOS AND SCHOOLS',
177
+ '7922' => 'THEATRICAL PRODUCERS-EXCL MOTION PIX TICKET AGNCY',
178
+ '7929' => 'BANDS ORCHESTRAS MISC ENTERTAINERS NOT ELSEWHERE',
179
+ '7933' => 'BOWLING ALLEYS',
180
+ '7941' => 'COMMERCIAL SPORTS PROFESSIONAL CLBS ATHLETIC FLD',
181
+ '7991' => 'TOURIST ATTRACTIONS AND EXHIBITS',
182
+ '7992' => 'GOLF COURSES-PUBLIC',
183
+ '7993' => 'VIDEO AMUSEMENT GAME SUPPLIES',
184
+ '7997' => 'MBRSHIP CLUBS COUNTRY CLUBS PRIVATE GOLF COURSES',
185
+ '7998' => 'AQUARIUMS SEAQUARIUMS AND DOLPHINARIUMS',
186
+ '7999' => 'RECREATION SERVICES (NOT ELSEWHERE CLASSIFIED)',
187
+ '8043' => 'OPTICIANS OPTICAL GOODS + EYEGLASSES',
188
+ '8044' => 'OPTICAL GOODS AND EYEGLASSES',
189
+ '8062' => 'HOSPITALS',
190
+ '8071' => 'MEDICAL AND DENTAL LABORATORIES',
191
+ '8099' => 'MEDICAL SVCS HEALTH PRACTICE-NOT CLASS ELSEWHERE',
192
+ '8211' => 'ELEMENTARY AND SECONDARY SCHOOLS',
193
+ '8220' => 'COLLEGES UNIV PRO SCHOOLS JUNIOR COLLEGES',
194
+ '8241' => 'CORRESPONDENCE SCHOOLS',
195
+ '8244' => 'BUSINESS AND SECRETARIAL SCHOOLS',
196
+ '8249' => 'VOCATIONAL AND TRADE SCHOOLS',
197
+ '8299' => 'SCHOOLS + EDUCATIONAL SVC-NOT ELSEWHERE CLASSIFIED',
198
+ '8398' => 'CHARITABLE AND SOCIAL SERVICE ORGANIZATIONS',
199
+ '8641' => 'CIVIC SOCIAL AND FRATERNAL ASSOCIATIONS',
200
+ '8699' => 'MEMBERSHIP ORGANIZATIONS-NOT ELSEWHERE CLASSIFIED',
201
+ '8734' => 'TESTING LABORATORIES (NON-MEDICAL)',
202
+ '8911' => 'ENGINEERING ARCHITECTURAL AND SURVEYING SERVICES',
203
+ '8931' => 'ACCOUNTING AUDITING AND BOOKKEEPING SERVICES',
204
+ '8999' => 'PROFESSIONAL SERVICES-NOT ELSEWHERE CLASSIFIED',
205
+ '9399' => 'GOVERNMENT SERVICES-NOT ELSEWHERE CLASSIFIED',
206
+ '9402' => 'POSTAL SERVICES-GOVERNMENT ONLY',
207
+ '9405' => 'INTRA GOVERNMENT PURCHASES',
208
+ '9702' => 'GCAS EMERGENCY SERVICES',
209
+ '9950' => 'INTRA COMPANY PURCHASES',
210
+ '0780' => 'LANDSCAPING AND HORTICULTURAL SERVICES',
211
+ '1520' => 'GENERAL CONTRACTORS-RESIDENTIAL BUILDINGS',
212
+ '1711' => 'HEATING PLUMBING AIR CONDITIONING CONTRACTORS',
213
+ '1731' => 'ELECTRICAL CONTRACTORS',
214
+ '1740' => 'MASONRY STONEWORK TILE SET PLASTER INSULATION',
215
+ '1750' => 'CARPENTRY CONTRACTORS',
216
+ '1761' => 'ROOFING + SIDING SHEET METAL WORK CONTRACTORS',
217
+ '1771' => 'CONCRETE WORK CONTRACTORS',
218
+ '1799' => 'SPECIAL TRADE CONTRACTORS-NOT ELSEWHERE CLASSIFIED',
219
+ '4214' => 'TRUCKING-LOCAL-LONG DIST- MOVING-STORAGE-LOC DEL',
220
+ '3501' => 'HOLIDAY INNS',
221
+ '3502' => 'BEST WESTERN HOTELS',
222
+ '3503' => 'SHERATON HOTELS',
223
+ '3504' => 'HILTON HOTELS',
224
+ '3505' => 'FORTE HOTELS',
225
+ '3506' => 'GOLDEN TULIP HOTELS',
226
+ '3507' => 'FRIENDSHIP INNS',
227
+ '3508' => 'QUALITY INNS',
228
+ '3509' => 'MARRIOTT',
229
+ '3510' => 'DAYS INNS',
230
+ '3511' => 'ARABELLA HOTELS',
231
+ '3512' => 'INTERCONTINENTAL HOTELS',
232
+ '3513' => 'WESTIN HOTELS',
233
+ '3514' => 'AMERISUITES',
234
+ '3515' => 'RODEWAY INNS',
235
+ '3516' => 'LA QUINTA MOTOR INNS',
236
+ '3517' => 'AMERICANA HOTELS',
237
+ '3518' => 'SOL HOTELS',
238
+ '3519' => 'PULLMAN INT\'L HOTELS',
239
+ '3520' => 'MERIDIEN HOTELS',
240
+ '3523' => 'PENINSULA HOTELS',
241
+ '3524' => 'WELCOMGROUP HOTELS',
242
+ '3525' => 'DUNFEY HOTELS',
243
+ '3526' => 'PRINCE HOTELS',
244
+ '3528' => 'RED LION INNS',
245
+ '3529' => 'CP (CANADIAN PACIFIC) HOTELS',
246
+ '3530' => 'RENAISSANCE HOTELS',
247
+ '3534' => 'SOUTHERN PACIFIC HOTELS',
248
+ '3535' => 'HILTON INTERNATIONAL',
249
+ '3536' => 'AMFAC HOTELS',
250
+ '3537' => 'ANA HOTELS',
251
+ '3538' => 'CONCORDE HOTELS',
252
+ '3539' => 'SUMMERFIELD SUITES HOTEL',
253
+ '3542' => 'ROYAL HOTELS',
254
+ '3543' => 'FOUR SEASONS HOTELS',
255
+ '3544' => 'CIGA HOTELS',
256
+ '3545' => 'SHANGRI-LA INTERNATIONAL',
257
+ '3546' => 'SIERRA SUITES HOTELS',
258
+ '3550' => 'REGAL 8 INNS',
259
+ '3553' => 'PARKS INNS INTERNATIONAL',
260
+ '3558' => 'JOLLY HOTELS',
261
+ '3562' => 'COMFORT INNS',
262
+ '3563' => 'JOURNEY\'S END MOTELS',
263
+ '3565' => 'RELAX INNS',
264
+ '3568' => 'LADBROKE HOTELS',
265
+ '3570' => 'FORUM HOTELS',
266
+ '3573' => 'SANDMAN HOTELS',
267
+ '3574' => 'VENTURE INN',
268
+ '3575' => 'VAGABOND HOTELS',
269
+ '3581' => 'DELTA HOTELS',
270
+ '3583' => 'SAS HOTELS',
271
+ '3584' => 'PRINCESS HOTELS INTERNATIONAL',
272
+ '3587' => 'DORAL HOTELS',
273
+ '3588' => 'HELMSLEY HOTELS',
274
+ '3590' => 'FAIRMONT HOTELS',
275
+ '3591' => 'SONESTA HOTELS',
276
+ '3592' => 'OMNI HOTELS',
277
+ '3593' => 'CUNARD HOTELS',
278
+ '3595' => 'HOSPITALITY INNS',
279
+ '3598' => 'REGENT INT\'L HOTEL',
280
+ '3599' => 'PANNONIA HOTELS',
281
+ '3612' => 'MOVENPICK HOTELS',
282
+ '3615' => 'TRAVELODGE',
283
+ '3622' => 'MERLIN HOTEL GROUP',
284
+ '3623' => 'DORINT HOTELS',
285
+ '3629' => 'DAN HOTELS',
286
+ '3631' => 'SLEEP INN',
287
+ '3633' => 'RANK HOTELS',
288
+ '3635' => 'RESO HOTEL',
289
+ '3636' => 'SAROVA HOTELS',
290
+ '3637' => 'RAMADA INNS',
291
+ '3638' => 'HOWARD JOHNSON',
292
+ '3640' => 'HYATT HOTELS',
293
+ '3641' => 'SOFITEL HOTELS',
294
+ '3642' => 'NOVOTEL HOTELS',
295
+ '3643' => 'STEIGENBERGER HOTELS',
296
+ '3644' => 'ECONOLODGES',
297
+ '3646' => 'SWALLOW HOTELS',
298
+ '3647' => 'HUSA HOTELS',
299
+ '3648' => 'DE VERA HOTELS',
300
+ '3649' => 'RADISSON HOTELS',
301
+ '3650' => 'RED ROOF INNS',
302
+ '3652' => 'EMBASSY HOTELS',
303
+ '3664' => 'FLAG INNS',
304
+ '3665' => 'HAMPTON INN HOTELS',
305
+ '3668' => 'MARITIM HOTELS',
306
+ '3670' => 'ARCADE HOTELS',
307
+ '3678' => 'CUMULUS HOTELS',
308
+ '3681' => 'ADAMS MARK HOTELS',
309
+ '3683' => 'BRADBURY SUITES',
310
+ '3684' => 'BUDGET HOST INNS',
311
+ '3685' => 'BUDGETEL INNS',
312
+ '3687' => 'CLARION HOTELS',
313
+ '3688' => 'COMPRI HOTELS',
314
+ '3689' => 'CONSORT HOTELS',
315
+ '3690' => 'COURTYARD INNS',
316
+ '3692' => 'DOUBLETREE HOTELS',
317
+ '3694' => 'ECONOMY INNS OF AMERICA',
318
+ '3695' => 'EMBASSY SUITES',
319
+ '3696' => 'EXCEL INN',
320
+ '3697' => 'FAIRFIELD HOTELS',
321
+ '3698' => 'HARLEY HOTELS',
322
+ '3700' => 'MOTEL 6',
323
+ '3702' => 'THE REGISTRY HOTELS',
324
+ '3703' => 'RESIDENCE INN',
325
+ '3704' => 'ROYCE HOTELS',
326
+ '3705' => 'SANDMAN INN',
327
+ '3706' => 'SHILO INN',
328
+ '3707' => 'SHONEY\'S INN',
329
+ '3709' => 'SUPER 8 MOTELS',
330
+ '3710' => 'THE RITZ CARLTON',
331
+ '3715' => 'FAIRFIELD INN',
332
+ '3716' => 'CARLTON HOTELS',
333
+ '3717' => 'CITY LODGE HOTELS',
334
+ '3718' => 'KAROS HOTELS',
335
+ '3719' => 'PROTEA HOTELS',
336
+ '3720' => 'SOUTHERN SUN HOTELS',
337
+ '3721' => 'CONRAD HOTELS',
338
+ '3722' => 'WYNDHAM HOTELS',
339
+ '3727' => 'BROADMOOR HOTEL',
340
+ '3730' => 'MGM GRAND',
341
+ '3734' => 'HARVEY BRISTOL HOTELS',
342
+ '3735' => 'MASTERS ECONOMY INNS',
343
+ '3740' => 'TOWNEPLACE SUITES',
344
+ '3743' => 'BILTMORE HOTEL AND SUITES',
345
+ '3745' => 'ST REGIS HOTEL',
346
+ '3746' => 'ELIOT HOTELS',
347
+ '3748' => 'WELLESLEY INNS',
348
+ '3750' => 'CROWNE PLAZA HOTELS',
349
+ '3751' => 'HOMEWOOD SUITES',
350
+ '3752' => 'PEABODY HOTELS',
351
+ '3770' => 'SPRINGHILL SUITES',
352
+ '4121' => 'TAXICABS-LIMOUSINES',
353
+ '7011' => 'LODGING-HOTELS MOTELS RESORTS',
354
+ '5811' => 'CATERERS',
355
+ '5812' => 'EATING PLACES RESTAURANTS',
356
+ '5813' => 'DRINKING PLACES-BARS-TAVERNS-NITECLB-LOUNGE-DISCO',
357
+ '5814' => 'FAST FOOD RESTAURANTS (QUICK PAY SERVICE PILOT)',
358
+ '3000' => 'UNITED AIRLINES',
359
+ '3001' => 'AMERICAN AIRLINES',
360
+ '3002' => 'PAN AMERICAN',
361
+ '3004' => 'TRANS WORLD AIRLINES',
362
+ '3005' => 'BRITISH AIRWAYS BRITISH AWYS',
363
+ '3006' => 'JAPAN AIR LINES',
364
+ '3007' => 'AIR FRANCE',
365
+ '3008' => 'LUFTHANSA',
366
+ '3009' => 'AIR CANADA',
367
+ '3010' => 'ROYAL DUTCH AIRLINES (KLM)',
368
+ '3011' => 'AEROFLOT',
369
+ '3012' => 'QANTAS',
370
+ '3013' => 'ALITALIA',
371
+ '3014' => 'SAUDI ARABIAN AIRLINES',
372
+ '3015' => 'SWISSAIR',
373
+ '3016' => 'SCANDINAVIAN AIRLINE SYSTEM (SAS)',
374
+ '3017' => 'SOUTH AFRICAN AIRWAYS',
375
+ '3018' => 'VARIG (BRAZIL)',
376
+ '3020' => 'AIR INDIA',
377
+ '3021' => 'AIR ALGERIE',
378
+ '3022' => 'PHILIPPINE AIRLINES',
379
+ '3023' => 'MEXICANA',
380
+ '3024' => 'PAKISTAN INTERNATIONAL',
381
+ '3025' => 'AIR NEW ZEALAND LIMITED INTERNATIONAL',
382
+ '3026' => 'EMIRATES AIRLINES (ABBR. EMIRATES)',
383
+ '3027' => 'UNION DE TRANSPORTS AERIENS',
384
+ '3028' => 'AIR MALTA',
385
+ '3029' => 'SABENA',
386
+ '3030' => 'AEROLINEAS ARGENTINAS',
387
+ '3031' => 'OLYMPIC AIRWAYS',
388
+ '3032' => 'EL AL',
389
+ '3033' => 'ANSETT AIRLINES',
390
+ '3034' => 'AUSTRALIAN AIRWAYS (TAA)',
391
+ '3035' => 'TAP (PORTUGAL)',
392
+ '3036' => 'VASP (BRAZIL)',
393
+ '3037' => 'EGYPTAIR',
394
+ '3038' => 'KUWAIT AIRWAYS',
395
+ '3039' => 'AVIANCA',
396
+ '3040' => 'GULF AIR (BAHRAIN)',
397
+ '3041' => 'BALKAN-BULGARIAN AIRLINES',
398
+ '3042' => 'FINNAIR',
399
+ '3043' => 'AER LINGUS',
400
+ '3044' => 'AIR LANKA (ABBR. AIR LANKA)',
401
+ '3045' => 'NIGERIA AIRWAYS',
402
+ '3046' => 'CRUZERIO DO SUL (BRAZIL)',
403
+ '3047' => 'THY (TURKEY)',
404
+ '3048' => 'ROYAL AIR MAROC',
405
+ '3049' => 'TUNIS AIR',
406
+ '3050' => 'ICELANDAIR',
407
+ '3051' => 'AUSTRIAN AIRLINES',
408
+ '3052' => 'LAN-CHILE',
409
+ '3053' => 'AVIACO (SPAIN)',
410
+ '3054' => 'LADECO (CHILE)',
411
+ '3055' => 'LAB (BOLIVIA)',
412
+ '3056' => 'QUEBECAIRE',
413
+ '3057' => 'EAST-WEST AIRLINES (AUSTRALIA)',
414
+ '3058' => 'DELTA',
415
+ '3060' => 'NORTHWEST',
416
+ '3061' => 'CONTINENTAL',
417
+ '3063' => 'USAIRWAYS',
418
+ '3064' => 'ADRIA AIRWAYS (ABBR- ADRIA)',
419
+ '3065' => 'AIR INTER',
420
+ '3066' => 'SOUTHWEST AIRLINES',
421
+ '3067' => 'VANGUARD AIRLINES (ABBR- VANGUARD)',
422
+ '3071' => 'AIR BRITISH COLUMBIA',
423
+ '3075' => 'SINGAPORE AIRLINES',
424
+ '3076' => 'AEROMEXICO',
425
+ '3077' => 'THAI AIRWAYS',
426
+ '3078' => 'CHINA AIRLINES',
427
+ '3081' => 'NORDAIR',
428
+ '3082' => 'KOREAN AIRLINES',
429
+ '3083' => 'AIR AFRIQUE (RK)',
430
+ '3084' => 'EVA AIRWAYS (BR)',
431
+ '3085' => 'MIDWEST EXPRESS AIRLINES',
432
+ '3086' => 'CARNIVAL AIRLINES (KW)',
433
+ '3087' => 'METRO AIRLINES',
434
+ '3088' => 'CROATIA AIR',
435
+ '3089' => 'TRANSAERO (ABBR. TRANSAERO)',
436
+ '3090' => 'UNI AIRWAYS',
437
+ '3092' => 'MIDWAY AIRLINES',
438
+ '3094' => 'ZAMBIA AIRWAYS',
439
+ '3095' => 'WARDAIR (CANADA)',
440
+ '3096' => 'AIR ZIMBABWE',
441
+ '3097' => 'SPANAIR',
442
+ '3098' => 'ASIANA AIRLINES',
443
+ '3099' => 'CATHAY PACIFIC',
444
+ '3100' => 'MALAYSIAN AIRLINE SYSTEM',
445
+ '3102' => 'IBERIA',
446
+ '3103' => 'GARUDA (INDONESIA)',
447
+ '3106' => 'BRAATHENS S.A.F.E. (NORWAY)',
448
+ '3110' => 'WINGS AIRWAYS',
449
+ '3111' => 'BRITISH MIDLAND',
450
+ '3112' => 'WINDWARD ISLAND',
451
+ '3115' => 'TOWER AIR',
452
+ '3117' => 'VENEZOLANA INTERNATIONAL DE AVIACION (VIASA)',
453
+ '3118' => 'VALLEY AIRLINES',
454
+ '3125' => 'TAN AIRLINES',
455
+ '3126' => 'TALAIR',
456
+ '3127' => 'TACA INTERNATIONAL',
457
+ '3129' => 'SURINAM AIRWAYS',
458
+ '3130' => 'SUNWORLD INTERNATIONAL AIRWAYS',
459
+ '3133' => 'SUNBELT AIRLINES',
460
+ '3135' => 'SUDAN AIRWAYS',
461
+ '3137' => 'SINGLETON AIR',
462
+ '3138' => 'SIMMONS AIRLINES',
463
+ '3143' => 'SCENIC AIRLINES',
464
+ '3144' => 'VIRGIN ATLANTIC',
465
+ '3145' => 'SAN JUAN AIRLINES',
466
+ '3146' => 'LUXAIR',
467
+ '3151' => 'AIR ZAIRE',
468
+ '3154' => 'PRINCEVILLE',
469
+ '3159' => 'PROVINCETOWN-BOSTON AIRWAYS (PBA)',
470
+ '3161' => 'ALL NIPPON AIRWAYS',
471
+ '3164' => 'NORONTAIR',
472
+ '3165' => 'NEW YORK HELICOPTER',
473
+ '3170' => 'MOUNT COOK',
474
+ '3171' => 'CANADIAN AIRLINES',
475
+ '3172' => 'NATION AIR',
476
+ '3175' => 'MIDDLE EAST AIR',
477
+ '3176' => 'METROFLIGHT AIRLINES',
478
+ '3178' => 'MESA AIR',
479
+ '3181' => 'MALEV HUNGARIAN AIRLINES',
480
+ '3182' => 'LOT - POLISH AIRLINES',
481
+ '3184' => 'LIAT',
482
+ '3185' => 'LAV LINEA AEROPOSTAL VENEZOLANA',
483
+ '3186' => 'LAP LINEAS AEREAS PARAGUAYAS',
484
+ '3187' => 'LACSA (COSTA RICA)',
485
+ '3190' => 'JUGOSLAV AIR',
486
+ '3191' => 'ISLAND AIRLINES',
487
+ '3192' => 'IRAN AIR',
488
+ '3193' => 'INDIAN AIRLINES',
489
+ '3196' => 'HAWAIIAN AIR',
490
+ '3197' => 'HAVASU AIRLINES',
491
+ '3200' => 'GUYANA AIRWAYS',
492
+ '3203' => 'GOLDEN PACIFIC AIR',
493
+ '3204' => 'FREEDOM AIRLINES',
494
+ '3206' => 'CHINA EASTERN AIRLINES (ABBR- CHINEASTAIR)',
495
+ '3212' => 'DOMINICANA DE AVIACION',
496
+ '3215' => 'DAN AIR SERVICES',
497
+ '3216' => 'CUMBERLAND AIRLINES',
498
+ '3217' => 'CSA CESKOSLOVENSKE AEROLINIE',
499
+ '3218' => 'CROWN AIR',
500
+ '3219' => 'COMPANIA PANAMENA DE AVIACION (COPA)',
501
+ '3220' => 'COMPANIA FAUCETT',
502
+ '3221' => 'TRANSPORTES AEREOS MILITARES ECUATORIANOS',
503
+ '3222' => 'COMMAND AIRWAYS',
504
+ '3223' => 'COMAIR',
505
+ '3228' => 'CAYMAN AIRWAYS',
506
+ '3229' => 'SAETA (SOCIEDAD ECUATORIANAS DE TRANSPORTES AEREO)',
507
+ '3231' => 'SAHSA (SERVICIO AERO DE HONDURAS)',
508
+ '3233' => 'CAPITOL AIR',
509
+ '3234' => 'BWIA INTERNATIONAL',
510
+ '3235' => 'BROCKWAY AIR',
511
+ '3238' => 'BEMIDJI AVIATION',
512
+ '3239' => 'BAR HARBOR AIRLINES',
513
+ '3240' => 'BAHAMASAIR',
514
+ '3241' => 'AVIATECA (GUATEMALA)',
515
+ '3242' => 'AVENSA',
516
+ '3243' => 'AUSTRIAN AIR SERVICE',
517
+ '3251' => 'ALOHA AIRLINES',
518
+ '3252' => 'ALM ANTILEAN AIRLINES',
519
+ '3253' => 'AMERICA WEST',
520
+ '3254' => 'US AIR SHUTTLE',
521
+ '3256' => 'ALASKA AIRLINES INC.',
522
+ '3259' => 'AMERICAN TRANS AIR ATA AIR',
523
+ '3261' => 'AIR CHINA',
524
+ '3262' => 'RENO AIR INC.',
525
+ '3263' => 'AERO SERVICIO CARABOBO',
526
+ '3266' => 'AIR SEYCHELLES',
527
+ '3267' => 'AIR PANAMA INTERNATIONAL',
528
+ '3280' => 'AIR JAMAICA',
529
+ '3282' => 'AIR DJIBOUTI',
530
+ '3284' => 'AERO VIRGIN ISLANDS',
531
+ '3285' => 'AERO PERU',
532
+ '3286' => 'AERO.NICARAGUENSES',
533
+ '3287' => 'AERO COACH AVIATION',
534
+ '3292' => 'CYPRUS AIRWAYS',
535
+ '3293' => 'EQUATORIANA',
536
+ '3294' => 'ETHIOPIAN AIRLINES',
537
+ '3295' => 'KENYA AIRWAYS',
538
+ '3297' => 'TAROM ROMANIAN AIR TRANSPORT',
539
+ '3298' => 'AIR MAURITIUS',
540
+ '3299' => 'WIDEROE\'S FLYVESELSKAP',
541
+ '3351' => 'AFFILIATED AUTO RENTAL',
542
+ '3352' => 'AMERICAN INT\'L',
543
+ '3353' => 'BROOKS RENT A CAR',
544
+ '3354' => 'ACTION AUTO RENTAL',
545
+ '3357' => 'HERTZ CORPORATION',
546
+ '3359' => 'PAYLESS CAR RENTAL',
547
+ '3360' => 'SNAPPY CAR RENTAL',
548
+ '3361' => 'AIRWAYS RENT-A-CAR',
549
+ '3362' => 'ALTRA AUTO RENTAL',
550
+ '3364' => 'AGENCY RENT-A-CAR',
551
+ '3366' => 'BUDGET RENT-A-CAR',
552
+ '3368' => 'HOLIDAY RENT-A-CAR',
553
+ '3370' => 'RENT A WRECK',
554
+ '3376' => 'AJAX RENT-A-CAR',
555
+ '3380' => 'TRIANGLE RENT A CAR',
556
+ '3381' => 'EUROPE CAR',
557
+ '3385' => 'TROPICAL RENT-A-CAR',
558
+ '3386' => 'SHOWCASE RENTAL CARS',
559
+ '3387' => 'ALAMO RENT-A-CAR',
560
+ '3389' => 'AVIS RENT A CAR',
561
+ '3390' => 'DOLLAR RENT A CAR',
562
+ '3391' => 'EUROPE BY CAR',
563
+ '3393' => 'NATIONAL CAR RENTAL',
564
+ '3394' => 'KEMWELL GROUP RENT-A-CAR',
565
+ '3395' => 'THRIFTY CAR RENTAL',
566
+ '3396' => 'TILDEN RENT-A-CAR',
567
+ '3398' => 'ECONO-CAR RENT-A-CAR',
568
+ '3400' => 'AUTO HOST CAR RENTAL',
569
+ '3405' => 'ENTERPRISE RENT-A-CAR',
570
+ '3409' => 'GENERAL RENT-A-CAR',
571
+ '3412' => 'A1 RENT-A-CAR',
572
+ '3414' => 'GODFREY NATIONAL RENT-A-CAR',
573
+ '3420' => 'ANSA INTERNATIONAL',
574
+ '3421' => 'ALLSTATE RENT-A-CAR',
575
+ '3423' => 'AVCAR RENT-A-CAR',
576
+ '3425' => 'AUTOMATE RENT-A-CAR',
577
+ '3427' => 'AVON RENT-A-CAR',
578
+ '3428' => 'CAREY RENT-A-CAR',
579
+ '3429' => 'INSURANCE RENT-A-CAR',
580
+ '3430' => 'MAJOR RENT A CAR',
581
+ '3431' => 'REPLACEMENT RENT-A-CAR',
582
+ '3432' => 'RESERVE RENT-A-CAR',
583
+ '3433' => 'UGLY DUCKLING RENT-A-CAR',
584
+ '3434' => 'USA RENT-A-CAR',
585
+ '3435' => 'VALUE RENT-A-CAR',
586
+ '3436' => 'AUTOHANSA RENT-A-CAR',
587
+ '3437' => 'CITE RENT-A-CAR',
588
+ '3438' => 'INTERENT RENT-A-CAR',
589
+ '3439' => 'MILLEVILLE RENT-A-CAR',
590
+ '3441' => 'ADVANTAGE RENT A CAR',
591
+ '4011' => 'RAILROADS',
592
+ '4111' => 'LOCAL + SUBURBAN PASS TRANSPORTATION INCL FERRIES',
593
+ '4112' => 'PASSENGER RAILWAYS',
594
+ '4119' => 'AMBULANCE SERVICES',
595
+ '4131' => 'BUS LINES',
596
+ '4225' => 'PUBLIC WAREHOUSING-FARM REFRIG GOODS HHG STORAGE',
597
+ '4411' => 'CRUISE LINES',
598
+ '4457' => 'BOAT RENTALS AND BOAT LEASES',
599
+ '4511' => 'AIRLINES AIR CARRIERS',
600
+ '4582' => 'AIRPORTS FLYING FIELDS AIRPORT TERMINALS',
601
+ '4722' => 'TRAVEL AGENCIES AND TOUR OPERATORS',
602
+ '4784' => 'TOLLS ROAD AND BRIDGE FEES',
603
+ '4789' => 'TRANSPORTATION SERVICES NOT ELSEWHERE CLASSIFIED',
604
+ '4829' => 'WIRE TRANSFER MONEY ORDERS (WTMOS)',
605
+ '5271' => 'MOBILE HOME DEALERS',
606
+ '5309' => 'DUTY FREE STORES',
607
+ '5521' => 'AUTO + TRUCK DLRS USED ONLY-SALES',
608
+ '5542' => 'AUTOMATED FUEL DISPENSER',
609
+ '5592' => 'MOTOR HOME DEALERS',
610
+ '5681' => 'FURRIERS AND FUR SHOPS',
611
+ '5921' => 'PACKAGE STORES BEER WINE LIQUOR',
612
+ '5960' => 'DIRECT MARKETING-INSURANCE SERVICES',
613
+ '5962' => 'DIRECT MARKETING-TRAVEL RELATED ARRANGEMENT SERVS.',
614
+ '5963' => 'DOOR-TO-DOOR SALES',
615
+ '5972' => 'STAMP + COIN STORES-PHILATELIC + NUMISMATIC SUPPLY',
616
+ '5993' => 'CIGAR STORES AND STANDS',
617
+ '6010' => 'FINANCIAL INSTITUTIONS-MANUAL CASH DISBURSEMENTS',
618
+ '6011' => 'FINANCIAL INSTITUTIONS-AUTOMATED CASH DISBURSEMENT',
619
+ '6012' => 'FINANCIAL INSTITUTIONS-MERCHANDISE SERVICES',
620
+ '6022' => 'FINANCIAL INSTITUTION (RCL INTERNAL)',
621
+ '6023' => 'STATE BANKS (RCL INTERNAL)',
622
+ '6025' => 'NATIONAL BANKS (RCL INTERNAL)',
623
+ '6026' => 'NATIONAL BANKS NON FEDERAL (RCL INTERNAL)',
624
+ '6028' => 'UNICORPORATED PRIVATE BANKS (RCL INTERNAL)',
625
+ '6051' => 'NON-FINANCIAL INST-FORN CURR-MO-TC',
626
+ '6211' => 'SECURITIES-BROKERS-DEALERS',
627
+ '6300' => 'INSURANCE SALES UNDERWRITING AND PREMIUMS',
628
+ '6381' => 'INSURANCE PREMIUMS',
629
+ '6399' => 'INSURANCE-CARRIERS NOT ELSEWHERE CLASSIFIED',
630
+ '7012' => 'TIMESHARES',
631
+ '7261' => 'FUNERAL SERVICE AND CREMATORIES',
632
+ '7273' => 'DATING AND ESCORT SERVICES',
633
+ '7276' => 'TAX PREPARATION SERVICE',
634
+ '7277' => 'COUNSELING SERVICE-DEBT MARRIAGE PERSONAL',
635
+ '7297' => 'MASSAGE PARLORS',
636
+ '7298' => 'HEALTH AND BEAUTY SPAS',
637
+ '7321' => 'CONSUMER CREDIT REPORTING AGENCIES',
638
+ '7511' => 'TRUCK STOP TRANSACTIONS',
639
+ '7512' => 'AUTOMOBILE RENTAL AND LEASING',
640
+ '7531' => 'AUTOMOTIVE BODY REPAIR SHOPS',
641
+ '7534' => 'TIRE RETREADING AND REPAIR SHOPS',
642
+ '7535' => 'AUTOMOTIVE PAINT SHOPS',
643
+ '7538' => 'AUTOMOTIVE SERVICE SHOPS',
644
+ '7932' => 'BILLIARD AND POOL ESTABLISHMENTS',
645
+ '7994' => 'VIDEO GAME ARCADES-ESTABLISHMENTS',
646
+ '7995' => 'BETTING-INCL LOTTERY GAMING CHIPS TRACK WAGERS',
647
+ '7996' => 'AMUSEMENT PARKS CIRCUSES CARNIVALS FORTUNE TLR',
648
+ '8011' => 'DOCTORS (NOT ELSEWHERE CLASSIFIED)',
649
+ '8021' => 'DENTISTS ORTHODONTISTS',
650
+ '8031' => 'OSTEOPATHIC PHYSICIANS',
651
+ '8041' => 'CHIROPRACTORS',
652
+ '8042' => 'OPTOMETRISTS OPHTHALMOLOGISTS',
653
+ '8049' => 'CHIROPODISTS PODIATRISTS',
654
+ '8050' => 'NURSING AND PERSONAL CARE FACILITIES',
655
+ '8111' => 'LEGAL SERVICES ATTORNEYS',
656
+ '8351' => 'CHILD CARE SERVICES',
657
+ '8651' => 'POLITICAL ORGANIZATIONS',
658
+ '8661' => 'RELIGIOUS ORGANIZATIONS',
659
+ '8675' => 'AUTOMOBILE ASSOCIATIONS',
660
+ '9211' => 'COURT COSTS INCLUDING ALIMONY AND CHILD SUPPORT',
661
+ '9222' => 'FINES',
662
+ '9223' => 'BAIL AND BOND PAYMENTS',
663
+ '9311' => 'TAX PAYMENTS',
664
+ '9401' => 'FOOD STAMPS',
665
+ '9751' => 'UK SUPERMARKETS ELECTRONIC HOT FILE',
666
+ '9752' => 'UK PETROLS STATIONS ELECTRONIC HOT FILE',
667
+ '9999' => 'MCC Invalid'
668
+ }.freeze
669
+ end
670
+ end
data/lib/ofx-parser.rb ADDED
@@ -0,0 +1,191 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+ require 'time'
4
+ require 'date'
5
+
6
+ %w[ofx mcc].each do |fn|
7
+ require File.dirname(__FILE__) + "/#{fn}"
8
+ end
9
+
10
+ module OfxParser
11
+ class OfxParser
12
+ # Creates and returns an Ofx instance when given a well-formed OFX document,
13
+ # complete with the mandatory key:pair header.
14
+ def self.parse(ofx)
15
+ ofx = ofx.respond_to?(:read) ? ofx.read.to_s : ofx.to_s
16
+
17
+ return Ofx.new if ofx == ''
18
+
19
+ header, body = pre_process(ofx)
20
+
21
+ ofx_out = parse_body(body)
22
+ ofx_out.header = header
23
+ ofx_out
24
+ end
25
+
26
+ # Designed to make the main OFX body parsable. This means adding closing tags
27
+ # to the SGML to make it parsable by hpricot.
28
+ #
29
+ # Returns an array of 2 elements:
30
+ # * header as a hash,
31
+ # * body as an evily pre-processed string ready for parsing by hpricot.
32
+ def self.pre_process(ofx)
33
+ header, body = ofx.split(/\n{2,}|:?<OFX>/, 2)
34
+
35
+ header = begin
36
+ Hash[*header.gsub(/^\r?\n+/, '').split(/\r\n/).collect do |e|
37
+ e.split(/:/, 2)
38
+ end.flatten]
39
+ rescue
40
+ nil
41
+ end
42
+
43
+ body.gsub!(/>\s+</m, '><')
44
+ body.gsub!(/\s+</m, '<')
45
+ body.gsub!(/>\s+/m, '>')
46
+ body.gsub!(/<([^>]+?)>([^<]+)/m, '<\1>\2</\1>')
47
+
48
+ [header, body]
49
+ end
50
+
51
+ # Takes an OFX datetime string of the format:
52
+ # * YYYYMMDDHHMMSS.XXX[gmt offset:tz name]
53
+ # * YYYYMMDD
54
+ # * YYYYMMDDHHMMSS
55
+ # * YYYYMMDDHHMMSS.XXX
56
+ #
57
+ # Returns a DateTime object. Milliseconds (XXX) are ignored.
58
+ def self.parse_datetime(date)
59
+ DateTime.parse(date)
60
+ rescue
61
+ nil
62
+ end
63
+
64
+ private
65
+
66
+ def self.parse_body(body)
67
+ doc = Hpricot.XML(body)
68
+
69
+ ofx = Ofx.new
70
+
71
+ ofx.sign_on = build_signon((doc / 'SIGNONMSGSRSV1/SONRS'))
72
+ ofx.signup_account_info = build_info((doc / 'SIGNUPMSGSRSV1/ACCTINFOTRNRS'))
73
+
74
+ # Bank Accounts
75
+ bank_fragment = (doc / 'BANKMSGSRSV1/STMTTRNRS')
76
+ ofx.bank_accounts = bank_fragment.collect do |fragment|
77
+ build_bank(fragment)
78
+ end
79
+
80
+ # Credit Cards
81
+ credit_card_fragment = (doc / 'CREDITCARDMSGSRSV1/CCSTMTTRNRS')
82
+ ofx.credit_accounts = credit_card_fragment.collect do |fragment|
83
+ build_credit(fragment)
84
+ end
85
+
86
+ # Investments (?)
87
+ # build_investment((doc/"SIGNONMSGSRQV1"))
88
+
89
+ ofx
90
+ end
91
+
92
+ def self.build_signon(doc)
93
+ sign_on = SignOn.new
94
+ sign_on.status = build_status((doc / 'STATUS'))
95
+ sign_on.date = parse_datetime((doc / 'DTSERVER').inner_text)
96
+ sign_on.language = (doc / 'LANGUAGE').inner_text
97
+
98
+ sign_on.institute = Institute.new
99
+ sign_on.institute.name = ((doc / 'FI') / 'ORG').inner_text
100
+ sign_on.institute.id = ((doc / 'FI') / 'FID').inner_text
101
+ sign_on
102
+ end
103
+
104
+ def self.build_info(doc)
105
+ account_infos = []
106
+
107
+ (doc / 'ACCTINFO').each do |info_doc|
108
+ acc_info = AccountInfo.new
109
+ acc_info.desc = (info_doc / 'DESC').inner_text
110
+ acc_info.number = (info_doc / 'ACCTID').first.inner_text
111
+ acc_info.bank_id = (info_doc / 'BANKID').first.inner_text unless (info_doc / 'BANKID').empty?
112
+ acc_info.type = (info_doc / 'ACCTTYPE').first.inner_text unless (info_doc / 'ACCTTYPE').empty?
113
+ account_infos << acc_info
114
+ end
115
+
116
+ account_infos
117
+ end
118
+
119
+ def self.build_bank(doc)
120
+ acct = BankAccount.new
121
+
122
+ acct.transaction_uid = (doc / 'TRNUID').inner_text.strip
123
+ acct.number = (doc / 'STMTRS/BANKACCTFROM/ACCTID').inner_text
124
+ acct.routing_number = (doc / 'STMTRS/BANKACCTFROM/BANKID').inner_text
125
+ acct.branch_number = (doc / 'STMTRS/BANKACCTFROM/BRANCHID').inner_text
126
+ acct.type = (doc / 'STMTRS/BANKACCTFROM/ACCTTYPE').inner_text.strip
127
+ acct.balance = (doc / 'STMTRS/LEDGERBAL/BALAMT').inner_text
128
+ acct.balance_date = parse_datetime((doc / 'STMTRS/LEDGERBAL/DTASOF').inner_text)
129
+
130
+ statement = Statement.new
131
+ statement.currency = (doc / 'STMTRS/CURDEF').inner_text
132
+ statement.start_date = parse_datetime((doc / 'STMTRS/BANKTRANLIST/DTSTART').inner_text)
133
+ statement.end_date = parse_datetime((doc / 'STMTRS/BANKTRANLIST/DTEND').inner_text)
134
+ acct.statement = statement
135
+
136
+ statement.transactions = (doc / 'STMTRS/BANKTRANLIST/STMTTRN').collect do |t|
137
+ build_transaction(t)
138
+ end
139
+
140
+ acct
141
+ end
142
+
143
+ def self.build_credit(doc)
144
+ acct = CreditAccount.new
145
+
146
+ acct.number = (doc / 'CCSTMTRS/CCACCTFROM/ACCTID').inner_text
147
+ acct.transaction_uid = (doc / 'TRNUID').inner_text.strip
148
+ acct.balance = (doc / 'CCSTMTRS/LEDGERBAL/BALAMT').inner_text
149
+ acct.balance_date = parse_datetime((doc / 'CCSTMTRS/LEDGERBAL/DTASOF').inner_text)
150
+ acct.remaining_credit = (doc / 'CCSTMTRS/AVAILBAL/BALAMT').inner_text
151
+ acct.remaining_credit_date = parse_datetime((doc / 'CCSTMTRS/AVAILBAL/DTASOF').inner_text)
152
+
153
+ statement = Statement.new
154
+ statement.currency = (doc / 'CCSTMTRS/CURDEF').inner_text
155
+ statement.start_date = parse_datetime((doc / 'CCSTMTRS/BANKTRANLIST/DTSTART').inner_text)
156
+ statement.end_date = parse_datetime((doc / 'CCSTMTRS/BANKTRANLIST/DTEND').inner_text)
157
+ acct.statement = statement
158
+
159
+ statement.transactions = (doc / 'CCSTMTRS/BANKTRANLIST/STMTTRN').collect do |t|
160
+ build_transaction(t)
161
+ end
162
+
163
+ acct
164
+ end
165
+
166
+ # for credit and bank transactions.
167
+ def self.build_transaction(t)
168
+ transaction = Transaction.new
169
+ transaction.type = (t / 'TRNTYPE').inner_text
170
+ transaction.date = parse_datetime((t / 'DTPOSTED').inner_text)
171
+ transaction.date_initiated = parse_datetime((t / 'DTUSER').inner_text) unless (t / 'DTUSER').inner_text.empty?
172
+ transaction.amount = (t / 'TRNAMT').inner_text
173
+ transaction.fit_id = (t / 'FITID').inner_text
174
+ transaction.payee = (t / 'PAYEE').inner_text + (t / 'NAME').inner_text
175
+ transaction.memo = (t / 'MEMO').inner_text
176
+ transaction.sic = (t / 'SIC').inner_text
177
+ transaction.check_number = (t / 'CHECKNUM').inner_text unless (t / 'CHECKNUM').inner_text.empty?
178
+ transaction
179
+ end
180
+
181
+ def self.build_investment(_doc); end
182
+
183
+ def self.build_status(doc)
184
+ status = Status.new
185
+ status.code = (doc / 'CODE').inner_text
186
+ status.severity = (doc / 'SEVERITY').inner_text
187
+ status.message = (doc / 'MESSAGE').inner_text
188
+ status
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,3 @@
1
+ module OfxParser
2
+ VERSION = '1.2.0'.freeze
3
+ end
data/lib/ofx.rb ADDED
@@ -0,0 +1,204 @@
1
+ module OfxParser
2
+ module MonetaryClassSupport
3
+ attr_accessor :monies
4
+
5
+ def monetary_vars(*methods) #:nodoc:
6
+ self.monies ||= []
7
+ self.monies += methods
8
+ end
9
+ end
10
+
11
+ module MonetarySupport
12
+ # Returns pennies for a given string amount, i.e:
13
+ # '-.45' => -45
14
+ # '-123.45' => -12345
15
+ # '123' => 12300
16
+ def pennies_for(amount)
17
+ return nil if amount == ''
18
+ int, fraction = amount.scan(/\d+/)
19
+ if amount =~ /^-?\./
20
+ fraction = int
21
+ int = 0
22
+ end
23
+ i = fraction.to_s.strip =~ /[1-9]/ ? "#{int}#{fraction[0, 2]}".to_i : int.to_i * 100
24
+ amount =~ /^\s*-\s*.?\d+/ ? -i : i
25
+ end
26
+
27
+ def original_method(meth) #:nodoc:
28
+ meth.to_s.sub('_in_pennies', '').to_sym
29
+ rescue
30
+ nil
31
+ end
32
+
33
+ def monetary_method_call?(meth) #:nodoc:
34
+ orig = original_method(meth)
35
+ self.class.monies.include?(orig) && meth.to_s == "#{orig}_in_pennies"
36
+ end
37
+
38
+ def method_missing(meth, *args) #:nodoc:
39
+ if monetary_method_call?(meth)
40
+ pennies_for(send(original_method(meth)))
41
+ else
42
+ super
43
+ end
44
+ end
45
+
46
+ def respond_to?(meth) #:nodoc:
47
+ monetary_method_call?(meth) ? true : super
48
+ end
49
+ end
50
+
51
+ # This class is returned when a parse is successful.
52
+ # == General Notes
53
+ # * currency symbols are an iso4217 3-letter code
54
+ # * language is defined by iso639 3-letter code
55
+ class Ofx
56
+ attr_accessor :header, :sign_on, :signup_account_info,
57
+ :bank_accounts, :credit_accounts,
58
+ :investment_accounts
59
+
60
+ def accounts
61
+ [bank_accounts, credit_accounts, investment_accounts].flatten!.compact!
62
+ end
63
+
64
+ def bank_account #:nodoc:
65
+ warn 'DEPRECATION WARNING: bank_account() is deprecated and may be removed from future releases, use bank_accounts() instead.'
66
+ bank_accounts.first
67
+ end
68
+
69
+ def credit_card #:nodoc:
70
+ warn 'DEPRECATION WARNING: credit_card() is deprecated and may be removed from future releases, use credit_accounts() instead.'
71
+ credit_accounts.first
72
+ end
73
+ end
74
+
75
+ class SignOn
76
+ attr_accessor :status, :date, :language, :institute
77
+ end
78
+
79
+ class AccountInfo
80
+ attr_accessor :desc, :number, :bank_id, :type
81
+ end
82
+
83
+ class Account
84
+ attr_accessor :number, :statement, :transaction_uid, :routing_number
85
+ end
86
+
87
+ class BankAccount < Account
88
+ TYPE = %i[CHECKING SAVINGS MONEYMRKT CREDITLINE].freeze
89
+ attr_accessor :type, :balance, :balance_date, :branch_number
90
+
91
+ include MonetarySupport
92
+ extend MonetaryClassSupport
93
+ monetary_vars :balance
94
+
95
+ undef type
96
+ def type
97
+ @type.to_s.upcase.to_sym
98
+ end
99
+ end
100
+
101
+ class CreditAccount < Account
102
+ attr_accessor :remaining_credit, :remaining_credit_date, :balance, :balance_date
103
+
104
+ include MonetarySupport
105
+ extend MonetaryClassSupport
106
+ monetary_vars :remaining_credit, :balance
107
+ end
108
+
109
+ class InvestmentAccount < Account
110
+ attr_accessor :broker_id, :positions, :margin_balance, :short_balance, :cash_balance
111
+
112
+ include MonetarySupport
113
+ extend MonetaryClassSupport
114
+ monetary_vars :margin_balance, :short_balance, :cash_balance
115
+ end
116
+
117
+ class Statement
118
+ attr_accessor :currency, :transactions, :start_date, :end_date
119
+ end
120
+
121
+ class Transaction
122
+ attr_accessor :type, :date, :date_initiated, :amount, :fit_id, :check_number, :sic, :memo, :payee
123
+
124
+ include MonetarySupport
125
+ extend MonetaryClassSupport
126
+ monetary_vars :amount
127
+
128
+ TYPE = {
129
+ CREDIT: 'Generic credit',
130
+ DEBIT: 'Generic debit',
131
+ INT: 'Interest earned or paid ',
132
+ DIV: 'Dividend',
133
+ FEE: 'FI fee',
134
+ SRVCHG: 'Service charge',
135
+ DEP: 'Deposit',
136
+ ATM: 'ATM debit or credit',
137
+ POS: 'Point of sale debit or credit ',
138
+ XFER: 'Transfer',
139
+ CHECK: 'Check',
140
+ PAYMENT: 'Electronic payment',
141
+ CASH: 'Cash withdrawal',
142
+ DIRECTDEP: 'Direct deposit',
143
+ DIRECTDEBIT: 'Merchant initiated debit',
144
+ REPEATPMT: 'Repeating payment/standing order',
145
+ OTHER: 'Other'
146
+ }.freeze
147
+
148
+ def type_desc
149
+ TYPE[type]
150
+ end
151
+
152
+ undef type
153
+ def type
154
+ @type.to_s.strip.upcase.to_sym
155
+ end
156
+
157
+ undef sic
158
+ def sic
159
+ @sic == '' ? nil : @sic
160
+ end
161
+
162
+ def sic_desc
163
+ Mcc::CODES[sic]
164
+ end
165
+
166
+ def eql?(other)
167
+ fit_id == other.fit_id
168
+ end
169
+
170
+ def hash
171
+ fit_id.hash
172
+ end
173
+ end
174
+
175
+ class Position
176
+ end
177
+
178
+ # Status of a sign on
179
+ class Status
180
+ attr_accessor :code, :severity, :message
181
+
182
+ CODES = {
183
+ '0' => 'Success',
184
+ '2000' => 'General error',
185
+ '15000' => 'Must change USERPASS',
186
+ '15500' => 'Signon invalid',
187
+ '15501' => 'Customer account already in use',
188
+ '15502' => 'USERPASS Lockout'
189
+ }.freeze
190
+
191
+ def code_desc
192
+ CODES[code]
193
+ end
194
+
195
+ undef code
196
+ def code
197
+ @code.to_s.strip
198
+ end
199
+ end
200
+
201
+ class Institute
202
+ attr_accessor :name, :id
203
+ end
204
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ekylibre-ofx-parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew A. Smith
8
+ - Louis Coquio
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-05-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: hpricot
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0.6'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0.6'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rdoc
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '3.10'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '3.10'
42
+ - !ruby/object:Gem::Dependency
43
+ name: hoe
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.3'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.3'
56
+ description: |-
57
+ == DESCRIPTION:
58
+
59
+ ofx-parser is a ruby library to parse a realistic subset of the lengthy OFX 1.x specification.
60
+
61
+ == FEATURES/PROBLEMS:
62
+
63
+ * Reads OFX responses - i.e. those downloaded from financial institutions and
64
+ puts it into a usable object graph.
65
+ * Supports the 3 main message sets: banking, credit card and investment
66
+ accounts, as well as the required 'sign on' set.
67
+ * Knows about SIC codes - if your institution provides them.
68
+ See http://www.eeoc.gov/stats/jobpat/siccodes.html
69
+ * Monetary amounts can be retrieved either as a raw string, or in pennies.
70
+ * Supports OFX timestamps.
71
+ email: andy@tinnedfruit.org
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - README.rdoc
77
+ - lib/mcc.rb
78
+ - lib/ofx-parser.rb
79
+ - lib/ofx-parser/version.rb
80
+ - lib/ofx.rb
81
+ homepage: https://github.com/ekylibre/ofx-parser
82
+ licenses: []
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.4.5.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: ofx-parser is a ruby library for parsing OFX 1.x data.
104
+ test_files: []