/**
* ESUP-Portail Helpdesk - Copyright (c) 2004-2009 ESUP-Portail consortium.
*/
package org.esupportail.helpdesk.domain.reporting;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.esupportail.commons.services.authentication.AuthUtils;
import org.esupportail.commons.utils.strings.StringUtils;
import org.esupportail.helpdesk.domain.beans.Department;
import org.esupportail.helpdesk.domain.beans.DepartmentManager;
import org.esupportail.helpdesk.domain.beans.Ticket;
import org.esupportail.helpdesk.domain.beans.User;
import org.esupportail.helpdesk.exceptions.DepartmentManagerNotFoundException;
import org.esupportail.helpdesk.services.statistics.StatisticsUtils;
import org.esupportail.helpdesk.web.beans.ElapsedTimeI18nFormatter;
import org.esupportail.helpdesk.web.beans.PriorityI18nKeyProvider;
import org.esupportail.helpdesk.web.beans.PriorityStyleClassProvider;
import org.esupportail.helpdesk.web.beans.TicketStatusI18nKeyProvider;
/**
* The basic implementation of TicketReporter.
*/
public class TicketReporterImpl extends AbstractSenderFormatter implements TicketReporter {
/**
* A constant for reports results.
*/
private static final String REPORT_MANAGED = "REPORT_MANAGED";
/**
* A constant for reports results.
*/
private static final String REPORT_FREE = "REPORT_FREE";
/**
* A constant for reports results.
*/
private static final String REPORT_CATEGORY_MEMBER = "REPORT_CATEGORY_MEMBER";
/**
* A constant for reports results.
*/
private static final String REPORT_OTHER = "REPORT_OTHER";
/**
* Bean constructor.
*/
public TicketReporterImpl() {
super();
}
/**
* @param user
* @param noTicketTitleKey
* @param titleKey
* @param tickets
* @return the HTML content for a list of tickets.
*/
protected String getTicketsReportContent(
final User user,
final String noTicketTitleKey,
final String titleKey,
final List<Ticket> tickets) {
Locale locale = getDomainService().getUserStore().getUserLocale(user);
String result = "";
if (tickets.isEmpty()) {
result += getI18nService().getString(noTicketTitleKey, locale);
} else {
result += getI18nService().getString(titleKey, locale, new Integer(tickets.size()));
result += getI18nService().getString("EMAIL.TICKET_REPORT.TICKET_TABLE_HEADER", locale);
boolean alternateColor = false;
for (Ticket ticket : tickets) {
String trClass = "table-";
if (alternateColor) {
trClass += "odd";
} else {
trClass += "even";
}
String creationDepartmentLabel;
if (ticket.getCreationDepartment() == null) {
creationDepartmentLabel = "";
} else {
creationDepartmentLabel = StringUtils.escapeHtml(
ticket.getCreationDepartment().getLabel());
}
String status = getI18nService().getString(
TicketStatusI18nKeyProvider.getI18nKey(ticket.getStatus()), locale);
String priority = getI18nService().getString(
PriorityI18nKeyProvider.getI18nKey(
ticket.getEffectivePriorityLevel()), locale);
String managerDisplayName;
if (ticket.getManager() == null) {
managerDisplayName = " ";
} else {
managerDisplayName = StringUtils.escapeHtml(
ticket.getManager().getDisplayName());
}
long idleTime = (
System.currentTimeMillis() - ticket.getLastActionDate().getTime()) / 1000;
result += getI18nService().getString(
"EMAIL.TICKET_REPORT.TICKET_TABLE_ENTRY", locale,
new String [] {
trClass,
PriorityStyleClassProvider.getStyleClass(
ticket.getEffectivePriorityLevel()),
String.valueOf(ticket.getId()),
creationDepartmentLabel,
StringUtils.escapeHtml(ticket.getCategory().getLabel()),
StringUtils.escapeHtml(ticket.getLabel()),
status,
priority,
StringUtils.escapeHtml(
ticket.getOwner().getDisplayName()),
managerDisplayName,
getUrlBuilder().getTicketViewUrl(user.getAuthType(), ticket.getId()),
ElapsedTimeI18nFormatter.format(
getI18nService(), idleTime, locale),
});
alternateColor = !alternateColor;
}
result += getI18nService().getString("EMAIL.TICKET_REPORT.TICKET_TABLE_FOOTER", locale);
}
return result;
}
/**
* Compute tickets and manager to prepare reports.
* @param manager
* @param openedTickets
* @return a map with reporting results.
*/
protected Map<String, List<Ticket>> computeReporting(
final DepartmentManager manager,
final List<Ticket> openedTickets) {
User user = manager.getUser();
String reportType = manager.getReportType();
if (reportType == null) {
return null;
}
boolean reportFreeTickets = !(reportType.equals(DepartmentManager.REPORT_M)
|| reportType.equals(DepartmentManager.REPORT_MC));
boolean reportCategoryMemberTickets = !(reportType.equals(DepartmentManager.REPORT_M)
|| reportType.equals(DepartmentManager.REPORT_MF));
boolean reportOtherTickets =
reportType.equals(DepartmentManager.REPORT_MCFO)
|| reportType.equals(DepartmentManager.REPORT_MFCO);
boolean reportFreeBeforeCategoryMember =
reportType.equals(DepartmentManager.REPORT_MF)
|| reportType.equals(DepartmentManager.REPORT_MFC)
|| reportType.equals(DepartmentManager.REPORT_MFCO);
List<Ticket> managedTickets = new ArrayList<Ticket>();
List<Ticket> freeTickets = new ArrayList<Ticket>();
List<Ticket> categoryMemberTickets = new ArrayList<Ticket>();
List<Ticket> otherTickets = new ArrayList<Ticket>();
for (Ticket ticket : openedTickets) {
if (user.equals(ticket.getManager())) {
managedTickets.add(ticket);
} else if (reportFreeTickets || reportCategoryMemberTickets || reportOtherTickets) {
if (reportFreeBeforeCategoryMember) {
if (ticket.isFree()) {
freeTickets.add(ticket);
} else if (reportCategoryMemberTickets || reportOtherTickets) {
if (getDomainService().isCategoryMember(ticket.getCategory(), user)) {
categoryMemberTickets.add(ticket);
} else if (reportOtherTickets) {
otherTickets.add(ticket);
}
}
} else {
if (getDomainService().isCategoryMember(ticket.getCategory(), user)) {
categoryMemberTickets.add(ticket);
} else if (reportFreeTickets || reportOtherTickets) {
if (ticket.isFree()) {
freeTickets.add(ticket);
} else if (reportOtherTickets) {
otherTickets.add(ticket);
}
}
}
}
}
Map<String, List<Ticket>> computeReportingResults = new HashMap<String, List<Ticket>>();
computeReportingResults.put(REPORT_MANAGED, managedTickets);
if (reportFreeTickets) {
computeReportingResults.put(REPORT_FREE, freeTickets);
}
if (reportCategoryMemberTickets) {
computeReportingResults.put(REPORT_CATEGORY_MEMBER, categoryMemberTickets);
}
if (reportOtherTickets) {
computeReportingResults.put(REPORT_OTHER, otherTickets);
}
return computeReportingResults;
}
/**
* @param manager
* @param computeReportingResults
* @return the HTML content for a department.
*/
protected String getDepartmentReportContent(
final DepartmentManager manager,
final Map<String, List<Ticket>> computeReportingResults) {
User user = manager.getUser();
String htmlContent = "";
String reportType = manager.getReportType();
boolean reportFreeBeforeCategoryMember =
reportType.equals(DepartmentManager.REPORT_MF)
|| reportType.equals(DepartmentManager.REPORT_MFC)
|| reportType.equals(DepartmentManager.REPORT_MFCO);
List<Ticket> managedTickets = computeReportingResults.get(REPORT_MANAGED);
List<Ticket> freeTickets = computeReportingResults.get(REPORT_FREE);
List<Ticket> categoryMemberTickets = computeReportingResults.get(REPORT_CATEGORY_MEMBER);
List<Ticket> otherTickets = computeReportingResults.get(REPORT_OTHER);
htmlContent += getTicketsReportContent(user,
"EMAIL.TICKET_REPORT.NO_MANAGED_TICKET_SUBTITLE",
"EMAIL.TICKET_REPORT.MANAGED_TICKETS_SUBTITLE",
managedTickets);
if (freeTickets != null || categoryMemberTickets != null) {
if (reportFreeBeforeCategoryMember) {
if (freeTickets != null) {
htmlContent += getTicketsReportContent(user,
"EMAIL.TICKET_REPORT.NO_FREE_TICKET_SUBTITLE",
"EMAIL.TICKET_REPORT.FREE_TICKETS_SUBTITLE",
freeTickets);
}
if (categoryMemberTickets != null) {
htmlContent += getTicketsReportContent(user,
"EMAIL.TICKET_REPORT.NO_CATEGORY_MEMBER_TICKET_SUBTITLE",
"EMAIL.TICKET_REPORT.CATEGORY_MEMBER_TICKETS_SUBTITLE",
categoryMemberTickets);
}
} else {
if (categoryMemberTickets != null) {
htmlContent += getTicketsReportContent(user,
"EMAIL.TICKET_REPORT.NO_CATEGORY_MEMBER_TICKET_SUBTITLE",
"EMAIL.TICKET_REPORT.CATEGORY_MEMBER_TICKETS_SUBTITLE",
categoryMemberTickets);
}
if (freeTickets != null) {
htmlContent += getTicketsReportContent(user,
"EMAIL.TICKET_REPORT.NO_FREE_TICKET_SUBTITLE",
"EMAIL.TICKET_REPORT.FREE_TICKETS_SUBTITLE",
freeTickets);
}
}
}
if (otherTickets != null) {
htmlContent += getTicketsReportContent(user,
"EMAIL.TICKET_REPORT.NO_OTHER_TICKET_SUBTITLE",
"EMAIL.TICKET_REPORT.OTHER_TICKETS_SUBTITLE",
otherTickets);
}
return htmlContent;
}
/**
* @param manager
* @param computeReportingResults
* @return the HTML content for a department.
*/
protected String getStatsDepartmentReportContent(
final DepartmentManager manager,
final Map<String, List<Ticket>> computeReportingResults) {
User user = manager.getUser();
Locale locale = getDomainService().getUserStore().getUserLocale(user);
String htmlContent = "";
String reportType = manager.getReportType();
boolean reportFreeBeforeCategoryMember =
reportType.equals(DepartmentManager.REPORT_MF)
|| reportType.equals(DepartmentManager.REPORT_MFC)
|| reportType.equals(DepartmentManager.REPORT_MFCO);
List<Ticket> managedTickets = computeReportingResults.get(REPORT_MANAGED);
List<Ticket> freeTickets = computeReportingResults.get(REPORT_FREE);
List<Ticket> categoryMemberTickets = computeReportingResults.get(REPORT_CATEGORY_MEMBER);
List<Ticket> otherTickets = computeReportingResults.get(REPORT_OTHER);
htmlContent += getI18nService().getString("EMAIL.TICKET_REPORT.STATS.SUBTITLE", locale);
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.STATS.MANAGED_TICKETS_NUMBER", locale, managedTickets.size());
if (freeTickets != null || categoryMemberTickets != null) {
if (reportFreeBeforeCategoryMember) {
if (freeTickets != null) {
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.STATS.FREE_TICKETS_NUMBER",
locale, freeTickets.size());
}
if (categoryMemberTickets != null) {
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.STATS.CATEGORY_MEMBER_TICKETS_NUMBER",
locale, categoryMemberTickets.size());
}
} else {
if (categoryMemberTickets != null) {
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.STATS.CATEGORY_MEMBER_TICKETS_NUMBER",
locale, categoryMemberTickets.size());
}
if (freeTickets != null) {
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.STATS.FREE_TICKETS_NUMBER",
locale, freeTickets.size());
}
}
}
if (otherTickets != null) {
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.STATS.OTHER_TICKETS_NUMBER", locale, otherTickets.size());
}
return htmlContent;
}
/**
* Send a report to a department manager (for a department).
* @param manager
* @param openedTickets
*/
protected void sendTicketReport(
final DepartmentManager manager,
final List<Ticket> openedTickets) {
User user = manager.getUser();
Department department = manager.getDepartment();
Locale locale = getDomainService().getUserStore().getUserLocale(user);
String subject = getI18nService().getString(
"EMAIL.TICKET_REPORT.DEPARTMENT_SUBJECT", locale, department.getLabel());
String htmlContent = getI18nService().getString(
"EMAIL.TICKET_REPORT.DEPARTMENT_TITLE", locale, department.getLabel());
Map<String, List<Ticket>> computeReportingResults = computeReporting(manager, openedTickets);
htmlContent += "<table width=\"100%\"><tr><td valign=\"top\">";
htmlContent += getStatsDepartmentReportContent(manager, computeReportingResults);
htmlContent += getDepartmentReportContent(manager, computeReportingResults);
htmlContent += "</td><td valign=\"top\">";
htmlContent += getEmailQuickLinks(AuthUtils.NONE, user, null);
htmlContent += "</td></tr></table>";
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.FOOTER", locale,
getUrlBuilder().getManagerPreferencesUrl(user.getAuthType()),
getUrlBuilder().getToggleTicketReportsUrl(user.getAuthType()));
send(user, genMessageId(), subject, htmlContent);
}
/**
* Send a ticket report to a user (for one or more departments).
* @param hour
* @param weekend
* @param user
* @param openedTicketsMap
*/
protected void sendTicketReport(
final int hour,
final boolean weekend,
final User user,
final Map<Department, List<Ticket>> openedTicketsMap) {
Locale locale = getDomainService().getUserStore().getUserLocale(user);
String subject = getI18nService().getString(
"EMAIL.TICKET_REPORT.SUBJECT", locale);
String htmlContent = getI18nService().getString(
"EMAIL.TICKET_REPORT.ALL_TITLE", locale);
htmlContent += "<table width=\"100%\"><tr><td valign=\"top\">";
for (Department department : getDomainService().getDepartments()) {
try {
DepartmentManager manager = getDomainService().getDepartmentManager(department, user);
if (isReportingManager(hour, weekend, manager)) {
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.DEPARTMENT_HEADER",
locale, department.getLabel());
Map<String, List<Ticket>> computeReportingResults =
computeReporting(manager, openedTicketsMap.get(department));
htmlContent += getStatsDepartmentReportContent(
manager, computeReportingResults);
htmlContent += getDepartmentReportContent(manager, computeReportingResults);
}
} catch (DepartmentManagerNotFoundException e) {
// not managing this department
}
}
htmlContent += "</td><td valign=\"top\">";
htmlContent += getEmailQuickLinks(AuthUtils.NONE, user, null);
htmlContent += "</td></tr></table>";
htmlContent += getI18nService().getString(
"EMAIL.TICKET_REPORT.FOOTER", locale,
getUrlBuilder().getManagerPreferencesUrl(user.getAuthType()),
getUrlBuilder().getToggleTicketReportsUrl(user.getAuthType()));
send(user, genMessageId(), subject, htmlContent);
}
/**
* @param hour
* @param weekend
* @param manager
* @return true if the manager receives reports for the given hour.
*/
protected boolean isReportingManager(
final int hour,
final boolean weekend,
final DepartmentManager manager) {
if (!manager.getUser().getReceiveTicketReports()) {
return false;
}
if (weekend && !manager.getReportWeekend()) {
return false;
}
if (manager.getReportType() == null) {
return false;
}
return hour == manager.getReportTime1() || hour == manager.getReportTime2();
}
/**
* @see org.esupportail.helpdesk.domain.reporting.TicketReporter#sendTicketReport(org.esupportail.helpdesk.domain.beans.DepartmentManager)
*/
@Override
public void sendTicketReport(
final DepartmentManager manager) {
sendTicketReport(manager, getDomainService().getOpenedTicketsByLastActionDate(manager.getDepartment()));
}
/**
* Send ticket reports for an hour.
* @param hour
* @param weekend
*/
protected void sendTicketReports(final int hour, final boolean weekend) {
List<User> users = new ArrayList<User>();
Map<Department, List<Ticket>> openedTicketsMap = new HashMap<Department, List<Ticket>>();
for (Department department : getDomainService().getDepartments()) {
for (DepartmentManager manager : getDomainService().getDepartmentManagers(department)) {
boolean userFound = false;
if (isReportingManager(hour, weekend, manager)) {
userFound = true;
if (!users.contains(manager.getUser())) {
users.add(manager.getUser());
}
}
if (userFound) {
openedTicketsMap.put(
department, getDomainService().getOpenedTicketsByLastActionDate(department));
}
}
}
for (User user : users) {
if (user.getReceiveTicketReportsAllInOne()) {
sendTicketReport(hour, weekend, user, openedTicketsMap);
} else {
for (Department department : getDomainService().getDepartments()) {
try {
DepartmentManager manager = getDomainService().getDepartmentManager(department, user);
if (isReportingManager(hour, weekend, manager)) {
sendTicketReport(manager, openedTicketsMap.get(department));
}
} catch (DepartmentManagerNotFoundException e) {
// not managing this department
}
}
}
}
}
/**
* @see org.esupportail.helpdesk.domain.reporting.TicketReporter#sendTicketReports()
*/
@Override
public void sendTicketReports() {
Timestamp now = new Timestamp(System.currentTimeMillis());
int hour = StatisticsUtils.getHour(now);
int dow = StatisticsUtils.getDayOfWeek(now);
boolean weekend = dow == Calendar.SATURDAY || dow == Calendar.SUNDAY;
sendTicketReports(hour, weekend);
}
}