Class: TaskJuggler::TraceReport
- Inherits:
-
ReportBase
- Object
- ReportBase
- TaskJuggler::TraceReport
- Includes:
- MessageHandler
- Defined in:
- lib/taskjuggler/reports/TraceReport.rb
Overview
The trace report is used to periodically snapshot a specific list of property attributes and add them to a CSV file.
Instance Method Summary collapse
-
#generateIntermediateFormat ⇒ Object
Generate the table in the intermediate format.
-
#initialize(report) ⇒ TraceReport
constructor
Create a new object and set some default values.
- #to_csv ⇒ Object
- #to_html ⇒ Object
Methods included from MessageHandler
#critical, #debug, #error, #fatal, #info, #warning
Methods inherited from ReportBase
#a, #filterAccountList, #filterResourceList, #filterTaskList
Constructor Details
#initialize(report) ⇒ TraceReport
Create a new object and set some default values.
29 30 31 32 |
# File 'lib/taskjuggler/reports/TraceReport.rb', line 29 def initialize(report) super @table = nil end |
Instance Method Details
#generateIntermediateFormat ⇒ Object
Generate the table in the intermediate format.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/taskjuggler/reports/TraceReport.rb', line 35 def generateIntermediateFormat super queryAttrs = { 'project' => @project, 'scopeProperty' => nil, 'loadUnit' => a('loadUnit'), 'numberFormat' => a('numberFormat'), # We use a hardcoded %Y-%m-%d format for tracereports. 'timeFormat' => "%Y-%m-%d", 'currencyFormat' => a('currencyFormat'), 'start' => a('start'), 'end' => a('end'), 'hideJournalEntry' => a('hideJournalEntry'), 'journalMode' => a('journalMode'), 'journalAttributes' => a('journalAttributes'), 'sortJournalEntries' => a('sortJournalEntries'), 'costAccount' => a('costaccount'), 'revenueAccount' => a('revenueaccount') } query = Query.new(queryAttrs) # Prepare the account list. accountList = PropertyList.new(@project.accounts) accountList.setSorting(a('sortAccounts')) accountList.query = query accountList = filterAccountList(accountList, a('hideAccount'), a('rollupAccount'), a('openNodes')) accountList.sort! # Prepare the resource list. resourceList = PropertyList.new(@project.resources) resourceList.setSorting(a('sortResources')) resourceList.query = query resourceList = filterTaskList(resourceList, nil, a('hideResource'), a('rollupResource'), a('openNodes')) resourceList.sort! # Prepare the task list. taskList = PropertyList.new(@project.tasks) taskList.includeAdopted taskList.setSorting(a('sortTasks')) taskList.query = query taskList = filterTaskList(taskList, nil, a('hideTask'), a('rollupTask'), a('openNodes')) taskList.sort! @fileName = ((@report.name[0] == '/' ? '' : @project.outputDir) + @report.name + '.csv').untaint # Generate the table header. headers = [ 'Date' ] + generatePropertyListHeader(accountList, query) + generatePropertyListHeader(resourceList, query) + generatePropertyListHeader(taskList, query) discontinuedColumns = 0 if File.exist?(@fileName) begin @table = CSVFile.new(nil, nil).read(@fileName) rescue error('tr_cannot_read_csv', "Cannot read CSV file #{@fileName}: #{$!}") end if @table[0] != headers # Some columns have changed. We move all discontinued columns to the # last columns and rearrange the others according to the new # headers. New columns will be filled with nil in previous rows. sorter = TableColumnSorter.new(@table) @table = sorter.sort(headers) discontinuedColumns = sorter.discontinuedColumns end else @table = [ headers ] end # Convert empty strings into nil objects and dates in %Y-%m-%d format # into TjTime objects. @table.each do |line| line.length.times do |i| if line[i] == '' line[i] = nil elsif line[i].is_a?(String) && /\d{4}-\d{2}-\d{2}/ =~ line[i] line[i] = TjTime.new(line[i]) end end end query = @project.reportContexts.last.query.dup dateTag = @project['now'].midnight idx = @table.index { |line| line[0] == dateTag } discColumnValues = discontinuedColumns > 0 ? Array.new(discontinuedColumns, nil) : [] if idx # We already have an entry for the current date. All old values of # this line will be overwritten with the current values. The old # values in the discontinued columns will be kept. if discontinuedColumns > 0 discColumnValues = @table[idx][headers.length..-1] end @table[idx] = [] else # Append a new line of values to the table. @table << [] idx = -1 end # The first entry is always the current date. @table[idx] << dateTag # Now add the new values to the line generatePropertyListValues(idx, accountList, query) generatePropertyListValues(idx, resourceList, query) generatePropertyListValues(idx, taskList, query) # Fill the discontinued columns with old values or nil. @table[idx] += discColumnValues # Sort the table by ascending first column dates. We need to ensure that # the header remains the first line in the table. @table.sort! { |l1, l2| l1[0].is_a?(String) ? -1 : (l2[0].is_a?(String) ? 1 : l1[0] <=> l2[0]) } end |
#to_csv ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/taskjuggler/reports/TraceReport.rb', line 174 def to_csv # Convert all TjTime values into String with format %Y-%m-%d and nil # objects into empty Strings. @table.each do |line| line.length.times do |i| if line[i].nil? line[i] = '' elsif line[i].is_a?(TjTime) line[i] = line[i].to_s('%Y-%m-%d') end end end @table end |
#to_html ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/taskjuggler/reports/TraceReport.rb', line 157 def to_html html = [] html << rt_to_html('header') begin plotter = ChartPlotter.new(a('width'), a('height'), @table) plotter.generate html << plotter.to_svg rescue ChartPlotterError => exception warning('chartPlotterError', exception., @report.sourceFileInfo) end html << rt_to_html('footer') html end |