fech 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +49 -0
  5. data/LICENSE +13 -0
  6. data/README.rdoc +178 -0
  7. data/Rakefile +3 -0
  8. data/autotest/discover.rb +1 -0
  9. data/fech.gemspec +32 -0
  10. data/lib/fech.rb +13 -0
  11. data/lib/fech/default_translations.rb +135 -0
  12. data/lib/fech/fech_utils.rb +41 -0
  13. data/lib/fech/filing.rb +248 -0
  14. data/lib/fech/map_generator.rb +187 -0
  15. data/lib/fech/mapped.rb +38 -0
  16. data/lib/fech/mappings.rb +66 -0
  17. data/lib/fech/translator.rb +138 -0
  18. data/lib/fech/version.rb +3 -0
  19. data/sources/F3P.csv +1 -0
  20. data/sources/F3P31.csv +1 -0
  21. data/sources/F3PS.csv +1 -0
  22. data/sources/F3S.csv +1 -0
  23. data/sources/HDR.csv +1 -0
  24. data/sources/SchA.csv +1 -0
  25. data/sources/SchB.csv +1 -0
  26. data/sources/SchC.csv +1 -0
  27. data/sources/SchC1.csv +1 -0
  28. data/sources/SchC2.csv +1 -0
  29. data/sources/SchD.csv +1 -0
  30. data/sources/SchE.csv +1 -0
  31. data/sources/SchF.csv +1 -0
  32. data/sources/TEXT.csv +1 -0
  33. data/sources/headers/3.csv +1 -0
  34. data/sources/headers/5.0.csv +1 -0
  35. data/sources/headers/5.1.csv +1 -0
  36. data/sources/headers/5.2.csv +1 -0
  37. data/sources/headers/5.3.csv +1 -0
  38. data/sources/headers/6.1.csv +1 -0
  39. data/sources/headers/6.2.csv +1 -0
  40. data/sources/headers/6.3.csv +1 -0
  41. data/sources/headers/6.4.csv +1 -0
  42. data/sources/headers/7.0.csv +1 -0
  43. data/sources/headers/ignore.csv +5 -0
  44. data/spec/data/723604.fec +4 -0
  45. data/spec/data/97405.fec +10 -0
  46. data/spec/default_translations_spec.rb +104 -0
  47. data/spec/fech_utils_spec.rb +29 -0
  48. data/spec/filing_spec.rb +251 -0
  49. data/spec/map_generator_spec.rb +49 -0
  50. data/spec/mapped_spec.rb +44 -0
  51. data/spec/mappings_spec.rb +46 -0
  52. data/spec/sources/F3P.csv +1 -0
  53. data/spec/sources/SchA.csv +1 -0
  54. data/spec/sources/SchB.csv +1 -0
  55. data/spec/sources/SchC.csv +1 -0
  56. data/spec/sources/headers/3.csv +1 -0
  57. data/spec/sources/headers/5.0.csv +1 -0
  58. data/spec/sources/headers/5.1.csv +1 -0
  59. data/spec/sources/headers/5.2.csv +1 -0
  60. data/spec/sources/headers/5.3.csv +1 -0
  61. data/spec/sources/headers/6.1.csv +1 -0
  62. data/spec/sources/headers/6.2.csv +1 -0
  63. data/spec/sources/headers/6.3.csv +1 -0
  64. data/spec/sources/headers/6.4.csv +1 -0
  65. data/spec/sources/headers/7.0.csv +1 -0
  66. data/spec/sources/headers/ignore.csv +5 -0
  67. data/spec/sources/sa.csv +1 -0
  68. data/spec/spec_helper.rb +9 -0
  69. data/spec/translator_spec.rb +195 -0
  70. data/tasks/fech.rake +41 -0
  71. metadata +280 -0
@@ -0,0 +1,38 @@
1
+ module Fech
2
+
3
+ # Fech::Mapped is a thin wrapper around Hash which allows values to be
4
+ # referenced either by key or by an alias specified in the associated
5
+ # Filing's Translations.
6
+ class Mapped < Hash
7
+
8
+ attr_accessor :filing, :row_type
9
+ alias :old_bracket :[]
10
+
11
+ def initialize(filing, row_type)
12
+ @filing = filing
13
+ @row_type = row_type
14
+ end
15
+
16
+ # Just calls Hash's [] method, unless the specified key doesn't
17
+ # exist, in which case it checks for any aliases on the filing's
18
+ # translator.
19
+ def [](key, &block)
20
+ if has_key?(key)
21
+ old_bracket(key, &block)
22
+ else
23
+ # Look up aliases in reverse, to find the most recent one
24
+ # Does not allow (obvious) recursion
25
+ aliias = filing.translator.aliases.reverse.detect do |a|
26
+ a[:alias] == key && a[:row].match(row_type) && a[:alias] != a[:for]
27
+ end
28
+ # Pass the key this alias references back to this function
29
+ aliias ? old_bracket(aliias[:for], &block) : nil
30
+ end
31
+ end
32
+
33
+ def method_missing(method, *args, &block)
34
+ self[method]
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,66 @@
1
+ module Fech
2
+
3
+ # Fech::Mappings loads a set of master mappings between labels and where
4
+ # their values can be found in Electronic Filings for various row types
5
+ # and versions.
6
+ # To access a map, call Mappings.for_row with the row_type,
7
+ # and optionally the version:
8
+ # Mappings.for_row("SA", :version => 6.1)
9
+ class Mappings
10
+
11
+ attr_accessor :map, :version
12
+
13
+ def initialize(ver = Fech::DEFAULT_VERSION)
14
+ @version = ver
15
+ @map = load_map
16
+ @cache = {}
17
+ end
18
+
19
+ # Returns a hash of mappings for row with given row_type
20
+ #
21
+ # @param [String,Symbol] row_type the row type whose map to find
22
+ def for_row(row_type)
23
+ @cache[row_type] ||= self.class.for_row(row_type, :version => @version)
24
+ end
25
+
26
+ # Returns the basic, default mappings hash by reading in a mappings
27
+ # file and saving the variable to the class's context.
28
+ def load_map
29
+ self.class.load_map
30
+ end
31
+
32
+ def self.load_map
33
+ Fech::RENDERED_MAPS
34
+ end
35
+
36
+ # Given a row type, first find the entire block of maps for that row type.
37
+ # Then, use the filing's version to choose which specific map set to use,
38
+ # and return it.
39
+ #
40
+ # @param [Symbol,String,Regex] row_type the row whose map to find
41
+ def self.for_row(row_type, opts={})
42
+ opts[:version] ||= Fech::DEFAULT_VERSION
43
+ map = key_by_regex(load_map, row_type)
44
+ key_by_regex(map, opts[:version])
45
+ end
46
+
47
+ # Given a Hash whose keys are string representations of regular expressions,
48
+ # return the value whose key best matches the given label.
49
+ #
50
+ # @param [Hash] hash a Hash with string regular expressions for keys
51
+ # @param [String,Symbol,Regexp] label return the key that best matches this
52
+ def self.key_by_regex(hash, label)
53
+ label = label.source if label.is_a?(Regexp)
54
+
55
+ # Try matching longer keys first, to ensure more accurate keys are
56
+ # prioritized over less accurate ones.
57
+ hash.keys.sort { |x, y| x.length <=> y.length }.reverse.each do |key|
58
+ return hash[key] if Regexp.new(key, Regexp::IGNORECASE).match(label.to_s)
59
+ end
60
+
61
+ raise "Attempted to access mapping that has not been generated (#{label}). " +
62
+ "Supported keys match the format: #{hash.keys.join(', ')}"
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,138 @@
1
+ require 'people'
2
+
3
+ module Fech
4
+
5
+ # Fech::Translator stores a collection of Procs which are associated with
6
+ # one or many field types, row types and filing versions. When a row that
7
+ # matches all of these is mapped in Filing, the Proc is run on that value.
8
+ #
9
+ # :action => :convert alters a single value in place.
10
+ # :combine creates a new row out of others.
11
+ #
12
+ # It also stores a set of aliases, allowing fields on the returned Hash of
13
+ # mapped data to be accessed by other names.
14
+ class Translator
15
+
16
+ attr_accessor :translations, :aliases, :cache
17
+
18
+ NAME_PARSER = People::NameParser.new
19
+
20
+ def initialize(opts = {})
21
+ @cache = {}
22
+ @aliases = []
23
+ @translations = []
24
+ # op-in default translation packs
25
+ add_default_translations(opts[:include] || [])
26
+ end
27
+
28
+ # Returns list of all translations that should be applied to values of
29
+ # specified row and field.
30
+ #
31
+ # @option opts [String] :field the current field's value
32
+ # @option opts [String] :version the current filing's version
33
+ # @option opts [String] :row the row type
34
+ # @option opts [Symbol] :action match only :combine or :convert translations
35
+ def get_translations(opts)
36
+ key = [:field, :row, :version, :action].collect { |key| opts[key] }.join(":")
37
+ @cache[key] ||= \
38
+ procs = translations.collect do |t|
39
+ t if self.class.applicable_translation?(t, opts)
40
+ end.compact
41
+ end
42
+
43
+ # Given a translation and any or all of field, version, row, action:
44
+ # Returns true if all the given options are compatible with those
45
+ # specified in the translation.
46
+ #
47
+ # @param [Hash] translation the translation being tested for relevance
48
+ # @option opts [String] :field the current field's value
49
+ # @option opts [String] :version the current filing's version
50
+ # @option opts [String] :row the row type
51
+ # @option opts [Symbol] :action match only :combine or :convert translations
52
+ def self.applicable_translation?(translation, opts)
53
+ opts.keys.all? { |k| translation[k].match(opts[k].to_s) }
54
+ end
55
+
56
+ # Adds a tranlation for preprocessing a single field's value
57
+ #
58
+ # t.convert(:row => /^sa/, :field => :date_coverage_from) { |v| Date.parse(v) }
59
+ #
60
+ # @option opts [String] :field the current field's value
61
+ # @option opts [String] :version the current filing's version
62
+ # @option opts [String] :row the row type
63
+ def convert(args={}, &block)
64
+ add_translation(args.merge(:action => :convert), &block)
65
+ end
66
+
67
+ # Adds a translation that uses other fields to create a new one
68
+ #
69
+ # t.combine(:row => "sa", :field => :net_individual_contributions) do |row|
70
+ # row.individual_contributions - row.individual_refunds
71
+ # end
72
+ #
73
+ # @option opts [String] :field the name of the field to create
74
+ # @option opts [String] :version the current filing's version
75
+ # @option opts [String] :row the row type
76
+ def combine(args={}, &block)
77
+ add_translation(args.merge(:action => :combine), &block)
78
+ end
79
+
80
+ # Allows @old_name on @row to be accessible on the returned hash as @new_name
81
+ #
82
+ # t.alias(:new, :old, "sa")
83
+ #
84
+ # @param [Symbol] new_name the given field will be accessible using this token
85
+ # @param [Symbol] old_name the existing field whose value to alias
86
+ # @param [Symbol,Regex] row the types of rows this alias should be applied to
87
+ def alias(new_name, old_name, row=/.*/)
88
+ aliases << {
89
+ :row => Fech.regexify(row),
90
+ :alias => new_name,
91
+ :for => old_name
92
+ }
93
+ end
94
+
95
+ private
96
+
97
+ # Adds a translation to the global translation list.
98
+ # Åt runtime, any field whose field, row and version match a translation
99
+ # will have its value preprocessed through &block.
100
+ #
101
+ # @option data [String] :field the current field's value
102
+ # @option data [String] :version the current filing's version
103
+ # @option data [String] :row the row type
104
+ def add_translation(data, &block)
105
+ raise "Block required" unless block_given?
106
+
107
+ # The cache may be now be out of date after adding this translation
108
+ cache = {}
109
+
110
+ data ||= {}
111
+ data[:row] ||= /.*/
112
+ data[:field] ||= /.*/
113
+ data[:version] ||= /.*/
114
+
115
+ # Convert any string or symbols to regular expressions for the hash
116
+ data.each do |k,v|
117
+ data[k] = Fech.regexify(v)
118
+ end
119
+
120
+ data = data.merge(:proc => block)
121
+ translations << data
122
+ data
123
+ end
124
+
125
+ # For each default translation set given, execute the corresponding
126
+ # code in Fech::DefaultTranslations.
127
+ def add_default_translations(translations_list)
128
+ translations_list = [translations_list] unless translations_list.is_a?(Array)
129
+ return if translations_list.empty?
130
+
131
+ default = Fech::DefaultTranslations.new(self)
132
+ translations_list.each do |package|
133
+ default.send(package)
134
+ end
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,3 @@
1
+ module Fech
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1 @@
1
+ canonical,^7.0,,^6.4|6.3|6.2|6.1,,^5.3|5.2,,^5.1|5.0|3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0|3,
@@ -0,0 +1 @@
1
+ canonical,^7.0,,^6.4|6.3|6.2|6.1,,^5.3|5.2|5.1|5.0|3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2|6.1,,^5.3|5.2|5.1|5.0|3,
@@ -0,0 +1 @@
1
+ canonical,^[6-7],,^[3-5],
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4,,^6.3|6.2,,^6.1,,^5.3,,^5.2,,^5.1,,^5.0,,^3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4,,^6.3|6.2,,^6.1,,^5.3,,^5.2|5.1,,^5.0,,^3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2,,^6.1,,^5.3,,^5.2|5.1,,^5.0|3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0,,^3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0,,^3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0|3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0,,^3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4,,^6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0,,^3,
@@ -0,0 +1 @@
1
+ canonical,^7.0|6.4|6.3|6.2|6.1,,^5.3,,^5.2|5.1|5.0,,^3,
@@ -0,0 +1 @@
1
+ Header,Record Type,EF Type,FEC Ver,Soft Name,Soft Ver,Name Delim,Rpt ID,Rpt Number,HDRcomment ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER FEC CMTE ID ,,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,,DATE (Submitted),,CHG OF COMMITTEE NAME,CHG OF ADDRESS,,5. COMMITTEE TYPE,,5. FEC CANDIDATE ID NUMBER,5. CANDIDATE NAME,5. CAN/OFFICE ,5. CAN/STATE,5. CAN/DIST,5. PARTY CODE,5. PARTY TYPE,,6. FEC COMMITTEE ID NUMBER,6. COMMITTEE NAME (Affiliated),6. STREET 1,6. STREET 2,6. CITY,6. STATE,6. ZIP,6. RELATIONSHIP (w/ Above Cmte),6. ORGANIZATION TYPE,,7. IND/NAME (Custodian Name),7. STREET 1,7. STREET 2,7. CITY,7. STATE,7. ZIP,7. TITLE,7. TELEPHONE,,8. IND/NAME (Treasurer),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,,8. IND/NAME (Designated Agent),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,,9. IND/NAME (Bank/Depository),9. STREET 1,9. STREET 2,9. CITY,9. STATE,9. ZIP,,NAME/TREASURER (as signed),DATE (Signed),,COMMITTEE EMAIL,COMMITTEE WEB URL,,COMMITTEE FAX NUMBER,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER FEC CMTE ID ,,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,,DATE (Submitted),,CHG OF COMMITTEE NAME,CHG OF ADDRESS,,5. COMMITTEE TYPE,,5. FEC CANDIDATE ID NUMBER,5. CANDIDATE NAME,5. CAN/OFFICE ,5. CAN/STATE,5. CAN/DIST,5. PARTY CODE,5. PARTY TYPE,,6. FEC COMMITTEE ID NUMBER,6. COMMITTEE NAME (Affiliated),6. STREET 1,6. STREET 2,6. CITY,6. STATE,6. ZIP,6. RELATIONSHIP (w/ Above Cmte),6. ORGANIZATION TYPE,,7. IND/NAME (Custodian Name),7. STREET 1,7. STREET 2,7. CITY,7. STATE,7. ZIP,7. TITLE,7. TELEPHONE,,8. IND/NAME (Treasurer),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,,8. IND/NAME (Designated Agent),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,,9. IND/NAME (Bank/Depository),9. STREET 1,9. STREET 2,9. CITY,9. STATE,9. ZIP,,NAME/TREASURER (as signed),DATE (Signed),,COMMITTEE EMAIL,COMMITTEE WEB URL,,COMMITTEE FAX NUMBER,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER FEC CMTE ID ,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,DATE (Submitted),CHG OF COMMITTEE NAME,CHG OF ADDRESS,5. COMMITTEE TYPE,5. FEC CANDIDATE ID NUMBER,5. CANDIDATE NAME,5. CAN/OFFICE ,5. CAN/STATE,5. CAN/DIST,5. PARTY CODE,5. PARTY TYPE,6. FEC COMMITTEE ID NUMBER,6. COMMITTEE NAME (Affiliated),6. STREET 1,6. STREET 2,6. CITY,6. STATE,6. ZIP,6. RELATIONSHIP (w/ Above Cmte),6. ORGANIZATION TYPE,7. IND/NAME (Custodian Name),7. STREET 1,7. STREET 2,7. CITY,7. STATE,7. ZIP,7. TITLE,7. TELEPHONE,8. IND/NAME (Treasurer),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,8. IND/NAME (Designated Agent),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,9. IND/NAME (Bank/Depository),9. STREET 1,9. STREET 2,9. CITY,9. STATE,9. ZIP,NAME/TREASURER (as signed),DATE (Signed),COMMITTEE EMAIL,COMMITTEE WEB URL,COMMITTEE FAX NUMBER,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER FEC CMTE ID ,,COMMITTEE NAME,STREET 1,STREET 2,CITY,STATE,ZIP,,DATE (Submitted),,CHG OF COMMITTEE NAME,CHG OF ADDRESS,,5. COMMITTEE TYPE,,5. FEC CANDIDATE ID NUMBER,5. CANDIDATE NAME,5. CAN/OFFICE ,5. CAN/STATE,5. CAN/DIST,5. PARTY CODE,5. PARTY TYPE,,6. FEC COMMITTEE ID NUMBER,6. COMMITTEE NAME (Affiliated),6. STREET 1,6. STREET 2,6. CITY,6. STATE,6. ZIP,6. RELATIONSHIP (w/ Above Cmte),6. ORGANIZATION TYPE,,7. IND/NAME (Custodian Name),7. STREET 1,7. STREET 2,7. CITY,7. STATE,7. ZIP,7. TITLE,7. TELEPHONE,,8. IND/NAME (Treasurer),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,,8. IND/NAME (Designated Agent),8. STREET 1,8. STREET 2,8. CITY,8. STATE,8. ZIP,8. TITLE,8. TELEPHONE,,9. IND/NAME (Bank/Depository),9. STREET 1,9. STREET 2,9. CITY,9. STATE,9. ZIP,,NAME/TREASURER (as signed),DATE (Signed),,COMMITTEE EMAIL,COMMITTEE WEB URL,,COMMITTEE FAX NUMBER,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER COMMITTEE ID NUMBER,CHANGE OF COMMITTEE NAME,COMMITTEE NAME,CHANGE OF ADDRESS,STREET 1,STREET 2,CITY,STATE,ZIP,COMMITTEE EMAIL,COMMITTEE WEB URL,COMMITTEE FAX NUMBER,SUBMISSION DATE,SIGNATURE LAST NAME,SIGNATURE FIRST NAME,SIGNATURE MIDDLE NAME,SIGNATURE PREFIX,SIGNATURE SUFFIX,DATE SIGNED,5. COMMITTEE TYPE,5. CANDIDATE ID NUMBER,5. CANDIDATE LAST NAME,5. CANDIDATE FIRST NAME,5. CANDIDATE MIDDLE NAME,5. CANDIDATE PREFIX,5. CANDIDATE SUFFIX,5. CANDIDATE OFFICE ,5. CANDIDATE STATE,5. CANDIDATE DISTRICT,5. PARTY CODE,5. PARTY TYPE,7. CUSTODIAN LAST NAME,7. CUSTODIAN FIRST NAME,7. CUSTODIAN MIDDLE NAME,7. CUSTODIAN PREFIX,7. CUSTODIAN SUFFIX,7. CUSTODIAN STREET 1,7. CUSTODIAN STREET 2,7. CUSTODIAN CITY,7. CUSTODIAN STATE,7. CUSTODIAN ZIP,7. CUSTODIAN TITLE,7. CUSTODIAN TELEPHONE,8. TREASURER LAST NAME,8. TREASURER FIRST NAME,8. TREASURER MIDDLE NAME,8. TREASURER PREFIX,8. TREASURER SUFFIX,8. TREASURER STREET 1,8. TREASURER STREET 2,8. TREASURER CITY,8. TREASURER STATE,8. TREASURER ZIP,8. TREASURER TITLE,8. TREASURER TELEPHONE,6. AFFILIATED CMTTE ID NUM,6. AFFILIATED CMTTE NAME,6. AFFILIATED STREET 1,6. AFFILIATED STREET 2,6. AFFILIATED CITY,6. AFFILIATED STATE,6. AFFILIATED ZIP,"6. RELATIONSHIP (with Filing
2
  Committe named in field #4)",6. ORGANIZATION TYPE,8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. a) BANK NAME,9. a) BANK STREET 1,9. a) BANK STREET 2,9. a) BANK CITY,9. a) BANK STATE,9. a) BANK ZIP,9. b) BANK NAME,9. b) BANK STREET 1,9. b) BANK STREET 2,9. b) BANK CITY,9. b) BANK STATE,9. b) BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER COMMITTEE ID NUMBER,CHANGE OF COMMITTEE NAME,COMMITTEE NAME,CHANGE OF ADDRESS,STREET 1,STREET 2,CITY,STATE,ZIP,COMMITTEE EMAIL,COMMITTEE WEB URL,COMMITTEE FAX NUMBER,SUBMISSION DATE,SIGNATURE LAST NAME,SIGNATURE FIRST NAME,SIGNATURE MIDDLE NAME,SIGNATURE PREFIX,SIGNATURE SUFFIX,DATE SIGNED,5. COMMITTEE TYPE,5. CANDIDATE ID NUMBER,5. CANDIDATE LAST NAME,5. CANDIDATE FIRST NAME,5. CANDIDATE MIDDLE NAME,5. CANDIDATE PREFIX,5. CANDIDATE SUFFIX,5. CANDIDATE OFFICE ,5. CANDIDATE STATE,5. CANDIDATE DISTRICT,5. PARTY CODE,5. PARTY TYPE,5 (e). ORGANIZATION TYPE,5 (f). LEADERSHIP PAC,6. AFFILIATED CMTTE ID NUM,6. AFFILIATED CMTTE NAME,6. AFFILIATED STREET 1,6. AFFILIATED STREET 2,6. AFFILIATED CITY,6. AFFILIATED STATE,6. AFFILIATED ZIP,6. AFFILIATED RELATIONSHIP CODE (with Filing Committe named in field #4),7. CUSTODIAN LAST NAME,7. CUSTODIAN FIRST NAME,7. CUSTODIAN MIDDLE NAME,7. CUSTODIAN PREFIX,7. CUSTODIAN SUFFIX,7. CUSTODIAN STREET 1,7. CUSTODIAN STREET 2,7. CUSTODIAN CITY,7. CUSTODIAN STATE,7. CUSTODIAN ZIP,7. CUSTODIAN TITLE,7. CUSTODIAN TELEPHONE,8. TREASURER LAST NAME,8. TREASURER FIRST NAME,8. TREASURER MIDDLE NAME,8. TREASURER PREFIX,8. TREASURER SUFFIX,8. TREASURER STREET 1,8. TREASURER STREET 2,8. TREASURER CITY,8. TREASURER STATE,6. RELATIONSHIP (with Filing Committe named in field #4),8. TREASURER ZIP,6. ORGANIZATION TYPE,8. TREASURER TITLE,8. TREASURER TELEPHONE,8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. a) BANK NAME,9. a) BANK STREET 1,9. a) BANK STREET 2,9. a) BANK CITY,9. a) BANK STATE,9. a) BANK ZIP,9. b) BANK NAME,9. b) BANK STREET 1,9. b) BANK STREET 2,9. b) BANK CITY,9. b) BANK STATE,9. b) BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER COMMITTEE ID NUMBER,CHANGE OF COMMITTEE NAME,COMMITTEE NAME,CHANGE OF ADDRESS,STREET 1,STREET 2,CITY,STATE,ZIP,CHANGE OF COMMITTEE EMAIL,COMMITTEE EMAIL,CHANGE OF COMMITTEE WEB URL,COMMITTEE FAX NUMBER,COMMITTEE WEB URL,SUBMISSION DATE,SIGNATURE LAST NAME,SIGNATURE FIRST NAME,SIGNATURE MIDDLE NAME,SIGNATURE PREFIX,SIGNATURE SUFFIX,DATE SIGNED,5. COMMITTEE TYPE,5. CANDIDATE ID NUMBER,5. CANDIDATE LAST NAME,5. CANDIDATE FIRST NAME,5. CANDIDATE MIDDLE NAME,5. CANDIDATE PREFIX,5. CANDIDATE SUFFIX,5. CANDIDATE OFFICE ,5. CANDIDATE STATE,5. CANDIDATE DISTRICT,5. PARTY CODE,5. PARTY TYPE,5 (e). ORGANIZATION TYPE,5 (e). LOBBYIST/REGISTRANT PAC ,5 (f). LOBBYIST/REGISTRANT PAC ,5 (f). LEADERSHIP PAC,6. AFFILIATED CMTTE ID NUM,6. AFFILIATED CMTTE NAME,6. AFFILIATED CANDIDATE ID NUM,6. AFFILIATED LAST NAME,6. AFFILIATED FIRST NAME,6. AFFILIATED MIDDLE NAME,6. AFFILIATED PREFIX,6. AFFILIATED SUFFIX,6. AFFILIATED STREET 1,6. AFFILIATED STREET 2,6. AFFILIATED CITY,6. AFFILIATED STATE,6. AFFILIATED ZIP,"6. AFFILIATED RELATIONSHIP CODE
