Class Index [+]

Quicksearch

TaskJuggler::StatusSheetReport

This specialization of ReportBase implements a template generator for status sheets. The status sheet is structured using the TJP file syntax.

Public Class Methods

new(report) click to toggle source

Create a new object and set some default values.

    # File lib/taskjuggler/reports/StatusSheetReport.rb, line 61
61:     def initialize(report)
62:       super(report)
63: 
64:       # A list of ManagerStatusRecord objects, one for each manager.
65:       @managers = []
66:     end

Public Instance Methods

generateIntermediateFormat() click to toggle source

In the future we might want to generate other output than TJP synatx. So we generate an abstract version of the status sheet first.

     # File lib/taskjuggler/reports/StatusSheetReport.rb, line 70
 70:     def generateIntermediateFormat
 71:       super
 72: 
 73:       # Prepare the resource list.
 74:       resourceList = PropertyList.new(@project.resources)
 75:       resourceList.setSorting(@report.get('sortResources'))
 76:       resourceList = filterResourceList(resourceList, nil,
 77:                                         @report.get('hideResource'),
 78:                                         @report.get('rollupResource'),
 79:                                         @report.get('openNodes'))
 80:       # Prepare a template for the Query we will use to get all the data.
 81:       scenarioIdx = a('scenarios')[0]
 82:       queryAttrs = { 'project' => @project,
 83:                      'scopeProperty' => nil,
 84:                      'scenarioIdx' => scenarioIdx,
 85:                      'loadUnit' => a('loadUnit'),
 86:                      'numberFormat' => a('numberFormat'),
 87:                      'timeFormat' => a('timeFormat'),
 88:                      'currencyFormat' => a('currencyFormat'),
 89:                      'start' => a('start'), 'end' => a('end'),
 90:                      'hideJournalEntry' => a('hideJournalEntry'),
 91:                      'costAccount' => a('costAccount'),
 92:                      'revenueAccount' => a('revenueAccount') }
 93:       resourceList.query = Query.new(queryAttrs)
 94:       resourceList.sort!
 95: 
 96:       # Prepare the task list.
 97:       taskList = PropertyList.new(@project.tasks)
 98:       taskList.setSorting(@report.get('sortTasks'))
 99:       taskList = filterTaskList(taskList, nil, @report.get('hideTask'),
100:                                 @report.get('rollupTask'),
101:                                 @report.get('openNodes'))
102:       taskList.sort!
103: 
104:       resourceList.each do |resource|
105:         # Status sheets only make sense for leaf resources.
106:         next unless resource.leaf?
107: 
108:         # Collect a list of tasks that the Resource is responsible for and
109:         # don't have a parent task that the Resource is responsible for.
110:         topLevelTasks = []
111:         taskList.each do |task|
112:           if task['responsible', scenarioIdx].include?(resource) &&
113:              (task.parent.nil? ||
114:               !task.parent['responsible', scenarioIdx].include?(resource))
115:             topLevelTasks << task
116:           end
117:         end
118: 
119:         next if topLevelTasks.empty?
120: 
121:         # Store the list of top-level responsibilities.
122:         @managers << (manager = ManagerStatusRecord.new(resource))
123: 
124:         topLevelTasks.each do |task|
125:           # Get a list of all the current Journal entries for this task and
126:           # all it's sub tasks.
127:           entries = @project['journal'].
128:             currentEntriesR(a('end'), task, 0, a('start') + 1,
129:                             resourceList.query.hideJournalEntry)
130:           next if entries.empty?
131: 
132:           manager.responsibilities << ManagerResponsibilities.new(task, entries)
133:         end
134:         # Sort the responsibilities list according to the original taskList.
135:         manager.sort!(taskList)
136:       end
137:     end
to_tjp() click to toggle source

Generate a time sheet in TJP syntax format.

     # File lib/taskjuggler/reports/StatusSheetReport.rb, line 140
140:     def to_tjp
141: 
142:       # This String will hold the result.
143:       @file = ''
144: 
145:       # Iterate over all the ManagerStatusRecord objects.
146:       @managers.each do |manager|
147:         resource = manager.resource
148:         @file << "# --------8<--------8<--------\n"
149:         # Generate the time sheet header
150:         @file << "statussheet #{resource.fullId} " +
151:                  "#{a('start')} - #{a('end')} {\n\n"
152: 
153:         if manager.responsibilities.empty?
154:           # If there were no assignments, just write a comment.
155:           @file << "  # This resource is not responsible for any task.\n\n"
156:         else
157:           manager.responsibilities.each do |responsibility|
158:             task = responsibility.task
159:             @file << "  # Task: #{task.name}\n"
160: 
161:             responsibility.journalEntries.each do |entry|
162:               task = entry.property
163:               @file << "  task #{task.fullId} {\n"
164:               alertLevel = @project['alertLevels'][entry.alertLevel][0]
165:               @file << "    # status #{alertLevel} \"#{entry.headline}\" {\n"
166:               @file << "    #   # Date: #{entry.date}\n"
167:               if (tsRecord = entry.timeSheetRecord)
168:                 @file << "    #   # "
169:                 @file << "Work: #{tsRecord.actualWorkPercent.to_i}% "
170:                 if tsRecord.actualWorkPercent != tsRecord.planWorkPercent
171:                   @file << "(#{tsRecord.planWorkPercent.to_i}%) "
172:                 end
173:                 if tsRecord.remaining
174:                   @file << "   Remaining: #{tsRecord.actualRemaining}d "
175:                   if tsRecord.actualRemaining !=  tsRecord.planRemaining
176:                     @file << "(#{tsRecord.planRemaining}d) "
177:                   end
178:                 else
179:                   @file << "   End: " +
180:                            "#{tsRecord.actualEnd.to_s(a('timeFormat'))} "
181:                   if tsRecord.actualEnd != tsRecord.planEnd
182:                     @file << "(#{tsRecord.planEnd.to_s(a('timeFormat'))}) "
183:                   end
184:                 end
185:                 @file << "\n"
186:               end
187:               @file << "    #   author #{entry.author.fullId}\n" if entry.author
188:               unless entry.flags.empty?
189:                 @file << "    #   flags #{entry.flags.join(', ')}\n"
190:               end
191:               if entry.summary
192:                 @file << "    #   summary -8<-\n" +
193:                          indentBlock(4, entry.summary.richText.inputText) +
194:                          "    #   ->8-\n"
195:               end
196:               if entry.details
197:                 @file << "    #   details -8<-\n" +
198:                          indentBlock(4, entry.details.richText.inputText) +
199:                          "    #   ->8-\n"
200:               end
201:               @file << "    # }\n  }\n\n"
202: 
203:             end
204:           end
205:         end
206:         @file << "}\n# -------->8-------->8--------\n\n"
207:       end
208:       @file
209:     end

Private Instance Methods

indentBlock(indent, text) click to toggle source
     # File lib/taskjuggler/reports/StatusSheetReport.rb, line 213
213:     def indentBlock(indent, text)
214:       indentation = ' ' * indent + '#   '
215:       buffer = indentation
216:       out = ''
217:       text.each_utf8_char do |c|
218:         unless buffer.empty?
219:           out += buffer
220:           buffer = ''
221:         end
222:         out << c
223:         buffer = indentation if c == "\n"
224:       end
225:       # Make sure we always have a trailing line break
226:       out += "\n" unless out[1] == "\n"
227:       out
228:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.