| Class | PeopleFile |
| In: |
app/models/people_file.rb
|
| Parent: | GridFile |
Excel or text file of People. Assumes that the first row is a header row. Updates membership to current year. If there are no more events in the current year, updates membership to next year. See trac.butlerpress.com/racing_on_rails/wiki/SampleImportFiles for format details and examples.
| COLUMN_MAP | = | { 'team' => 'team_name', 'Cycling Team' => 'team_name', 'club' => 'club_name', 'ncca club' => 'ncca_club_name', 'fname' => 'first_name', 'lname' => 'last_name', 'f_name' => 'first_name', 'l_name' => 'last_name', 'FirstName' => 'first_name', 'first name' => 'first_name', 'LastName' => 'last_name', 'last name' => 'last_name', 'AAA Last Name' => 'last_name', 'Birth date' => 'date_of_birth', 'Birthdate' => 'date_of_birth', 'year of birth' => 'date_of_birth', 'dob' => 'date_of_birth', 'address' => 'street', 'Address1_Contact address' => 'street', 'Address2_Contact address' => 'street', 'address1' => 'street', 'City_Contact address' => 'city', 'State_Contact address' => 'state', 'Zip_Contact address' => 'zip', 'Phone' => 'home_phone', 'DayPhone' => 'home_phone', 'cell/fax' => 'cell_fax', 'cell' => 'cell_fax', 'e-mail' => 'email', 'category' => 'road_category', 'road cat' => 'road_category', 'Cat.' => 'road_category', 'cat' => 'road_category', 'Road Category - ' => 'road_category', 'Road Age Group - ' => 'road_category', 'USCF Category' => 'road_category', 'track cat' => 'track_category', 'Track Category - ' => 'track_category', 'Track Age Group - ' => 'track_category', 'Cyclocross Category - ' => 'ccx_category', 'cross cat' => 'ccx_category', 'ccx cat' => 'ccx_category', 'Cyclocross Age Group -' => 'ccx_category', 'Cross Country Mountain Bike Category -' => 'mtb_category', 'mtn cat' => 'mtb_category', 'Cross Country Mountain Age Group -' => 'mtb_category', 'XC' => 'mtb_category', 'Downhill Mountain Bike Category - ' => 'dh_category', 'dh cat' => 'dh_category', 'dh' => 'dh_category', 'Downhill Mountain Bike Age Group -' => 'dh_category', 'number' => 'road_number', '2009 road' => 'road_number', 'WSBA #' => 'road_number', '2009 xc' => 'xc_number', 'mtb #' => 'xc_number', '09 dh' => 'dh_number', 'singlespeed' => 'singlespeed_number', '2009 ss' => 'singlespeed_number', 'ss' => 'singlespeed_number', 'ss #' => 'singlespeed_number', 'Membership No' => 'license', 'license#' => 'license', 'date joined' => 'member_from', 'exp date' => 'member_usac_to', 'expiration date' => 'member_usac_to', 'card' => 'print_card', 'sex' => 'gender', 'What is your occupation? (optional)' => 'occupation', 'Suspension' => 'status', #e.g. "SUSPENDED - Contact USA Cycling" 'Interests' => 'notes', 'Receipt Code' => 'notes', 'Confirmation Code' => 'notes', 'Transaction Payment Total' => 'notes', 'Registration Completion Date/Time' => 'notes', 'Donation' => 'notes', 'Singlespeed' => 'notes', 'Tandem' => 'notes', 'Please select a category:' => Column.new(:name => 'notes', :description => 'Disciplines'), '2009 notes' => 'notes', 'Would you like to make an additional donation to support OBRA? ' => Column.new(:name => 'notes', :description => 'Donation'), 'Please indicate if you are interested in racing cross country or downhill. ' => Column.new(:name => 'notes', :description => 'Downhill/Cross Country'), 'Please indicate if you are interested in racing single speed.' => Column.new(:name => 'notes', :description => 'Singlespeed'), 'Please indicate other interests. (For example: time trial tandem triathalon r' => Column.new(:name => 'notes', :description => 'Other interests'), 'Your team or club name (please enter N/A if you do not have a team affiliation)' => Column.new(:name => 'team_name', :description => 'Team') |
‘club’ …this is often team in USAC download. How handle?
Use club for team if no team? and if both, ignore club?
'NCCA club' ...can have this in addition to club and team. should team be many to many? |
| created | [R] | |
| duplicates | [R] | |
| updated | [R] |
# File app/models/people_file.rb, line 100
100: def initialize(source, *options)
101: if options.empty?
102: options = Hash.new
103: else
104: options = options.first
105: end
106: options = {
107: :delimiter => ',',
108: :quoted => true,
109: :header_row => true,
110: :row_class => Person,
111: :column_map => COLUMN_MAP
112: }.merge(options)
113:
114: super(source, options)
115:
116: @created = 0
117: @updated = 0
118: @duplicates = []
119: end
year for RaceNumbers New memberships start on today, but really should start on January 1st of next year, if year is next year
# File app/models/people_file.rb, line 123
123: def import(update_membership, year = nil)
124: logger.debug("PeopleFile import update_membership: #{update_membership}")
125: @update_membership = update_membership
126: @has_print_column = columns.any? do |column|
127: column.field == :print_card
128: end
129: year = year.to_i if year
130:
131: logger.debug("#{rows.size} rows")
132: created = 0
133: updated = 0
134: if @update_membership
135: if year && year > Date.today.year
136: @member_from_imported_people = Date.new(year, 1, 1)
137: else
138: @member_from_imported_people = Date.today
139: end
140: @member_to_for_imported_people = Date.new(year || Date.today.year, 12, 31)
141: end
142:
143: Person.transaction do
144: begin
145: rows.each do |row|
146: row_hash = row.to_hash
147: row_hash[:year] = year if year
148: row_hash[:updated_by] = "Membership import: #{import_file.name}"
149: logger.debug(row_hash.inspect) if logger.debug?
150: next if row_hash[:first_name].blank? && row_hash[:first_name].blank? && row_hash[:name].blank?
151:
152: combine_categories(row_hash)
153: row_hash.delete(:date_of_birth) if row_hash[:date_of_birth] == 'xx'
154:
155: # TODO or by USAC license number
156: people = []
157:
158: if row_hash[:license].present?
159: people = Person.find_all_by_license(row_hash[:license])
160: end
161:
162: if people.empty?
163: people = Person.find_all_by_name_or_alias(:first_name => row_hash[:first_name], :last_name => row_hash[:last_name])
164: end
165:
166: person = nil
167: row_hash[:member_to] = @member_to_for_imported_people if @update_membership
168: if people.empty?
169: delete_unwanted_member_from(row_hash, person)
170: add_print_card_and_label(row_hash)
171: row_hash[:created_by] = import_file
172: person = Person.new(row_hash)
173: person.save!
174: @created = @created + 1
175: elsif people.size == 1
176: # Don't want to overwrite existing categories
177: delete_blank_categories(row_hash)
178: person = people.first
179: delete_unwanted_member_from(row_hash, person)
180: unless person.notes.blank?
181: row_hash[:notes] = "#{people.last.notes}#{$INPUT_RECORD_SEPARATOR}#{row_hash[:notes]}"
182: end
183: add_print_card_and_label(row_hash, person)
184:
185: person = Person.update(people.last.id, row_hash)
186: unless person.valid?
187: raise ActiveRecord::RecordNotSaved.new(person.errors.full_messages.join(', '))
188: end
189: @updated = @updated + 1
190: else
191: logger.warn("PeopleFile Found #{people.size} people for '#{row_hash[:first_name]} #{row_hash[:last_name]}'")
192: delete_blank_categories(row_hash)
193: person = Person.new(row_hash)
194: delete_unwanted_member_from(row_hash, person)
195: unless person.notes.blank?
196: row_hash[:notes] = "#{people.last.notes}#{$INPUT_RECORD_SEPARATOR}#{row_hash[:notes]}"
197: end
198: add_print_card_and_label(row_hash, person)
199: duplicates << Duplicate.create!(:new_attributes => row_hash, :people => people)
200: end
201: end
202: rescue Exception => e
203: logger.error("PeopleFile #{e}")
204: raise
205: end
206: end
207: return @created, @updated
208: end