The TimeSheetSender class generates time sheet templates for the current week and sends them out to the project contributors. For this to work, the resources must provide the ‘Email’ custom attribute with their email address. The actual project data is accessed via tj3client on a tj3 server process.
# File lib/taskjuggler/TimeSheetSummary.rb, line 27 27: def initialize 28: super('tj3ts_summary', 'summary') 29: 30: # This is a LogicalExpression string that controls what resources should 31: # not be considered in the summary. 32: @hideResource = '0' 33: # The base directory of the time sheet templates. 34: @templateDir = 'TimeSheetTemplates' 35: # The base directory of the submitted time sheets 36: @sheetDir = 'TimeSheets' 37: # The log file 38: @logFile = 'timesheets.log' 39: # A list of email addresses to send the individual sheets. The sender 40: # will be the sheet submitter. 41: @sheetRecipients = [] 42: # A list of email addresses to send the summary to 43: @digestRecipients = [] 44: 45: @resourceIntro = "== Weekly Report from <nowiki>%s</nowiki> ==\n" 46: @resourceSheetSubject = "Weekly report %s" 47: @summarySubject = "Weekly staff reports %s" 48: @reminderSubject = "Your time sheet for the period ending %s is overdue!" 49: @reminderText = The deadline for your time sheet submission has passed but we haven't receivedit yet. Please submit your time sheet immediately so the content can still beincluded in the management reports. Please send a copy of your submissionnotification email to your manager. If possible, your manager will still tryto include your report data in his/her report.Please be aware that post deadline submissions must be processed manually andcreate an additional load for your manager and/or project manager. Please tryto submit in time in the future.Thanks for your cooperation! 50: @defaulterHeader = "The following %d person(s) have not yet submitted " + 51: "their time sheets:\n\n" 52: end
# File lib/taskjuggler/TimeSheetSummary.rb, line 67 67: def sendSummary(resourceIds) 68: setWorkingDir 69: 70: summary = '' 71: defaulterList = [] 72: getResourceList.each do |resource| 73: resourceId = resource[0] 74: resourceName = resource[1] 75: resourceEmail = resource[2] 76: next if !resourceIds.empty? && !resourceIds.include?(resourceId) 77: 78: templateFile = "#{@templateDir}/#{@date}/#{resourceId}_#{@date}.tji" 79: sheetFile = "#{@sheetDir}/#{@date}/#{resourceId}_#{@date}.tji" 80: if File.exist?(templateFile) 81: if File.exists?(sheetFile) 82: # If there are no recipients specified, we don't need to compile 83: # the summary. 84: unless @digestRecipients.empty? && @sheetRecipients.empty? 85: # Resource has submitted a time sheet 86: sheet = getResourceJournal(sheetFile) 87: summary += sprintf(@resourceIntro, resourceName) 88: summary += sheet + "\n----\n" 89: info("Adding report from #{resourceName} to summary") 90: 91: @sheetRecipients.each do |to| 92: sendRichTextEmail(to, sprintf(@resourceSheetSubject, @date), 93: sheet, nil, 94: "#{resourceName} <#{resourceEmail}>") 95: end 96: end 97: else 98: defaulterList << resource 99: # Resource did not submit a time sheet 100: info("Report from #{resourceId} is missing") 101: end 102: end 103: end 104: 105: unless defaulterList.empty? 106: # Prepend the defaulter list to the summary. 107: text = sprintf(@defaulterHeader, defaulterList.length) 108: defaulterList.each do |resource| 109: text += "* <nowiki>#{resource[1]}</nowiki>\n" 110: end 111: text += "\n----\n" 112: summary = text + summary 113: 114: # Create a file with the IDs of the resources who's reports are 115: # missing. 116: missingFile = "#{@sheetDir}/#{@date}/missing-reports" 117: begin 118: File.open(missingFile, 'w') do |f| 119: defaulterList.each { |resource| f.puts resource[0] } 120: end 121: rescue 122: error("Cannot write file with missing reports (#missingFile): #{$!}") 123: end 124: end 125: 126: # Send out the summary text to the list of digest recipients. 127: @digestRecipients.each do |to| 128: sendRichTextEmail(to, sprintf(@summarySubject, @date), summary) 129: end 130: 131: # If there is a reminder text defined, resend the template to those 132: # individuals that have not yet submitted their report yet. 133: if @reminderText && !@reminderText.empty? 134: defaulterList.each do |resource| 135: sendReminder(resource[0], resource[1], resource[2]) 136: end 137: end 138: end
# File lib/taskjuggler/TimeSheetSummary.rb, line 154 154: def getResourceJournal(sheetFile) 155: err = '' 156: status = nil 157: report = nil 158: warnings = nil 159: begin 160: # Save a copy of the sheet for debugging purposes. 161: command = [ '--unsafe', "--silent", "check-ts", @projectId, 162: sheetFile ] 163: res = stdIoWrapper do 164: Tj3Client.new.main(command) 165: end 166: if res.returnValue != 0 167: error("summary sheets: #{err}") 168: end 169: report = res.stdOut 170: warnings = res.stdErr 171: rescue 172: fatal("Cannot summarize sheet: #{$!}") 173: end 174: 175: report 176: end
# File lib/taskjuggler/TimeSheetSummary.rb, line 142 142: def sendReminder(id, name, email) 143: attachment = "#{@templateDir}/#{@date}/#{id}_#{@date}.tji" 144: unless File.exist?(attachment) 145: error("sendReportTemplates: " + 146: "#{@sheetType} sheet #{attachment} for #{name} not found") 147: end 148: 149: message = "Hello #{name}!\n\n#{@reminderText}" + File.read(attachment) 150: 151: sendEmail(email, sprintf(@reminderSubject, @date), message, attachment) 152: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.