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/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
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
# 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.
Generated with the Darkfish Rdoc Generator 1.1.6.