require 'csv' module Twstats class CSVReader attr_reader :logs attr_reader :tags attr_reader :people attr_reader :tasks attr_reader :projects # Create an object structure from the csv file which allows to easily read the content def initialize(file) @logs = Set.new([]) @tags = Set.new([]) @people = Set.new([]) @tasks = Set.new([]) @projects = Set.new([]) # Initialize the reader with a csv file and fill the times as an array of columns CSV.foreach(file, DEFAULT_OPTIONS) do |row| update_info TwLog.new(row) end end def update_info(log) @projects << log.project @people << log.who log.tags.each{|x| @tags << x} @tasks << log.task @logs << log end def mean_time logs.inject(0) {|sum, log| sum + log.decimal_time }.to_f/logs.size end def get_total_time(object, element, filter_billable) billable = 0 non_billable = 0 case object when :projects billable = logs.select{|log| log.project == element && log.billable}.inject(0){ |sum, l| sum + l.decimal_time} non_billable = logs.select{|log| log.project == element && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time} when :tags billable = logs.select{|log| log.tags.include?(element) && log.billable}.inject(0){ |sum, l| sum + l.decimal_time} non_billable = logs.select{|log| log.tags.include?(element) && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time} when :people billable = logs.select{|log| log.who == element && log.billable}.inject(0){ |sum, l| sum + l.decimal_time} non_billable = logs.select{|log| log.who == element && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time} when :tasks billable = logs.select{|log| log.task == element && log.billable}.inject(0){ |sum, l| sum + l.decimal_time} non_billable = logs.select{|log| log.task == element && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time} when :all billable = logs.select{|log| log.billable}.inject(0){ |sum, l| sum + l.decimal_time} non_billable = logs.select{|log| !log.billable}.inject(0){ |sum, l| sum + l.decimal_time} else return -99999 end if filter_billable return [billable, non_billable] else return billable + non_billable end end def is_weekly? sorted_logs = logs.map{|l| l.date}.sort (sorted_logs[-1] - sorted_logs[0]).to_i <= 7 end ## Filer the logs in the CSV by a given object when the element provided matches the object def get_logs(object, element = nil) case object when :projects logs.select{|log| log.project == element} when :tags logs.select{|log| log.tags.include?(element)} when :people logs.select{|log| log.who == element} when :tasks logs.select{|log| log.task == element} when :all logs else nil end end def not_tagged_tasks(to_analize=nil) to_analize = logs if to_analize.nil? total_time = 0 list = [] to_analize.each do |log| if log.tags.empty? list << log total_time += log.decimal_time end end { total_time: total_time, list: list } end end end