Skip to content

Instantly share code, notes, and snippets.

@mooreniemi
Created May 8, 2012 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mooreniemi/2639232 to your computer and use it in GitHub Desktop.
Save mooreniemi/2639232 to your computer and use it in GitHub Desktop.
post promo payment
require 'date'
require 'csv'
#Given a csv file output from Sermo App at https://app.sermo.com/reporting/reports/post_summary_by_date
#we need a csv of the Post Promo contest winners (base $15 and grand prize $30) by the week's targeted specialties.
#We need to only pay members once, and only pay them for posts which received 10 comments and an average rating of at least 3 stars.
#Specialties targeted were sent an automated e-mail from Exact Target to remind them it was their day to participate.
#You will only need to tell this program what the file name from the Sermo app was, and it will output a payment csv file for you!
#constructor of my post object with the csv fields to hold all the attributes
class Post <
Struct.new(:post_id, :publish_date, :avg_rating, :raters, :comments, :voters, :views, :author_id, :username, :first_name, :last_name, :email, :specialty, :pop, :prize)
end
# define an array to hold the all the posts of the week
posts = Array.new
#asks me what the file name for the week is and removes enter
csv = gets.chomp
# open csv file and then grab each field, skipping top row of field names
CSV.foreach(csv) {|fields|
if fields[0] == 'Post ID' then
next
end
# create a new Post constructor object
p = Post.new
#methods after field object to get rid of double-quotes and blanks
p.post_id = fields[0].tr_s('"', '').strip
#taking the hours and minutes off the date field
date = fields[4].split(' ')[0]
#then convert that date variable to the ruby Date object
p.publish_date = Date.parse(date)
p.avg_rating = fields[5].tr_s('"', '').strip.to_f
p.raters = fields[6].tr_s('"', '').strip.to_i
p.comments = fields[7].tr_s('"', '').strip.to_i
p.voters = fields[8].tr_s('"', '').strip.to_i
p.views = fields[10].tr_s('"', '').strip.to_i
p.author_id = fields[11].tr_s('"', '').strip
p.username = fields[12].tr_s('"', '').strip
p.first_name = fields[13].tr_s('"', '').strip
p.last_name = fields[14].tr_s('"', '').strip
p.email = fields[15].tr_s('"', '').strip
#for non-physician accounts a nil value of specialty appears which this skips
if fields[16].nil? then
next
end
p.specialty = fields[16].tr_s('"', '').strip
#puts the items p into the array posts
posts.push(p)
}
#defining my hashes for post promo schedule
#1-4 is M-Thu
week1 = {1=>["Internal Medicine"],
2=>["Anesthesiology", "Critical Care", "Endocrinology", "Ophthalmology", "Otolaryngology", "Women's Health"],
3=>["Allergy and Immunology", "Cardiology", "Gastroenterology", "Infectious Diseases", "Med/Peds","Neurosurgery","Plastic Surgery", "Surgery - General"],
4=>["Dermatology", "Neurology", "Pediatrics"]}
week2 = {1=>["Oncology", "Pathology", "Psychiatry", "Pulmonology"],
2=>["Emergency Medicine", "Hematology", "Hospitalist", "Pain Medicine", "Physiatry", "Radiology", "Rheumatology"],
3=>["Family Medicine"],
4=>["Geriatrics", "Nephrology", "OBGYN", "Orthopaedics", "Osteopathy", "Urology"]}
#another hash containing the week hashes
whichweek = {0=>week1, 1=>week2}
#regrouping the weekday qualifiers into weekly qualifiers
specialties1 = week1.values.flatten
specialties2 = week2.values.flatten
by_specialty = {0=>specialties1, 1=>specialties2}
#checking which week by publish date in the csv file and comparing it to the calendar week in the year on a modulo rotation
week = (posts.first.publish_date.cweek-1) %2
qualified = Array.new
posts.each { |p|
#tells us if it's schedule 1 or 2 and then converts the publish date field into a wday number
participating = whichweek[week][p.publish_date.wday]
#checks if a specialty is in the week1 or week2 hash
if participating.include?(p.specialty) then
qualified.push(p)
end
}
#daily winners
winners = Array.new
qualified.each {|p|
#checks requirements to win base prize
if p.comments >= 10 and p.avg_rating >= 3 then
#assigns new prize field to the post object
p.prize = 15
#assigns new popularity field to the post object
#formula is ancient and based on averages, by Joe Bulkin
p.pop = p.comments+(0.38*p.raters)+(0.35*p.voters)+(0.06*p.views)
winners.push(p)
end
}
#now we need to find the grand prize winners, 1 per each specialty
#first, in by specialty find which week it is
by_specialty[week].each {|specialty|
#choses specialty for iteration and gives me virtual array of it
winnersinspec = Array.new
winners.each{|p|
#takes winners and organizes by specialty
if p.specialty == specialty then
winnersinspec.push(p)
end
}
#takes winners organized by specialty and sorts so that most popular post is last
winnersinspec.sort_by! {|p|
p.pop
}
if winnersinspec.length != 0 then
#gives most popular post by given specialist the grand prize
winnersinspec.last.prize = 30
end}
#creats empty hash to determine dupes, author ids will be keys and posts will be values per each key
duplicates = {}
#writing into our hash
winners.each{|p|
#checks keys, at first our hash is empty
if not duplicates.has_key?(p.author_id) then
#creates keys
duplicates[p.author_id] = [p]
#adds values to the keys
else duplicates[p.author_id].push(p)
end}
#checking key by key
duplicates.each_key {|author_id|
#within each key's author array sorting for pop
duplicates[author_id].sort_by! {|p|
p.pop
}
#choosing only the most pop for each author, sorted so last is most popular
duplicates[author_id] = duplicates[author_id].last
}
#redefining winners array to only the most pop for each author
winners = duplicates.values
#outputing a csv file with today's date
payments = File.open("Week of " + posts.last.publish_date.next.strftime("%m%d%y") + ".csv", "w")
#adding necessary extra field for bookkeeper and arranging them how it likes
winners.each {|p|
#the batch transactions uploader wants the first five columns to be: event date, honorarium, activity type, activity id, and the payee user id
row = [ p.publish_date, p.prize, "mktg_other", p.post_id, p.author_id, p.username, p.first_name, p.last_name, p.email]
payments.puts row.join(",")
}
payments.close
#What did we just output?
#A file containing everything bookkeeper in the Sermo App needs to upload, but you may want to add a comments field in the csv file.
#Not adding it in here, because comments are only for error'd surveys, customer support issues, and other misc physician payments--
#this program is not designed to output anything but the weekly post promo winners. :)
#Upload the generated file to: https://app.sermo.com/accounting/transactions/upload_batch_new
#amoore-niemi@sermo.com or moore.niemi@gmail.com
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment