org.cgiar.ccafs.ap.action.projects.ProjectPartnersAction.java Source code

Java tutorial

Introduction

Here is the source code for org.cgiar.ccafs.ap.action.projects.ProjectPartnersAction.java

Source

/*****************************************************************
 * This file is part of CCAFS Planning and Reporting Platform. CCAFS P&R is free software: you can redistribute it
 * and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or at your option) any later version. CCAFS P&R is distributed in the hope that it
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU
 * General Public License along with CCAFS P&R. If not, see <http://www.gnu.org/licenses/>.
 *****************************************************************/
package org.cgiar.ccafs.ap.action.projects;

import org.cgiar.ccafs.ap.action.BaseAction;
import org.cgiar.ccafs.ap.config.APConstants;
import org.cgiar.ccafs.ap.data.manager.ActivityManager;
import org.cgiar.ccafs.ap.data.manager.BudgetManager;
import org.cgiar.ccafs.ap.data.manager.DeliverableManager;
import org.cgiar.ccafs.ap.data.manager.DeliverablePartnerManager;
import org.cgiar.ccafs.ap.data.manager.HistoryManager;
import org.cgiar.ccafs.ap.data.manager.InstitutionManager;
import org.cgiar.ccafs.ap.data.manager.LocationManager;
import org.cgiar.ccafs.ap.data.manager.ProjectManager;
import org.cgiar.ccafs.ap.data.manager.ProjectPartnerManager;
import org.cgiar.ccafs.ap.data.manager.RoleManager;
import org.cgiar.ccafs.ap.data.manager.UserManager;
import org.cgiar.ccafs.ap.data.model.Activity;
import org.cgiar.ccafs.ap.data.model.Country;
import org.cgiar.ccafs.ap.data.model.Deliverable;
import org.cgiar.ccafs.ap.data.model.Institution;
import org.cgiar.ccafs.ap.data.model.InstitutionType;
import org.cgiar.ccafs.ap.data.model.PartnerPerson;
import org.cgiar.ccafs.ap.data.model.Project;
import org.cgiar.ccafs.ap.data.model.ProjectPartner;
import org.cgiar.ccafs.ap.data.model.Role;
import org.cgiar.ccafs.ap.data.model.User;
import org.cgiar.ccafs.ap.validation.projects.ProjectPartnersValidator;
import org.cgiar.ccafs.utils.APConfig;
import org.cgiar.ccafs.utils.SendMail;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.inject.Inject;
import com.opensymphony.xwork2.ActionContext;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class is used to manage the Project Partners section in the planning step.
 * 
 * @author Hernn Carvajal
 * @author Hctor Fabio Tobn R. - CIAT/CCAFS
 * @author Carlos Alberto Martnez M.
 * @author Christian David Garcia
 */
public class ProjectPartnersAction extends BaseAction {

    private static final long serialVersionUID = 5839536146328620421L;
    public static Logger LOG = LoggerFactory.getLogger(ProjectPartnersAction.class);

    // Managers
    private ProjectPartnerManager projectPartnerManager;
    private InstitutionManager institutionManager;
    private LocationManager locationManager;
    private ProjectManager projectManager;
    private UserManager userManager;
    private RoleManager roleManager;
    private ActivityManager activityManager;
    private DeliverableManager deliverableManager;
    private HistoryManager historyManager;
    private BudgetManager budgetManager;

    private String overrall;
    // private BudgetManager budgetManager;
    // private DeliverablePartnerManager deliverablePartnerManager;
    // private DeliverableManager deliverableManager;

    // Validator
    private ProjectPartnersValidator projectPartnersValidator;

    // Model for the back-end
    private int projectID;

    private Project previousProject;

    private Project project;
    // Model for the view
    private List<InstitutionType> intitutionTypes;
    private Map<String, String> partnerPersonTypes; // List of partner person types (CP, PL, PC).

    private List<Country> countries;
    private List<Institution> allInstitutions; // Is used to list all the partner institutions that have the system.
    private List<Institution> allPPAInstitutions; // Is used to list all the PPA partners institutions
    private List<ProjectPartner> projectPPAPartners; // Is used to list all the PPA partners that belongs to the project.
    private List<User> allUsers; // will be used to list all the project leaders that have the system.
    // Util
    private SendMail sendMail;

    @Inject
    public ProjectPartnersAction(APConfig config, ProjectPartnerManager projectPartnerManager,
            InstitutionManager institutionManager, LocationManager locationManager, ProjectManager projectManager,
            UserManager userManager, BudgetManager budgetManager, ProjectPartnersValidator projectPartnersValidator,
            DeliverablePartnerManager deliverablePartnerManager, DeliverableManager deliverableManager,
            ActivityManager activityManager, RoleManager roleManager, SendMail sendMail,
            HistoryManager historyManager) {
        super(config);
        this.projectPartnerManager = projectPartnerManager;
        this.institutionManager = institutionManager;
        this.locationManager = locationManager;
        this.projectManager = projectManager;
        this.userManager = userManager;
        this.activityManager = activityManager;
        this.deliverableManager = deliverableManager;
        this.projectPartnersValidator = projectPartnersValidator;
        this.roleManager = roleManager;
        this.sendMail = sendMail;
        this.historyManager = historyManager;
        this.budgetManager = budgetManager;
        // this.deliverablePartnerManager = deliverablePartnerManager;
    }

    public List<Activity> getActivitiesLedByUser(int userID) {
        return activityManager.getProjectActivitiesLedByUser(projectID, userID);
    }

    // private List<Institution> contributionPartners; // this would get the partners contributing to others

    public List<Institution> getAllInstitutions() {
        return allInstitutions;
    }

    public List<Institution> getAllPPAInstitutions() {
        return allPPAInstitutions;
    }

    public List<Institution> getAllPPAPartners() {
        return allPPAInstitutions;
    }

    public List<User> getAllUsers() {
        return allUsers;
    }

    // private boolean deletePartner(ProjectPartner partnerToDelete, List<ProjectPartner> partners) {
    //
    // // Before deleting the project partner, we have to delete the deliverable partner contributions.
    //
    // List<Deliverable> deliverables = deliverableManager.getDeliverablesByProjectPartnerID(partnerToDelete.getId());
    //
    // for (Deliverable deliverable : deliverables) {
    // // Deleting partner in case it is selected in the responsible.
    // if (deliverable.getResponsiblePartner() != null
    // && deliverable.getResponsiblePartner().getPartner().equals(partnerToDelete)) {
    // deliverablePartnerManager.deleteDeliverablePartner(deliverable.getResponsiblePartner().getId(),
    // this.getCurrentUser(), this.getJustification());
    // }
    // // Deleting partner in case it is selected in other parter contributions.
    // for (DeliverablePartner deliverablePartner : deliverable.getOtherPartners()) {
    // if (deliverablePartner.getPartner().equals(partnerToDelete)) {
    // deliverablePartnerManager.deleteDeliverablePartner(deliverablePartner.getId(), this.getCurrentUser(),
    // this.getJustification());
    // }
    // }
    // }
    //
    // // Deleting all the project partners contributions.
    //
    // // we need to validate that it is the only institution that is entered in the system.
    // boolean lastInstitution = institutionManager.validateLastOneInstitution(partnerToDelete.getId());
    // // If the institution is the last one, we need to get all the project partners that will be affected.
    // if (lastInstitution) {
    // for (ProjectPartner partner : partners) {
    // // Looping the list of "contribute institutions".
    // // if (partner.getContributeInstitutions() != null) {
    // // for (Institution institution : partner.getContributeInstitutions()) {
    // // if (institution.equals(partnerToDelete.getInstitution())) {
    // // // delete the project partner contribution
    // // institutionManager.deleteProjectPartnerContributeInstitution(partner, partnerToDelete.getInstitution());
    // // break; // stop the loop.
    // // }
    // // }
    // // }
    // }
    // }
    //
    // // Now it is ok to delete the current project partner.
    // boolean deleted = projectPartnerManager.z_old_deleteProjectPartner(partnerToDelete.getId(), this.getCurrentUser(),
    // this.getJustification());
    // return deleted;
    // }

