This specialization of ReportBase implements a template generator for status sheets. The status sheet is structured using the TJP file syntax.
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
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
# 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.
Generated with the Darkfish Rdoc Generator 1.1.6.