Skip to content

Instantly share code, notes, and snippets.

@bradgessler
Created November 7, 2012 01:12
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 bradgessler/4028891 to your computer and use it in GitHub Desktop.
Save bradgessler/4028891 to your computer and use it in GitHub Desktop.
Generate a report by month for the amount of payment received in Blinksale
require 'open-uri'
require 'nokogiri'
require 'filecache'
require 'logger'
require 'date'
require 'pry'
# When do you want to grab invoices? Default is 90 days ago.
@since = ENV.include?('SINCE') ? Date.parse(ENV['SINCE']) : Date.today - 90
# Blinksale username
@username = ENV['USERNAME']
# Blinksale password
@password = ENV['PASSWORD']
# Display status on this process.
@logger = Logger.new($stdout)
# Read responses from website and memoize to file sytem.
def memoize(key, &block)
if value = cache.get(key)
value
else
value = block.call
cache.set(key, value)
value
end
end
# Initalize file cache to speed up invoice processing with multiple runs.
def cache
@cache ||= FileCache.new('blinksale', '.cache')
end
# Execute and caches HTTP requests.
def get(url)
memoize url do
@logger.info "HTTP GET #{url.inspect}"
open(url,
:http_basic_authentication => [@username, @password],
'Accept' => 'application/vnd.blinksale+xml'
).read
end
end
# Read XML from website (and cache)
invoices_xml = get("https://polleverywhere.blinksale.com/invoices/closed/date/#{@since.strftime('%Y-%m-%d')}")
invoices = Nokogiri::XML(invoices_xml).css('invoice[uri]')
@logger.info "Analysis of #{invoices.count} invoice(s)"
# Parse invoices XML
invoice_payments_xml = invoices.map do |invoice|
Nokogiri::XML(get(File.join(invoice[:uri], '/payments')))
end
# Group payments by month.
grouped = invoice_payments_xml.group_by do |payment|
created_at = Time.parse(payment.css('payment').first[:created_at])
Time.utc(created_at.year, created_at.month)
end
# Now lets sum up all of the payments per month
totals = grouped.reduce Hash.new do |hash, (month, payments)|
hash[month] = payments.map{ |i| i.css('amount').map(&:content) }.flatten.map(&:to_i).reduce(&:+)
hash
end
# And finally, we should print it out!
puts "Month\t\tTotal"
totals.each do |month, total|
puts "#{month.strftime('%B, %Y')}\t#{total}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment