/** * */ package org.msh.tb.cases; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Transactional; import org.jboss.seam.annotations.security.Restrict; import org.jboss.seam.core.Events; import org.jboss.seam.international.Messages; import org.jboss.seam.security.Identity; import org.msh.tb.EntityHomeEx; import org.msh.tb.MsgDispatcher; import org.msh.tb.application.mail.MailService; import org.msh.tb.entities.*; import org.msh.tb.entities.enums.UserView; import javax.persistence.EntityManager; import java.util.Date; import java.util.List; /** * Services to handle case issues and its follow-up * * @author Ricardo Memoria * */ @Name("caseIssueHome") public class CaseIssueHome extends EntityHomeEx { private static final long serialVersionUID = 5972585923087719473L; public enum Action { NEWISSUE, READING_FOLLOWUPS, NEWFOLLOWUP, DEL_ISSUE, DEL_FOLLOWUP, CLOSE_ISSUE, REOPEN_ISSUE; } @In EntityManager entityManager; @In CaseHome caseHome; private List list; private Integer count; private IssueFollowup followup; private Action action; private Integer followupId; /** * Create a new issue for the current case and logged user * @return String value "issue-created" if successfully created */ @Restrict("#{s:hasRole('NEW_ISSUE')}") @Transactional public String createNewIssue() { Issue issue = getInstance(); TbCase tbcase = caseHome.getInstance(); issue.setCreationDate(new Date()); issue.setTbcase(tbcase); issue.setUser(getUser()); issue.setClosed(false); issue.setUser(getUser()); issue.setUnit(getUserWorkspace().getTbunit()); super.persist(); caseHome.updateCaseTags(); action = Action.NEWISSUE; Events.instance().raiseEvent(CaseEvent.NEW_ISSUE, issue); return "issue-created"; } /** * Return the string to be displayed with the status of the issue * @param issue * @return String value */ public String getDisplayStatus(Issue issue) { if (issue.isClosed()) { return Messages.instance().get("cases.closed"); } if (issue.getAnswerDate() == null) { return Messages.instance().get("Issue.new"); } return Messages.instance().get("Issue.answered"); } /** {@inheritDoc} */ @Override @Transactional public String remove() { if (!isManaged()) throw new RuntimeException("Issue is not informed"); // check permission // is not the owner of the user? if (isAllowedToCloseOrDelete(getInstance())) { throw new SecurityException("User is not authorized to delete this issue"); } return super.remove(); } /** * Post a new follow up for the given issue using the information * in the {@link CaseIssueHome#followup} variable * @return true if successfully saved */ public boolean postFollowup() { if (followup == null) return false; if (!isAllowedToAnswer(getInstance())) throw new SecurityException("You don't have permission to post an answer"); // prepare and save the follow up followup.setFollowupDate(new Date()); followup.setIssue(getInstance()); followup.setUser(getUser()); followup.setUnit(getUserWorkspace().getTbunit()); entityManager.persist(followup); // save the follow up date getInstance().setAnswerDate(followup.getFollowupDate()); persist(); caseHome.updateCaseTags(); action = Action.NEWFOLLOWUP; return true; } /** * Notify a new issue by e-mail to the users in charge of responding it */ // protected void notifyIssueByEmail() { // TbCase tbcase = caseHome.getInstance(); // Issue issue = getInstance(); // Tbunit unit = tbcase.getOwnerUnit(); // // List lst = msgDispatcher.getUsersByRoleAndUnit("CASE_DATA", unit); // // MailService srv = MailService.instance(); // // // String code = unit.getAdminUnit().getCode(); // String s = ""; // String join = ""; // while (code != null) { // s += join + "'" + code + "'"; // code = AdministrativeUnit.getParentCode(code); // join = ","; // } // // String hql = "select u.user from UserWorkspace u where u.profile.id in " + // "(select distinct p.id " + // "from UserProfile p join p.permissions perm " + // "where perm.userRole.name like :rolename " + // "and p.workspace.id = #{defaultWorkspace.id} " + // "and ((perm.userRole.changeable = true and perm.canChange = true) or (perm.userRole.changeable = false and perm.canExecute = true))" + // "and (u.view = :viewcountry or (u.view = :viewunit and u.tbunit.id = :unitid) " + // "or (u.view = :viewadm and u.tbunit.adminUnit.code in (" + s + "))))"; // // //Verificar a melhor forma de selecionar os usuarios // List users = (List) entityManager // .createQuery(hql) // .setParameter("viewcountry", UserView.COUNTRY) // .setParameter("viewunit", UserView.TBUNIT) // .setParameter("unitid", unit.getId()) // .setParameter("viewadm", UserView.ADMINUNIT) // .setParameter("rolename", "CASE_DATA") // .getResultList(); // // for (UserWorkspace userW: users) { // srv.addComponent("user", userW.getUser()); // srv.addComponent("issue", issue); // srv.addComponent("tbcase", tbcase); // srv.addComponent("isAnswer", issue.isClosed()); // srv.addMessageToQueue("/mail/casetransfered.xhtml", userW.getUser().getTimeZone(), userW.getUser().getLanguage(), userW.getUser(), true); // } // // srv.dispatchQueue(); // } /** * Close the current issue */ @Transactional public void closeIssue() { if ((!isManaged()) || (getInstance().isClosed())) throw new RuntimeException("Issue is not informed or it's already closed: " + getId()); // check permission // is not the owner of the user? if (!isAllowedToCloseOrDelete(getInstance())) { throw new SecurityException("User is not authorized to close this issue"); } getInstance().setClosed(true); persist(); caseHome.updateCaseTags(); action = Action.CLOSE_ISSUE; } /** * Check if user is allowed to close the given issue * @param issue instance of the {@link Issue} class * @return true if user can close the issue */ public boolean isAllowedToCloseOrDelete(Issue issue) { if (issue == null) return false; // is not the owner of the user? if (getUser().getId().equals(issue.getUser().getId())) return true; return Identity.instance().hasRole("CLOSEDEL_ISSUE"); } /** * Check if user is allowed to close the given issue * @param issue instance of the {@link Issue} class * @return true if user can close the issue */ public boolean isAllowedToAnswer(Issue issue) { if (issue == null) { return false; } // is not the owner of the user? if (getUser().getId().equals(issue.getUser().getId())) { return true; } return Identity.instance().hasRole("ANSWER_ISSUE"); } /** * Reopen a closed issue */ @Transactional public void reopenIssue() { if ((!isManaged()) || (!getInstance().isClosed())) throw new RuntimeException("Issue is not informed or it's already open: " + getId()); // check permission // is not the owner of the user? if (!isAllowedToCloseOrDelete(getInstance())) { throw new SecurityException("User is not authorized to open this issue"); } getInstance().setClosed(false); persist(); caseHome.updateCaseTags(); action = Action.REOPEN_ISSUE; } /** * Return the number of open issues for a given case * @return integer value */ public int getOpenIssuesCount() { if (count == null) { count = ((Long)entityManager .createQuery("select count(*) from Issue where tbcase.id = #{caseHome.id}") .getSingleResult()).intValue(); } return count; } /** * Called to indicate that the follow-ups of the current issue will be rendered in the client side */ public void loadFollowups() { action = Action.READING_FOLLOWUPS; } /** * Return the instance of the issue follow up being edited * @return instance of the {@link IssueFollowup} class */ public IssueFollowup getFollowup() { if (followup == null) followup = new IssueFollowup(); return followup; } /** * Return list of issues of a case * @return list of objects of class {@link Issue} */ public List getList() { if (list == null) createList(); return list; } /** * Create the list of issues of a given case */ protected void createList() { list = entityManager.createQuery("from Issue where tbcase.id = #{caseHome.id} order by creationDate") .getResultList(); } /** * Delete the follow-up specified by the followupId property */ public void deleteFollowup() { if (followupId == null) return; followup = entityManager.find(IssueFollowup.class, followupId); entityManager.remove(followup); caseHome.updateCaseTags(); action = Action.DEL_FOLLOWUP; } /** * Delete the current issue */ public void deleteIssue() { super.remove(); action = Action.DEL_ISSUE; } /** * @return the action */ public Action getAction() { return action; } /** * @return the followupId */ public Integer getFollowupId() { return followupId; } /** * @param followupId the followupId to set */ public void setFollowupId(Integer followupId) { this.followupId = followupId; } }