    public List<Country> getCountries() {
        return countries;
    }

    public List<Deliverable> getDeliverablesLedByUser(int userID) {
        return deliverableManager.getProjectDeliverablesLedByUser(projectID, userID);
    }

    public List<InstitutionType> getInstitutionTypes() {
        return intitutionTypes;
    }

    public String getOverrall() {
        return overrall;
    }

    public Map<String, String> getPartnerPersonTypes() {
        return partnerPersonTypes;
    }

    public Project getProject() {
        return project;
    }

    public int getProjectID() {
        return projectID;
    }

    public String getProjectRequest() {
        return APConstants.PROJECT_REQUEST_ID;
    }

    public String getTypeProjectContactPerson() {
        return APConstants.PROJECT_PARTNER_CP;
    }

    public String getTypeProjectCoordinator() {
        return APConstants.PROJECT_PARTNER_PC;
    }

    public String getTypeProjectLeader() {
        return APConstants.PROJECT_PARTNER_PL;
    }

    public boolean isNewProject() {
        return project.isNew(config.getCurrentPlanningStartDate());
    }

    @Override
    public String next() {
        String result = this.save();
        if (result.equals(BaseAction.SUCCESS)) {
            return BaseAction.NEXT;
        } else {
            return result;
        }
    }

    /**
     * This method will validate if the user is deactivated. If so, it will send an email indicating the credentials to
     * access.
     * 
     * @param leader is a PartnerPerson object that could be the leader or the coordinator.
     */
    private void notifyNewUserCreated(User user) {

        if (!user.isActive()) {

            user.setActive(true);
            // Building the Email message:
            StringBuilder message = new StringBuilder();
            message.append(this.getText("planning.manageUsers.email.dear", new String[] { user.getFirstName() }));
            message.append(this.getText("planning.manageUsers.email.newUser.part1"));
            message.append(this.getText("planning.manageUsers.email.newUser.part2"));

            String password = this.getText("planning.manageUsers.email.outlookPassword");
            if (!user.isCcafsUser()) {
                // Generating a random password.
                password = RandomStringUtils.randomNumeric(6);
                // Applying the password to the user.
                user.setMD5Password(password);
            }
            message.append(this.getText("planning.manageUsers.email.newUser.part3",
                    new String[] { config.getBaseUrl(), user.getEmail(), password }));
            message.append(this.getText("planning.manageUsers.email.support"));
            message.append(this.getText("planning.manageUsers.email.bye"));

            // Saving the new user configuration.
            userManager.saveUser(user, this.getCurrentUser());

            String toEmail = null;
            if (config.isProduction()) {
                // Send email to the new user and the P&R notification email.
                // TO
                toEmail = user.getEmail();
            }
            // BBC
            String bbcEmails = this.config.getEmailNotification();
            sendMail.send(toEmail, null, bbcEmails, this.getText("planning.manageUsers.email.newUser.subject",
                    new String[] { user.getComposedName() }), message.toString(), null, null, null);
        }
    }

    /**
     * This method notify the user that is been assigned as Project Leader/Coordinator for a specific project.
     * 
     * @param userAssigned is the user that is being assigned.
     * @param role is the role (Project Leader or Project Coordinator).
     */
    private void notifyRoleAssigned(User userAssigned, Role role) {
        String projectRole = null;
        if (role.getId() == APConstants.ROLE_PROJECT_LEADER) {
            projectRole = this.getText("planning.projectPartners.types.PL");
        } else {
            projectRole = this.getText("planning.projectPartners.types.PC");
        }
        StringBuilder message = new StringBuilder();
        // Building the Email message:
        message.append(
                this.getText("planning.manageUsers.email.dear", new String[] { userAssigned.getFirstName() }));
        message.append(this.getText("planning.manageUsers.email.project.assigned",
                new String[] { projectRole, project.getTitle() }));
        message.append(this.getText("planning.manageUsers.email.support"));
        message.append(this.getText("planning.manageUsers.email.bye"));

        String toEmail = null;
        String ccEmail = null;
        if (config.isProduction()) {
            // Send email to the new user and the P&R notification email.
            // TO
            toEmail = userAssigned.getEmail();
            // CC will be the user who is making the modification.
            if (this.getCurrentUser() != null) {
                ccEmail = this.getCurrentUser().getEmail();
            }
        }
        // BBC will be our gmail notification email.
        String bbcEmails = this.config.getEmailNotification();
        sendMail.send(toEmail, ccEmail, bbcEmails,
                this.getText("planning.manageUsers.email.project.assigned.subject",
                        new String[] { projectRole,
                                project.getStandardIdentifier(Project.EMAIL_SUBJECT_IDENTIFIER) }),
                message.toString(), null, null, null);
    }

    /**
     * This method notify the the user that he/she stopped contributing to a specific project.
     * 
     * @param userUnassigned is the user that stopped contribution.
     * @param role is the user role that stopped contributing (Project Leader or Project Coordinator).
     */
    private void notifyRoleUnassigned(User userUnassigned, Role role) {
        String projectRole = null;
        if (role.getId() == APConstants.ROLE_PROJECT_LEADER) {
            projectRole = this.getText("planning.projectPartners.types.PL");
        } else {
            projectRole = this.getText("planning.projectPartners.types.PC");
        }
        StringBuilder message = new StringBuilder();
        // Building the Email message:
        message.append(
                this.getText("planning.manageUsers.email.dear", new String[] { userUnassigned.getFirstName() }));
        message.append(this.getText("planning.manageUsers.email.project.unAssigned",
                new String[] { projectRole, project.getTitle() }));
        message.append(this.getText("planning.manageUsers.email.support"));
        message.append(this.getText("planning.manageUsers.email.bye"));

        String toEmail = null;
        String ccEmail = null;
        if (config.isProduction()) {
            // Send email to the new user and the P&R notification email.
            // TO
            toEmail = userUnassigned.getEmail();
            // CC will be the user who is making the modification.
            if (this.getCurrentUser() != null) {
                ccEmail = this.getCurrentUser().getEmail();
            }
        }
        // BBC will be our gmail notification email.
        String bbcEmails = this.config.getEmailNotification();
        sendMail.send(toEmail, ccEmail, bbcEmails,
                this.getText("planning.manageUsers.email.project.unAssigned.subject",
                        new String[] { projectRole,
                                project.getStandardIdentifier(Project.EMAIL_SUBJECT_IDENTIFIER) }),
                message.toString(), null, null, null);
    }

    @Override
    public void prepare() throws Exception {
        super.prepare();
        // Getting the project id from the URL parameter
        // It's assumed that the project parameter is ok. (@See ValidateProjectParameterInterceptor)
        projectID = Integer
                .parseInt(StringUtils.trim(this.getRequest().getParameter(APConstants.PROJECT_REQUEST_ID)));

        // Getting the project identified with the id parameter.
        project = projectManager.getProject(projectID);

        // Getting the list of all institutions
        allInstitutions = institutionManager.getAllInstitutions();

        // Getting the list of all PPA institutions
        allPPAInstitutions = new ArrayList<>();
        allPPAInstitutions.addAll(institutionManager.getAllPPAInstitutions());

        // Getting all the countries
        countries = locationManager.getInstitutionCountries();

        // Getting all partner types
        intitutionTypes = institutionManager.getAllInstitutionTypes();

        // Getting all Project Leaders
        allUsers = userManager.getAllUsers();
        int year = 0;
        if (this.isReportingCycle()) {
            year = config.getReportingCurrentYear();
        } else {
            year = config.getPlanningCurrentYear();
        }
        // Getting all the project partners.
        project.setProjectPartners(projectPartnerManager.getProjectPartners(project, year));
        if (!project.getProjectPartners().isEmpty()) {
            overrall = project.getProjectPartners().get(0).getOverall();

        }

        // Positioning project leader to be the first in the list.
        ProjectPartner leader = project.getLeader();
        if (leader != null) {
            // First we remove the element from the array.
            project.getProjectPartners().remove(leader);
            // then we add it to the first position.
            project.getProjectPartners().add(0, leader);
        }

        // Getting the list of PPA Partners for this project
        this.projectPPAPartners = new ArrayList<ProjectPartner>();
        for (ProjectPartner pp : project.getProjectPartners()) {
            if (pp.getInstitution().isPPA()) {
                this.projectPPAPartners.add(pp);
            }
        }

        // Populating the list of partner person types
        partnerPersonTypes = new HashMap<>();
        partnerPersonTypes.put(APConstants.PROJECT_PARTNER_CP, this.getText("planning.projectPartners.types.CP"));

        if (this.hasProjectPermission("leader", projectID)) {
            partnerPersonTypes.put(APConstants.PROJECT_PARTNER_PL,
                    this.getText("planning.projectPartners.types.PL"));
        }

        if (this.hasProjectPermission("coordinator", projectID)) {
            partnerPersonTypes.put(APConstants.PROJECT_PARTNER_PC,
                    this.getText("planning.projectPartners.types.PC"));
        }

        // If the user is not admin or the project owner, we should keep some information

        previousProject = new Project();
        previousProject.setId(project.getId());
        previousProject.setProjectPartners(projectPartnerManager.getProjectPartners(project, year));

        if (this.getRequest().getMethod().equalsIgnoreCase("post")) {
            // Clear out the list if it has some element
            // if (ActionContext.getContext().getName().equals("ppaPartners") && project.getPPAPartners() != null) {
            // project.getPPAPartners().clear();
            // }

            if (ActionContext.getContext().getName().equals("partners") && project.getProjectPartners() != null) {
                project.getProjectPartners().clear();
            }
        }

        // Getting the Project lessons for this section.
        int evaluatingYear = 0;
        if (this.getCycleName().equals(APConstants.REPORTING_SECTION)) {
            evaluatingYear = this.getCurrentReportingYear();
        } else {
            evaluatingYear = this.getCurrentPlanningYear();
        }
        // Getting the Project lessons for this section.
        this.setProjectLessons(lessonManager.getProjectComponentLesson(projectID, this.getActionName(),
                evaluatingYear, this.getCycleName()));
        if (this.getCycleName().equals(APConstants.REPORTING_SECTION)) {
            this.setProjectLessonsPreview(lessonManager.getProjectComponentLesson(projectID, this.getActionName(),
                    this.getCurrentReportingYear(), APConstants.PLANNING_SECTION));
        }
        // Initializing Section Statuses:
        this.initializeProjectSectionStatuses(project, this.getCycleName());

        // Set History.
        super.setHistory(historyManager.getProjectPartnersHistory(project.getId()));

    }

    public List<ProjectPartner> projectPPAPartners() {
        return this.projectPPAPartners;
    }

    @Override
    public String save() {
        if (this.hasProjectPermission("update", projectID)) {
            // Saving Lessons
            if (!this.isNewProject()) {
                this.saveProjectLessons(project.getId());
            }

            // First, delete the partners that are not active anymore
            for (ProjectPartner previousPartner : previousProject.getProjectPartners()) {
                if (!project.getProjectPartners().contains(previousPartner)) {
                    projectPartnerManager.deleteProjectPartner(previousPartner, this.getCurrentUser(),
                            this.getJustification());
                    budgetManager.deleteBudgetsByInstitution(project.getId(), previousPartner.getInstitution(),
                            this.getCurrentUser(), this.getJustification());
                }
            }
            int year = 0;
            if (this.isReportingCycle()) {
                year = config.getReportingCurrentYear();
            } else {
                year = config.getPlanningCurrentYear();
            }

            projectPartnerManager.saveProjectPartners(project, project.getProjectPartners(), this.getCurrentUser(),
                    this.getJustification(), overrall, year);

            // Check if the project leader has changed and send the corresponding emails
            PartnerPerson previousLeader = previousProject.getLeaderPerson();
            PartnerPerson leader = project.getLeaderPerson();
            // Notify user if the project leader was created.
            if (leader != null) {
                this.notifyNewUserCreated(leader.getUser());
            }
            Role plRole = new Role(APConstants.ROLE_PROJECT_LEADER);
            // Update roles into the database and notify project assignment.
            this.updateRoles(previousLeader, leader, plRole);

            // Check if the project coordinator has changed and send the corresponding emails
            PartnerPerson previousCoordinator = null;
            if (previousProject.getCoordinatorPersons().size() > 0) {
                previousCoordinator = previousProject.getCoordinatorPersons().get(0);
            }
            PartnerPerson coordinator = null;
            if (project.getCoordinatorPersons() != null) {
                if (project.getCoordinatorPersons().size() > 0) {
                    coordinator = project.getCoordinatorPersons().get(0);
                }
            }

            // Notify user if the project coordinator was created.
            if (coordinator != null) {
                this.notifyNewUserCreated(coordinator.getUser());
            }
            Role pcRole = new Role(APConstants.ROLE_PROJECT_COORDINATOR);
            // Update roles into the database and notify project assignment.
            this.updateRoles(previousCoordinator, coordinator, pcRole);

            // Get the validation messages and append them to the save message
            Collection<String> messages = this.getActionMessages();
            if (!messages.isEmpty()) {
                String validationMessage = messages.iterator().next();
                this.setActionMessages(null);
                this.addActionWarning(this.getText("saving.saved") + validationMessage);
            } else {
                this.addActionMessage(this.getText("saving.saved"));
            }
            return SUCCESS;
        }
        return NOT_AUTHORIZED;

    }

    public void setAllProjectLeaders(List<User> allProjectLeaders) {
        this.allUsers = allProjectLeaders;
    }

    public void setOverrall(String overrall) {
        this.overrall = overrall;
    }

    public void setProject(Project project) {
        this.project = project;
    }

    public void setProjectID(int projectID) {
        this.projectID = projectID;
    }

    /**
     * This method updates the role for each user (Leader/Coordinator) into the database, and notifies by email what has
     * been done.
     * 
     * @param previousPartnerPerson is the previous leader/coordinator that has assigned the project before.
     * @param partnerPerson the current leader/coordinator associated to the project.
     * @param role is the new role assignated (leader/coordinator).
     */
    private void updateRoles(PartnerPerson previousPartnerPerson, PartnerPerson partnerPerson, Role role) {
        if (previousPartnerPerson == null && partnerPerson != null) {
            roleManager.saveRole(partnerPerson.getUser(), role);
            // Notifying user is assigned as Project Leader/Coordinator.
            this.notifyRoleAssigned(partnerPerson.getUser(), role);
        } else if (previousPartnerPerson != null && partnerPerson == null) {
            roleManager.deleteRole(previousPartnerPerson.getUser(), role);
            // Notifying user that is not the project leader anymore
            this.notifyRoleUnassigned(previousPartnerPerson.getUser(), role);
        } else if (previousPartnerPerson != null && partnerPerson != null) {
            if (!partnerPerson.equals(previousPartnerPerson)) {
                roleManager.saveRole(partnerPerson.getUser(), role);
                // Notifying user is assigned as Project Leader/Coordinator.
                this.notifyRoleAssigned(partnerPerson.getUser(), role);
                // Deleting role.
                roleManager.deleteRole(previousPartnerPerson.getUser(), role);
                // Notifying user that is not the project leader anymore
                this.notifyRoleUnassigned(previousPartnerPerson.getUser(), role);
            }
        }
        this.clearPermissionsCache();
    }

    @Override
    public void validate() {
        if (save) {
            if (!project.getProjectPartners().isEmpty()) {
                project.getProjectPartners().get(0).setOverall(overrall);
            }
            projectPartnersValidator.validate(this, project, this.getCycleName());
        }
    }

}