module RbInvoice::Options
Public Class Methods
add_invoice_to_data(tasks, start_date, end_date, filename, opts)
click to toggle source
# File lib/rbinvoice/options.rb, line 151 def self.add_invoice_to_data(tasks, start_date, end_date, filename, opts) data = opts[:data] client = data_for_client(data, opts[:client]) || add_new_client_data(opts[:client], data) (client[:invoices] ||= []) << { 'id' => opts[:invoice_number], 'start_date' => start_date, 'end_date' => end_date, 'filename' => filename } if not data[:last_invoice] or opts[:invoice_number] > data[:last_invoice] data[:last_invoice] = opts[:invoice_number] end write_data_file(opts) end
add_new_client_data(client, data)
click to toggle source
# File lib/rbinvoice/options.rb, line 141 def self.add_new_client_data(client, data) h = { 'name' => client, 'key' => client, 'invoices' => [] } (data[:clients] ||= []) << h return h end
address_for_client(data, opts, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 211 def self.address_for_client(data, opts, client) key_for_client(data, client, :address) end
all_clients(data)
click to toggle source
# File lib/rbinvoice/options.rb, line 166 def self.all_clients(data) data[:clients] || [] end
data_for_client(data, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 174 def self.data_for_client(data, client) all_clients(data).select{|x| x[:key] == RbInvoice::to_client_key(client)}.first end
dba_for_client(data, opts, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 199 def self.dba_for_client(data, opts, client) key_for_client(data, client, :dba) || opts[:dba] || 'Illuminated Computing Inc.' end
default_data_file()
click to toggle source
default_out_directory(opts)
click to toggle source
TODO: Allow per-client settings to override the global setting
# File lib/rbinvoice/options.rb, line 73 def self.default_out_directory(opts) opts[:out_directory] || '.' end
default_out_filename(opts)
click to toggle source
Looks in ~/.rbinvoice
# File lib/rbinvoice/options.rb, line 78 def self.default_out_filename(opts) if opts[:client] and opts[:invoice_number] File.join(default_out_directory(opts), "invoice-#{opts[:invoice_number]}-#{opts[:client]}.pdf") else nil end end
default_rc_file()
click to toggle source
default_template_filename()
click to toggle source
# File lib/rbinvoice/options.rb, line 25 def self.default_template_filename File.join(File.dirname(__FILE__), '..', '..', 'templates', 'invoice.tex.liquid') end
description_for_client(data, opts, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 215 def self.description_for_client(data, opts, client) desc = key_for_client(data, client, :description) "#{desc} from #{opts[:start_date].strftime("%B %-d")} to #{opts[:end_date].strftime("%B %-d, %Y")}." end
find_invoice_bounds(d, freq, second_half_of_biweek=false)
click to toggle source
second_half_of_biweek - indicates that ‘d` is from the second half of the biweek. If false (the default), we assume `d` is from the first half.
# File lib/rbinvoice/options.rb, line 122 def self.find_invoice_bounds(d, freq, second_half_of_biweek=false) case freq.to_sym when :weekly return week_start(d), week_end(d) when :biweekly if second_half_of_biweek return week_start(d) - 7, week_end(d) else return week_start(d), week_end(d) + 7 end when :semimonthly return semimonth_start(d), semimonth_end(d) when :monthly return first_day_of_the_month(d), last_day_of_the_month(d) else raise "Unknown frequency: #{freq}" end end
first_day_of_the_month(d)
click to toggle source
# File lib/rbinvoice/options.rb, line 86 def self.first_day_of_the_month(d) Date.new(d.year, d.month, 1) end
frequency_for_client(data, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 195 def self.frequency_for_client(data, client) key_for_client(data, client, :frequency) end
frequncy_for_client(data, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 183 def self.frequncy_for_client(data, client) key_for_client(data, client, :frequency) end
full_name_for_client(data, opts, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 207 def self.full_name_for_client(data, opts, client) key_for_client(data, client, :full_name) end
invoices_for_client(data, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 187 def self.invoices_for_client(data, client) key_for_client(data, client, :invoices) || [] end
key_for_client(data, client, key)
click to toggle source
# File lib/rbinvoice/options.rb, line 178 def self.key_for_client(data, client, key) d = data_for_client(data, client) d = d ? d[key] : nil end
last_day_of_the_month(d)
click to toggle source
# File lib/rbinvoice/options.rb, line 90 def self.last_day_of_the_month(d) n = d.next_month Date.new(d.year, d.month, (Date.new(n.year, n.month, 1) - 1).day) end
last_invoice_for_client(data, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 191 def self.last_invoice_for_client(data, client) invoices_for_client(data, client).sort_by{|x| x[:end_date]}.last end
last_invoice_number(data)
click to toggle source
# File lib/rbinvoice/options.rb, line 170 def self.last_invoice_number(data) data[:last_invoice] end
parse_command_line(argv)
click to toggle source
# File lib/rbinvoice/options.rb, line 220 def self.parse_command_line(argv) opts = Trollop::options(argv) do version "rbinvoice #{::RbInvoice::VERSION} (c) 2012 Paul A. Jungwirth" banner <<-EOH USAGE: rbinvoice [options] <client> [filename] EOH opt :help, "Show a help message" opt :rcfile, "Use an rc file other than ~/.rbinvoicerc", :short => '-r' opt :no_rcfile, "Don't read an rc file", :default => false, :short => '-R' opt :data_file, "Use a data file other than ${out_directory}/rbinvoice", :default => nil, :short => '-d' opt :no_data_file, "Don't update the data file", :default => false, :short => '-D' opt :invoice_number, "Use a specific invoice number", :type => :int, :short => '-n' opt :no_write_invoice_number, "Record the invoice number", :default => false, :short => '-N' opt :spreadsheet, "Read the given spreadsheet URL", :type => :string, :short => '-u' opt :start_date, "Date to begin the invoice (yyyy-mm-dd)", :type => :string opt :end_date, "Date to end the invoice (yyyy-mm-dd)", :type => :string opt :template, "Use the given liquid template", :type => :string, :default => RbInvoice::Options::default_template_filename end Trollop::die "client must be given" unless argv.size > 0 opts[:client] = argv.shift read_rc_file(opts) unless opts[:no_rcfile] opts[:data_file] ||= "#{default_out_directory(opts)}/rbinvoice" opts[:data] = read_data_file(opts) if not opts[:invoice_number] and not last_invoice_number(opts[:data]) Trollop::die "Can't determine invoice number" end opts[:invoice_number] ||= last_invoice_number(opts[:data]) + 1 Trollop::die "can't determine hourly spreadsheet" unless opts[:spreadsheet] opts[:out_filename] = argv.shift if not opts[:out_filename] opts[:out_filename] = default_out_filename(opts) opts[:used_default_out_filename] = true # TODO if this is set and not quiet, then print the name of the file we wrote to: "Wrote invoice to #{out_filename}" end Trollop::die "can't infer output filename; please provide one" unless opts[:out_filename] # opts[:start_date] = '2012-07-15' # opts[:end_date] = '2012-07-31' opts[:start_date] = Date.strptime(opts[:start_date], "%Y-%m-%d") if opts[:start_date] opts[:end_date] = Date.strptime(opts[:end_date], "%Y-%m-%d") if opts[:end_date] opts[:dba] = dba_for_client(opts[:data], opts, opts[:client]) opts[:payment_due] = payment_due_for_client(opts[:data], opts, opts[:client]) # Read the list of past invoices. # If there are none, assume there is only one invoice to do. jobs = [] last_invoice = last_invoice_for_client(opts[:data], opts[:client]) if opts[:end_date] and opts[:start_date] # just do it, regardless of frequency. elsif opts[:end_date] or opts[:start_date] freq = frequency_for_client(opts[:data], opts[:client]) if freq opts[:start_date], opts[:end_date] = find_invoice_bounds(opts[:start_date] || opts[:end_date], freq, !!opts[:end_date]) else Trollop::die "can't determine invoice range without frequency" end else # Do all pending invoices (leave start_date and end_date nil). end # return jobs return opts[:client], opts[:start_date], opts[:end_date], opts[:out_filename], opts end
parse_data_file(text, opts)
click to toggle source
# File lib/rbinvoice/options.rb, line 45 def self.parse_data_file(text, opts) text ? RbInvoice::Util::read_with_yaml(text) : {} end
parse_rc_file(text, opts)
click to toggle source
# File lib/rbinvoice/options.rb, line 63 def self.parse_rc_file(text, opts) rc = (text ? RbInvoice::Util::read_with_yaml(text) : {}) %w{spreadsheet spreadsheet_user spreadsheet_password out_directory}.each do |key| key = key.to_sym opts[key] ||= rc[key] end return opts end
payment_due_for_client(data, opts, client)
click to toggle source
# File lib/rbinvoice/options.rb, line 203 def self.payment_due_for_client(data, opts, client) key_for_client(data, client, :payment_due) || opts[:payment_due] || 'upon receipt' end
read_data_file(opts)
click to toggle source
# File lib/rbinvoice/options.rb, line 34 def self.read_data_file(opts) if File.exist?(opts[:data_file]) ret = parse_data_file(File.read(opts[:data_file]), opts) client = data_for_client(ret, opts[:client]) opts[:rate] = client[:rate] if client return ret else return {} end end
read_rc_file(opts)
click to toggle source
# File lib/rbinvoice/options.rb, line 49 def self.read_rc_file(opts) Trollop::die :rcfile, "doesn't exist" if opts[:rcfile] and not File.exist?(opts[:rcfile]) # Don't apply the default until now # so we know if the user requested one specifically or not: opts[:rcfile] ||= default_rc_file if File.exist?(opts[:rcfile]) return parse_rc_file(File.read(opts[:rcfile]), opts) else return opts end end
semimonth_end(d)
click to toggle source
# File lib/rbinvoice/options.rb, line 95 def self.semimonth_end(d) if d.day <= 15 Date.new(d.year, d.month, 15) else Date.new(d.year, d.month, last_day_of_the_month(d).day) end end
semimonth_start(d)
click to toggle source
# File lib/rbinvoice/options.rb, line 103 def self.semimonth_start(d) if d.day <= 15 first_day_of_the_month(d) else Date.new(d.year, d.month, 16) end end
week_end(d)
click to toggle source
# File lib/rbinvoice/options.rb, line 116 def self.week_end(d) week_start(d) + 7 end
week_start(d)
click to toggle source
# File lib/rbinvoice/options.rb, line 111 def self.week_start(d) # Assumes the week starts on a Sunday: d - d.wday end
write_data_file(opts)
click to toggle source
# File lib/rbinvoice/options.rb, line 29 def self.write_data_file(opts) # Add the new invoice to the list of client invoices. File.open(opts[:data_file], 'w') { |f| f.puts YAML::dump(RbInvoice::Util::stringify_hash(opts[:data])) } end