package fi.arcusys.koku.av; import static fi.arcusys.koku.util.Constants.DATE; import static fi.arcusys.koku.util.Constants.TASK_TYPE_APPOINTMENT_INBOX_EMPLOYEE; import static fi.arcusys.koku.util.Constants.TASK_TYPE_APPOINTMENT_RESPONSE_EMPLOYEE; import static fi.arcusys.koku.util.Constants.TIME; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.TimeZone; import org.apache.log4j.Logger; import org.springframework.context.NoSuchMessageException; import fi.arcusys.koku.AbstractHandle; import fi.arcusys.koku.av.EmployeeAppointment.UserWithTarget; import fi.arcusys.koku.av.employeeservice.Appointment; import fi.arcusys.koku.av.employeeservice.Appointment.AcceptedSlots; import fi.arcusys.koku.av.employeeservice.Appointment.AcceptedSlots.Entry; import fi.arcusys.koku.av.employeeservice.AppointmentCriteria; import fi.arcusys.koku.av.employeeservice.AppointmentReceipientTO; import fi.arcusys.koku.av.employeeservice.AppointmentSlot; import fi.arcusys.koku.av.employeeservice.AppointmentSummary; import fi.arcusys.koku.av.employeeservice.AppointmentSummaryStatus; import fi.arcusys.koku.av.employeeservice.AppointmentUserRejected; import fi.arcusys.koku.av.employeeservice.User; import fi.arcusys.koku.exceptions.KokuServiceException; import fi.arcusys.koku.users.KokuUser; import fi.arcusys.koku.util.MessageUtil; /** * Handles the appointments for employee * @author Jinhua Chen * Aug 22, 2011 */ public class AvEmployeeServiceHandle extends AbstractHandle { private static final Logger LOG = Logger.getLogger(AvEmployeeServiceHandle.class); private AvEmployeeService aes; /** * Constructor and initialization */ public AvEmployeeServiceHandle() { aes = new AvEmployeeService(); } /** * Gets summary appointments * @param user user * @param startNum start index of appointment * @param maxNum maximum number of appointments * @param taskType task type requested * @return a list of summary appointments */ public List<KokuAppointment> getAppointments(String userId, int startNum, int maxNum, String taskType, String keyword) throws KokuServiceException { String targetPersonSsn = keyword; if(taskType.equals(TASK_TYPE_APPOINTMENT_INBOX_EMPLOYEE)) { return getCreatedAppointments(userId, targetPersonSsn, startNum, maxNum); } else if(taskType.equals(TASK_TYPE_APPOINTMENT_RESPONSE_EMPLOYEE)) { return getProcessedAppointment(userId, targetPersonSsn, startNum, maxNum); } else { return new ArrayList<KokuAppointment>(); } } public List<KokuAppointment> getCreatedAppointments(String userId, String targetPersonSsn, int startNum, int maxNum) throws KokuServiceException { return getAppointmentList(aes.getCreatedAppointments(userId, createAppointmentCriteria(targetPersonSsn), startNum, maxNum)); } public List<KokuAppointment> getProcessedAppointment(String userId, String targetPersonSsn, int startNum, int maxNum) throws KokuServiceException { return getAppointmentList(aes.getProcessedAppointments(userId, createAppointmentCriteria(targetPersonSsn), startNum, maxNum)); } private AppointmentCriteria createAppointmentCriteria(String targetPersonSsn) { AppointmentCriteria criteria = null; if (targetPersonSsn != null && !targetPersonSsn.trim().isEmpty()) { criteria = new AppointmentCriteria(); criteria.setTargetPersonHetu(targetPersonSsn); } return criteria; } /** * Gets summary appointments * @param user user * @param startNum start index of appointment * @param maxNum maximum number of appointments * @param taskType task type requested * @return a list of summary appointments */ private List<KokuAppointment> getAppointmentList(List<AppointmentSummary> appSummaryList) { List<KokuAppointment> appList = new ArrayList<KokuAppointment>(); for (AppointmentSummary appSummary : appSummaryList) { KokuAppointment kokuAppointment = new KokuAppointment(); kokuAppointment.setAppointmentId(appSummary.getAppointmentId()); kokuAppointment.setSenderUser(new KokuUser(appSummary.getSenderUserInfo())); // KOKU-1234 - 'Tapaamiset'-listauksiin tarvitaan tieto kenelle viesti on lähetetty (Työntekijän puoli) kokuAppointment.setReceivingUser(new KokuUser()); kokuAppointment.setSubject(appSummary.getSubject()); kokuAppointment.setDescription(appSummary.getDescription()); kokuAppointment.setStatus(localizeActionRequestStatus(appSummary.getStatus())); appList.add(kokuAppointment); } return appList; } /** * Gets detailed appointment which is used to be presented * @param appointmentId appointment id * @return detailed appointment for employee */ public EmployeeAppointment getAppointmentById(String appointmentId) throws KokuServiceException { long appId = 0; try { appId = (long) Long.parseLong(appointmentId); } catch (NumberFormatException nfe) { throw new KokuServiceException("Invalid appointmentId. AppointmentId: '"+appointmentId+"'", nfe); } EmployeeAppointment empAppointment = new EmployeeAppointment(); Appointment appointment = aes.getAppointmentById(appId); empAppointment.setAppointmentId(appointment.getAppointmentId()); empAppointment.setSenderUser(new KokuUser(appointment.getSenderUserInfo())); empAppointment.setSubject(appointment.getSubject()); empAppointment.setDescription(appointment.getDescription()); empAppointment.setStatus(localizeActionRequestStatus(appointment.getStatus())); empAppointment.setAcceptedSlots(appointment.getAcceptedSlots()); empAppointment.getRecipients().addAll(appointment.getRecipients()); empAppointment.setCancellationComment(appointment.getCancelComment()); empAppointment.getUsersRejected().addAll(convertUserRejectedToKokuUserRejected(appointment.getUsersRejectedWithComments())); empAppointment.getRejectedUsers().addAll(formatRejectedUsers(getUsers(appointment.getUsersRejectedWithComments()), appointment.getRecipients())); empAppointment.getUnrespondedUsers().addAll(calcUnrespondedUsers(appointment)); List<Slot> allSlots = formatSlots(appointment.getSlots(), appointment.getAcceptedSlots(), appointment.getRecipients()); setSlots(empAppointment, allSlots); return empAppointment; } private List<KokuAppointmentUserRejected> convertUserRejectedToKokuUserRejected(List<AppointmentUserRejected> rejectedUsers) { if (rejectedUsers == null) { return new ArrayList<KokuAppointmentUserRejected>(); } List<KokuAppointmentUserRejected> list = new ArrayList<KokuAppointmentUserRejected>(); for (AppointmentUserRejected rejectedUser : rejectedUsers ) { list.add(new KokuAppointmentUserRejected(rejectedUser)); } return list; } /** * Gets the total number of appointments * @param user user * @param taskType task type requested * @return the number of appointments */ public int getTotalAppointmentsNum(String userId, String taskType, String keyword) throws KokuServiceException { if(taskType.equals(TASK_TYPE_APPOINTMENT_INBOX_EMPLOYEE)) { // for employee return aes.getTotalCreatedAppointmentNum(userId, createAppointmentCriteria(keyword)); } else if(taskType.equals(TASK_TYPE_APPOINTMENT_RESPONSE_EMPLOYEE)) { return aes.getTotalProcessedAppointments(userId, createAppointmentCriteria(keyword)); } else { return 0; } } /** * Generates slot object for client side user interface * @param appSlots AppointmentSlot * @param acceptedSlots AcceptedSlots * @param recipients AppointmentReceipientTO * @return a list of slots */ private List<Slot> formatSlots(List<AppointmentSlot> appSlots, AcceptedSlots acceptedSlots, List<AppointmentReceipientTO> recipients) { List<Slot> slots = new ArrayList<Slot>(); /* Why GMT0? See issue KOKU-1210 - Ajanvarauksessa tapaamisten ajat muuttuvat */ final TimeZone timeZone = TimeZone.getTimeZone("GMT+0:00"); for (AppointmentSlot appSlot : appSlots) { Slot slot = new Slot(); slot.setSlotNumber(appSlot.getSlotNumber()); slot.setAppointmentDate(MessageUtil.formatDateByString(appSlot.getAppointmentDate(), DATE, timeZone)); slot.setStartTime(MessageUtil.formatDateByString(appSlot.getStartTime(), TIME, timeZone)); slot.setEndTime(MessageUtil.formatDateByString(appSlot.getEndTime(), TIME, timeZone)); slot.setLocation(appSlot.getLocation()); slot.setComment(appSlot.getComment()); slots.add(slot); } // go through the accepted slots and set related information (O²) for (Entry entry : acceptedSlots.getEntry()) { for (Slot slot : slots) { if(slot.getSlotNumber() == entry.getKey()) { slot.setApproved(true); KokuUser targetPerson = new KokuUser(entry.getValue()); slot.setTargetPersonUser(targetPerson); slot.getRecipientUsers().addAll(mapRecipients(targetPerson, recipients)); break; } } } return slots; } /** * Finds the approved slots and unapproved slots and sets them afterwards * @param empAppointment EmployeeAppointment * @param slots all slots */ private void setSlots(EmployeeAppointment empAppointment, List<Slot> slots) { List<Slot> approvedSlots = new ArrayList<Slot>(); List<Slot> unapprovedSlots = new ArrayList<Slot>(); Slot slot; Iterator<Slot> it = slots.iterator(); while(it.hasNext()) { slot = it.next(); if (slot.getApproved() == true) { approvedSlots.add(slot); } else { unapprovedSlots.add(slot); } } empAppointment.getApprovedSlots().addAll(approvedSlots); empAppointment.getUnapprovedSlots().addAll(unapprovedSlots); } /** * Maps the recipients with the given targetPerson and convert the * recipients list to string * * @param targetPerson target person * @param recipients AppointmentReceipientTO recipients * @return recipients string corresponding target person */ private List<KokuUser> mapRecipients(final KokuUser targetPerson, List<AppointmentReceipientTO> recipients) { final List<KokuUser> kokuRecipients = new ArrayList<KokuUser>(); for (AppointmentReceipientTO appReceipient : recipients) { KokuUser appRecepientUser = new KokuUser(appReceipient.getTargetPersonUserInfo()); if (appRecepientUser.equals(targetPerson)) { for (User receipientUser : appReceipient.getReceipientUserInfos()) { kokuRecipients.add(new KokuUser(receipientUser)); } break; } } return kokuRecipients; } /** * Formats the rejected users with corresponding target person * * @param userRejected user who rejected slot * @param recipients recipients list * @return a list of rejected users */ private List<UserWithTarget> formatRejectedUsers(List<KokuUser> userRejected, List<AppointmentReceipientTO> recipients) { List<UserWithTarget> rejectedUsers = new ArrayList<UserWithTarget>(); for(KokuUser rejectedUser : userRejected) { List<KokuUser> recipientsList = mapRecipients(rejectedUser, recipients); UserWithTarget user = new UserWithTarget(); user.setTargetPersonUser(rejectedUser); user.getRecipientUsers().addAll(recipientsList); rejectedUsers.add(user); } return rejectedUsers; } private List<UserWithTarget> calcUnrespondedUsers(Appointment appointment) { List<UserWithTarget> unrespondedUsers = new ArrayList<UserWithTarget>(); List<AppointmentUserRejected> userRejected = appointment.getUsersRejectedWithComments(); AcceptedSlots acceptedSlots = appointment.getAcceptedSlots(); for (AppointmentReceipientTO app : appointment.getRecipients()) { KokuUser targetPerson = new KokuUser(app.getTargetPersonUserInfo()); if(!hasTargetPerson(targetPerson, acceptedSlots, userRejected)) { UserWithTarget user = new UserWithTarget(); user.setTargetPersonUser(targetPerson); user.setTargetPersonUser(new KokuUser(app.getTargetPersonUserInfo())); for (User recipientUser : app.getReceipientUserInfos()) { user.getRecipientUsers().add(new KokuUser(recipientUser)); } unrespondedUsers.add(user); } } return unrespondedUsers; } /** * @param users * @return */ private List<KokuUser> getUsers(List<AppointmentUserRejected> users) { if (users == null || users.isEmpty()) { return Collections.emptyList(); } final List<KokuUser> result = new ArrayList<KokuUser>(users.size()); for (final AppointmentUserRejected user : users) { result.add(new KokuUser(user.getUserInfo())); } return result; } /** * Checks that the targetPeson exists or not * @param targetPerson * @param acceptedSlots * @param userRejected * @return true or false */ private boolean hasTargetPerson(final KokuUser targetPerson, final AcceptedSlots acceptedSlots, final List<AppointmentUserRejected> userRejected) { for (Entry entry : acceptedSlots.getEntry()) { KokuUser target = new KokuUser(entry.getValue()); if(target.equals(targetPerson)) { return true; } } for (AppointmentUserRejected user : userRejected) { KokuUser target = new KokuUser(user.getUserInfo()); if(target.equals(targetPerson)) { return true; } } return false; } /** * Cancels appointment * @param appointmentIdStr * @param comment */ public void cancelAppointments(long appId, String comment) throws KokuServiceException { aes.cancelAppointment(appId, comment); } private String localizeActionRequestStatus(AppointmentSummaryStatus appointmentStatus) { if (getMessageSource() == null) { LOG.warn(MESSAGE_SOURCE_MISSING); return appointmentStatus.toString(); } Locale locale = MessageUtil.getLocale(); try { switch (appointmentStatus) { case APPROVED: return getMessageSource().getMessage("AppointmentStatus.Approved", null, locale); case CANCELLED: return getMessageSource().getMessage("AppointmentStatus.Cancelled", null, locale); case CREATED: return getMessageSource().getMessage("AppointmentStatus.Created", null, locale); default: return appointmentStatus.toString(); } } catch (NoSuchMessageException nsme) { LOG.warn("Coulnd't find localized message for '" +appointmentStatus +"'. Localization doesn't work properly"); return appointmentStatus.toString(); } } }