ekylibre-ofx-parser 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []