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/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/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:                      'costAccount' => a('costAccount'),
 91:                      'revenueAccount' => a('revenueAccount') }
 92:       resourceList.query = Query.new(queryAttrs)
 93:       resourceList.sort!
 94: 
 95:       # Prepare the task list.
 96:       taskList = PropertyList.new(@project.tasks)
 97:       taskList.setSorting(@report.get('sortTasks'))
 98:       taskList = filterTaskList(taskList, nil, @report.get('hideTask'),
 99:                                 @report.get('rollupTask'),
100:                                 @report.get('openNodes'))
101:       taskList.sort!
102: 
103:       resourceList.each do |resource|
104:         # Status sheets only make sense for leaf resources.
105:         next unless resource.leaf?
106: 
107:         # Collect a list of tasks that the Resource is responsible for and
108:         # don't have a parent task that the Resource is responsible for.
109:         topLevelTasks = []
110:         taskList.each do |task|
111:           if task['responsible', scenarioIdx].include?(resource) &&
112:              (task.parent.nil? ||
113:               !task.parent['responsible', scenarioIdx].include?(resource))
114:             topLevelTasks << task
115:           end
116:         end
117: 
118:         next if topLevelTasks.empty?
119: 
120:         # Store the list of top-level responsibilities.
121:         @managers << (manager = ManagerStatusRecord.new(resource))
122: 
123:         topLevelTasks.each do |task|
124:           # Get a list of all the current Journal entries for this task and
125:           # all it's sub tasks.
126:           entries = @project['journal'].currentEntriesR(a('end'), task,
127:                                                         0, a('start') + 1)
128:           next if entries.empty?
129: 
130:           manager.responsibilities << ManagerResponsibilities.new(task, entries)
131:         end
132:         # Sort the responsibilities list according to the original taskList.
133:         manager.sort!(taskList)
134:       end
135:     end
to_tjp() click to toggle source

Generate a time sheet in TJP syntax format.

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

Private Instance Methods

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

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.