2
  (with Filing Committe named in field #4)",7. CUSTODIAN LAST NAME,7. CUSTODIAN FIRST NAME,7. CUSTODIAN MIDDLE NAME,7. CUSTODIAN PREFIX,7. CUSTODIAN SUFFIX,7. CUSTODIAN STREET 1,7. CUSTODIAN STREET 2,7. CUSTODIAN CITY,7. CUSTODIAN STATE,7. CUSTODIAN ZIP,7. CUSTODIAN TITLE,7. CUSTODIAN TELEPHONE,8. TREASURER LAST NAME,8. TREASURER FIRST NAME,8. TREASURER MIDDLE NAME,8. TREASURER PREFIX,8. TREASURER SUFFIX,8. TREASURER STREET 1,8. TREASURER STREET 2,8. TREASURER CITY,8. TREASURER STATE,8. TREASURER ZIP,8. TREASURER TITLE,8. TREASURER TELEPHONE,8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. a) BANK NAME,9. a) BANK STREET 1,9. a) BANK STREET 2,9. a) BANK CITY,9. a) BANK STATE,9. a) BANK ZIP,9. b) BANK NAME,9. b) BANK STREET 1,9. b) BANK STREET 2,9. b) BANK CITY,9. b) BANK STATE,9. b) BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
3
  (with Filing Committe named in field #4)",8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. BANK NAME,9. BANK STREET 1,9. BANK STREET 2,9. BANK CITY,9. BANK STATE,9. BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER COMMITTEE ID NUMBER,CHANGE OF COMMITTEE NAME,COMMITTEE NAME,CHANGE OF ADDRESS,STREET 1,STREET 2,CITY,STATE,ZIP,CHANGE OF COMMITTEE EMAIL,COMMITTEE EMAIL,CHANGE OF COMMITTEE WEB URL,COMMITTEE FAX NUMBER,COMMITTEE WEB URL,SUBMISSION DATE,SIGNATURE LAST NAME,SIGNATURE FIRST NAME,SIGNATURE MIDDLE NAME,SIGNATURE PREFIX,SIGNATURE SUFFIX,DATE SIGNED,5. COMMITTEE TYPE,5. CANDIDATE ID NUMBER,5. CANDIDATE LAST NAME,5. CANDIDATE FIRST NAME,5. CANDIDATE MIDDLE NAME,5. CANDIDATE PREFIX,5. CANDIDATE SUFFIX,5. CANDIDATE OFFICE ,5. CANDIDATE STATE,5. CANDIDATE DISTRICT,5. PARTY CODE,5. PARTY TYPE,5 (e). ORGANIZATION TYPE,5 (e). LOBBYIST/REGISTRANT PAC ,5 (f). LOBBYIST/REGISTRANT PAC ,5 (f). LEADERSHIP PAC,6. AFFILIATED CMTTE ID NUM,6. AFFILIATED CMTTE NAME,6. AFFILIATED CANDIDATE ID NUM,6. AFFILIATED LAST NAME,6. AFFILIATED FIRST NAME,6. AFFILIATED MIDDLE NAME,6. AFFILIATED PREFIX,6. AFFILIATED SUFFIX,6. AFFILIATED STREET 1,6. AFFILIATED STREET 2,6. AFFILIATED CITY,6. AFFILIATED STATE,6. AFFILIATED ZIP,"6. AFFILIATED RELATIONSHIP CODE
2
  (with Filing Committe named in field #4)",7. CUSTODIAN LAST NAME,7. CUSTODIAN FIRST NAME,7. CUSTODIAN MIDDLE NAME,7. CUSTODIAN PREFIX,7. CUSTODIAN SUFFIX,7. CUSTODIAN STREET 1,7. CUSTODIAN STREET 2,7. CUSTODIAN CITY,7. CUSTODIAN STATE,7. CUSTODIAN ZIP,7. CUSTODIAN TITLE,7. CUSTODIAN TELEPHONE,8. TREASURER LAST NAME,8. TREASURER FIRST NAME,8. TREASURER MIDDLE NAME,8. TREASURER PREFIX,8. TREASURER SUFFIX,8. TREASURER STREET 1,8. TREASURER STREET 2,8. TREASURER CITY,8. TREASURER STATE,8. TREASURER ZIP,8. TREASURER TITLE,8. TREASURER TELEPHONE,8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. a) BANK NAME,9. a) BANK STREET 1,9. a) BANK STREET 2,9. a) BANK CITY,9. a) BANK STATE,9. a) BANK ZIP,9. b) BANK NAME,9. b) BANK STREET 1,9. b) BANK STREET 2,9. b) BANK CITY,9. b) BANK STATE,9. b) BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
3
  (with Filing Committe named in field #4)",8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. BANK NAME,9. BANK STREET 1,9. BANK STREET 2,9. BANK CITY,9. BANK STATE,9. BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1 @@
1
+ F1,FORM TYPE,FILER COMMITTEE ID NUMBER,CHANGE OF COMMITTEE NAME,COMMITTEE NAME,CHANGE OF ADDRESS,STREET 1,STREET 2,CITY,STATE,ZIP,CHANGE OF COMMITTEE EMAIL,COMMITTEE EMAIL,CHANGE OF COMMITTEE WEB URL,COMMITTEE WEB URL,EFFECTIVE DATE,SIGNATURE LAST NAME,SIGNATURE FIRST NAME,SIGNATURE MIDDLE NAME,SIGNATURE PREFIX,SIGNATURE SUFFIX,DATE SIGNED,5. COMMITTEE TYPE,5. CANDIDATE ID NUMBER,5. CANDIDATE LAST NAME,5. CANDIDATE FIRST NAME,5. CANDIDATE MIDDLE NAME,5. CANDIDATE PREFIX,5. CANDIDATE SUFFIX,5. CANDIDATE OFFICE ,5. CANDIDATE STATE,5. CANDIDATE DISTRICT,5. PARTY CODE,5. PARTY TYPE,5 (e). ORGANIZATION TYPE,5 (e). LOBBYIST/REGISTRANT PAC ,5 (f). LOBBYIST/REGISTRANT PAC ,5 (f). LEADERSHIP PAC,6. AFFILIATED CMTTE ID NUM,6. AFFILIATED CMTTE NAME,6. AFFILIATED CANDIDATE ID NUM,6. AFFILIATED LAST NAME,6. AFFILIATED FIRST NAME,6. AFFILIATED MIDDLE NAME,6. AFFILIATED PREFIX,6. AFFILIATED SUFFIX,6. AFFILIATED STREET 1,6. AFFILIATED STREET 2,6. AFFILIATED CITY,6. AFFILIATED STATE,6. AFFILIATED ZIP,"6. AFFILIATED RELATIONSHIP CODE
2
  (with Filing Committee named in field #4)",7. CUSTODIAN LAST NAME,7. CUSTODIAN FIRST NAME,7. CUSTODIAN MIDDLE NAME,7. CUSTODIAN PREFIX,7. CUSTODIAN SUFFIX,7. CUSTODIAN STREET 1,7. CUSTODIAN STREET 2,7. CUSTODIAN CITY,7. CUSTODIAN STATE,7. CUSTODIAN ZIP,7. CUSTODIAN TITLE,7. CUSTODIAN TELEPHONE,8. TREASURER LAST NAME,8. TREASURER FIRST NAME,8. TREASURER MIDDLE NAME,8. TREASURER PREFIX,8. TREASURER SUFFIX,8. TREASURER STREET 1,8. TREASURER STREET 2,8. TREASURER CITY,8. TREASURER STATE,8. TREASURER ZIP,8. TREASURER TITLE,8. TREASURER TELEPHONE,8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. a) BANK NAME,9. a) BANK STREET 1,9. a) BANK STREET 2,9. a) BANK CITY,9. a) BANK STATE,9. a) BANK ZIP,9. b) BANK NAME,9. b) BANK STREET 1,9. b) BANK STREET 2,9. b) BANK CITY,9. b) BANK STATE,9. b) BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
3
  (with Filing Committee named in field #4)",8. AGENT LAST NAME,8. AGENT FIRST NAME,8. AGENT MIDDLE NAME,8. AGENT PREFIX,8. AGENT SUFFIX,8. AGENT STREET 1,8. AGENT STREET 2,8. AGENT CITY,8. AGENT STATE,8. AGENT ZIP,8. AGENT TITLE,8. AGENT TELEPHONE,9. BANK NAME,9. BANK STREET 1,9. BANK STREET 2,9. BANK CITY,9. BANK STATE,9. BANK ZIP,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -0,0 +1,5 @@
1
+ COLUMN A REPORT TOTALS
2
+ COLUMN B YEAR-TO-DATE TOTALS
3
+ COLUMN B YTD TOTALS - LEVIN ACTIVITY
4
+ (New line 30 fields added to end of this layout)
5
+ (New line 18(b) & 18(c) fields at end of layout)
@@ -0,0 +1,4 @@
1
+ HDRFEC7.0CMDI FEC FILER8.1.1
2
+ F3PNC00494393"Pawlenty for President Exploratory Committee""One Financial Plaza""120 South Sixth Street, 9th Floor""Minneapolis"MN55402XQ1P2012201211052011010120110331"Kennedy""Mark"201104150.00160065.91160065.9143419.40116646.510.000.000.00160065.9143419.401000000.00138450.0021547.75159997.750.0068.160.00160065.910.000.000.000.000.000.000.000.000.00160065.9143419.400.000.000.000.000.000.005000.000.000.000.000.0043419.400.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00138450.0021547.75159997.750.0068.160.00160065.910.000.000.000.000.000.000.000.000.00160065.9143419.400.000.000.000.000.000.000.000.000.000.000.0043419.400.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00
3
+ SA17AC00494393SA17.19538IND"ALLEN""JOHN""DR.""1052 CANNON MILL DRIVE""NORTH AUGUSTA"SC298608420P201220110322250.00250.0015"CONTRIBUTION""NORTH AUGUSTA PEDIATRICS""PHYSICIAN"
4
+ SB23C00494393SB23.1115ORG"NEW FRONTIER STRATEGY""315 KENTUCKY AVE""ALEXANDRIA"VA22305P2012201103318889.86"POLITICAL STRATEGY CONSULTING/TRAVEL"
@@ -0,0 +1,10 @@
1
+ HDR,FEC,5.00,"Campaign Central",,,,0,
2
+ "F3PN","C00386987","BUSH-CHENEY 04, INC.","P.O. BOX 10648","","ARLINGTON","VA","22210",,X,,"Q3",P2004,20041102,,"20030701","20030930",32679798.37,50049763.70,82729562.07,12288117.89,70441444.18,0.00,370599.43,0.00,83945952.26,13923575.88,0.00,49187571.07,16000.00,767411.80,0.00,49970982.87,0.00,0.00,0.00,0.00,20063.03,0.00,0.00,20063.03,58717.80,50049763.70,11506837.31,310650.00,0.00,0.00,0.00,0.00,0.00,429480.58,0.00,41150.00,470630.58,0.00,12288117.89,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,82843771.04,23000.00,1581711.80,0.00,84448482.84,671000.00,0.00,0.00,0.00,20410.03,0.00,0.00,20410.03,58717.80,85198610.67,13943985.91,310650.00,0.00,0.00,0.00,0.00,0.00,445380.58,0.00,57150.00,502530.58,0.00,14757166.49,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,"DAVID HERNDON",20031014
3
+ "SA17A","C00386987","IND","Aaker^Steve^Mr.^","16901 Wild Plum Circle","","Morrison","CO","80465","P2004","","Newmont Mining Corporation","Mining Industry Executive",400.00,20030930,400.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.203318,,,""
4
+ "SA17A","C00386987","IND","Aarnio^Terrance J.^Mr.^","19321 S.E. River Drive Court","","Milwaukee","OR","97267","P2004","","Oregon Iron Works","C. E. O.",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.217363,,,""
5
+ "SA17A","C00386987","IND","Abbassi^Jadan^Dr.^","1618 Main Avenue","","Clifton","NJ","07011","P2004","","Self-Employed","Physician",300.00,20030902,300.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.222415,,,""
6
+ "SA17A","C00386987","IND","Abbasi^Mohammad A.^Mr.^","9707 Broadley Drive","","Sugar Land","TX","77478","P2004","","Aupak Eagle, Inc.","C.E.O.",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.145208,,,""
7
+ "SA17A","C00386987","IND","Abbasi^Seyed H^Mr.^","1021 Adelaine Ave.","","South Pasadena","CA","91030","P2004","","Art & Tech","Contractor",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.300657,,,""
8
+ "SA17A","C00386987","IND","Abbey^Scott G.^Mr.^","22 Merimus Brook Road","","Saddle River","CT","07458","P2004","","U.B.S. Services U.S.A., L.L.C.","Information Requested Per Best Efforts",2000.00,20030930,-2000.00,15,Contribution,,,,,,,,,,,,,X,"Redesignation to Compliance",,SA17.221821,,,""
9
+ "SA17A","C00386987","IND","Abbey^Stephen^Mr.^","7270 Cardinal Lane","","Chagrin Falls","OH","44022","P2004","","Revenue Group","Information Requested Per Best Efforts",2000.00,20030930,2000.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.194269,,,""
10
+ "SA17A","C00386987","IND","Abbott^Charles G.^Mr.^","4218 Rockaway Beach Road N.E.","","Bainbridge Island","WA","98110","P2004","","","Retired",500.00,20030902,500.00,15,Contribution,,,,,,,,,,,,,,"",,SA17.220645,,,""
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ def stub_file(filing_id=723604)
4
+ Fech::Filing.any_instance.stubs(:file_path).returns(File.join(File.dirname(__FILE__), 'data', "#{filing_id}.fec"))
5
+ end
6
+
7
+ def unstub_file
8
+ Fech::Filing.any_instance.unstub(:file_path)
9
+ end
10
+
11
+ describe Fech::DefaultTranslations do
12
+
13
+ before do
14
+ stub_file
15
+ end
16
+
17
+ after do
18
+ unstub_file
19
+ end
20
+
21
+ describe ".names" do
22
+
23
+ it "should add name translations to default translation set" do
24
+ filing = Fech::Filing.new(723604, :translate => :names)
25
+ filing.translator.translations.size.should > 0
26
+ end
27
+
28
+ it "should combine name components into aggregate name fields" do
29
+ filing = Fech::Filing.new(723604, :translate => :names)
30
+ Fech::Mapped.any_instance.stubs(:contributor_prefix).returns("Mr.")
31
+ Fech::Mapped.any_instance.stubs(:contributor_first_name).returns("John")
32
+ Fech::Mapped.any_instance.stubs(:contributor_middle_name).returns("Charles")
33
+ Fech::Mapped.any_instance.stubs(:contributor_last_name).returns("Smith")
34
+ Fech::Mapped.any_instance.stubs(:contributor_suffix).returns("III")
35
+ filing.rows_like(/sa/).first.contributor_name.should == "Mr. John Charles Smith III"
36
+ end
37
+
38
+ it "should split an aggregate name into its component parts" do
39
+ stub_file(97405)
40
+ filing = Fech::Filing.new(97405, :translate => :names)
41
+ filing.filing_version.should == "5.00"
42
+ row = filing.rows_like(/sa/).first
43
+ row.contributor_prefix.should == "Mr."
44
+ row.contributor_first_name.should == "Steve"
45
+ row.contributor_middle_name.should == ""
46
+ row.contributor_last_name.should == "Aaker"
47
+ row.contributor_suffix.should == ""
48
+ end
49
+
50
+ end
51
+
52
+ describe ".dates" do
53
+
54
+ before do
55
+ @filing = Fech::Filing.new(723604, :translate => :dates)
56
+ end
57
+
58
+ it "should convert values matching YYYYMMDD to Date objects" do
59
+ @filing.rows_like(/sa/).first.contribution_date.should == Date.parse("20110322")
60
+ end
61
+
62
+ it "should pass all other values through untouched" do
63
+ @filing.rows_like(/sa/).first.contributor_zip.should == "298608420"
64
+ end
65
+
66
+ it "should pass nils through untouched" do
67
+ @filing.rows_like(/sa/).first.conduit_zip.should be_nil
68
+ end
69
+
70
+ end
71
+
72
+ describe ".combine_components_into_name" do
73
+
74
+ before do
75
+ @defaults = Fech::DefaultTranslations.new(Fech::Translator.new)
76
+ end
77
+
78
+ it "should accept :field as either Array or Symbol" do
79
+ data = {:row => /^sc$/, :version => /^[6-7]/, :field => :lender_candidate}
80
+ expect { @defaults.send(:combine_components_into_name, data) }.to_not raise_error
81
+
82
+ data[:field] = [data[:field]]
83
+ expect { @defaults.send(:combine_components_into_name, data) }.to_not raise_error
84
+ end
85
+
86
+ end
87
+
88
+ describe ".split_name_into_components" do
89
+
90
+ before do
91
+ @defaults = Fech::DefaultTranslations.new(Fech::Translator.new)
92
+ end
93
+
94
+ it "should accept :field as either Array or Symbol" do
95
+ data = {:row => /^sc$/, :version => /^[6-7]/, :field => :lender_candidate}
96
+ expect { @defaults.send(:split_name_into_components, data) }.to_not raise_error
97
+
98
+ data[:field] = [data[:field]]
99
+ expect { @defaults.send(:split_name_into_components, data) }.to_not raise_error
100
+ end
101
+
102
+ end
103
+
104
+ end