Java tutorial
/***************************************************************** * This file is part of Managing Agricultural Research for Learning & * Outcomes Platform (MARLO). * MARLO 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. * MARLO 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 MARLO. If not, see <http://www.gnu.org/licenses/>. *****************************************************************/ package org.cgiar.ccafs.marlo.action.projects; import org.cgiar.ccafs.marlo.action.BaseAction; import org.cgiar.ccafs.marlo.config.APConstants; import org.cgiar.ccafs.marlo.data.manager.AuditLogManager; import org.cgiar.ccafs.marlo.data.manager.BudgetTypeManager; import org.cgiar.ccafs.marlo.data.manager.CrpClusterOfActivityManager; import org.cgiar.ccafs.marlo.data.manager.GlobalUnitManager; import org.cgiar.ccafs.marlo.data.manager.LiaisonInstitutionManager; import org.cgiar.ccafs.marlo.data.manager.ProjectBudgetManager; import org.cgiar.ccafs.marlo.data.manager.ProjectBudgetsCluserActvityManager; import org.cgiar.ccafs.marlo.data.manager.ProjectManager; import org.cgiar.ccafs.marlo.data.model.BudgetType; import org.cgiar.ccafs.marlo.data.model.CrpClusterOfActivity; import org.cgiar.ccafs.marlo.data.model.GlobalUnit; import org.cgiar.ccafs.marlo.data.model.Project; import org.cgiar.ccafs.marlo.data.model.ProjectBudget; import org.cgiar.ccafs.marlo.data.model.ProjectBudgetsCluserActvity; import org.cgiar.ccafs.marlo.data.model.ProjectClusterActivity; import org.cgiar.ccafs.marlo.security.APCustomRealm; import org.cgiar.ccafs.marlo.security.Permission; import org.cgiar.ccafs.marlo.utils.APConfig; import org.cgiar.ccafs.marlo.utils.AutoSaveReader; import org.cgiar.ccafs.marlo.validation.projects.ProjectBudgetsCoAValidator; import org.cgiar.ccafs.marlo.validation.projects.ProjectBudgetsValidator; import java.io.BufferedReader; import java.io.FileReader; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.file.Path; import java.nio.file.Paths; import java.text.DecimalFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import javax.inject.Inject; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import org.apache.commons.lang3.StringUtils; public class ProjectBudgetByClusterOfActivitiesAction extends BaseAction { /** * */ private static final long serialVersionUID = -7931655721857302103L; private CrpClusterOfActivityManager crpClusterOfActivityManager; private BudgetTypeManager budgetTypeManager; private ProjectManager projectManager; private ProjectBudgetsCluserActvityManager projectBudgetsCluserActvityManager; private GlobalUnitManager crpManager; private long projectID; private GlobalUnit loggedCrp; private Project project; private String transaction; private AuditLogManager auditLogManager; private ProjectBudgetsCoAValidator validator; private List<BudgetType> budgetTypesList; @Inject public ProjectBudgetByClusterOfActivitiesAction(APConfig config, CrpClusterOfActivityManager crpClusterOfActivityManager, ProjectManager projectManager, GlobalUnitManager crpManager, ProjectBudgetManager projectBudgetManager, AuditLogManager auditLogManager, BudgetTypeManager budgetTypeManager, LiaisonInstitutionManager liaisonInstitutionManager, ProjectBudgetsValidator projectBudgetsValidator, ProjectBudgetsCluserActvityManager projectBudgetsCluserActvityManager, ProjectBudgetsCoAValidator validator) { super(config); this.crpClusterOfActivityManager = crpClusterOfActivityManager; this.projectManager = projectManager; this.crpManager = crpManager; this.validator = validator; this.auditLogManager = auditLogManager; this.budgetTypeManager = budgetTypeManager; this.projectBudgetsCluserActvityManager = projectBudgetsCluserActvityManager; } @Override public String cancel() { Path path = this.getAutoSaveFilePath(); if (path.toFile().exists()) { boolean fileDeleted = path.toFile().delete(); } this.setDraft(false); Collection<String> messages = this.getActionMessages(); if (!messages.isEmpty()) { String validationMessage = messages.iterator().next(); this.setActionMessages(null); this.addActionMessage("draft:" + this.getText("cancel.autoSave")); } else { this.addActionMessage("draft:" + this.getText("cancel.autoSave")); } messages = this.getActionMessages(); return SUCCESS; } /** * This method clears the cache and re-load the user permissions in the next iteration. */ @Override public void clearPermissionsCache() { ((APCustomRealm) securityContext.getRealm()) .clearCachedAuthorizationInfo(securityContext.getSubject().getPrincipals()); } private Path getAutoSaveFilePath() { String composedClassName = project.getClass().getSimpleName(); // get the action name and replace / for _ String actionFile = this.getActionName().replace("/", "_"); // concatane name and add the .json extension String autoSaveFile = project.getId() + "_" + composedClassName + "_" + this.getActualPhase().getDescription() + "_" + this.getActualPhase().getYear() + "_" + actionFile + ".json"; return Paths.get(config.getAutoSaveFolder() + autoSaveFile); } public ProjectBudgetsCluserActvity getBudget(String activitiyId, int year, long type) { if (project.getBudgetsCluserActvities() == null) { project.setBudgetsCluserActvities(new ArrayList<>()); } return project.getBudgetsCluserActvities().get(this.getIndexBudget(activitiyId, year, type)); } public List<BudgetType> getBudgetTypesList() { return budgetTypesList; } public int getIndexBudget(String activitiyId, int year, long type) { if (project.getBudgetsCluserActvities() != null) { int i = 0; for (ProjectBudgetsCluserActvity projectBudget : project.getBudgetsCluserActvities()) { if (projectBudget.getCrpClusterOfActivity() != null) { if (projectBudget.getCrpClusterOfActivity().getIdentifier().equals(activitiyId) && year == projectBudget.getYear() && type == projectBudget.getBudgetType().getId().longValue()) { return i; } } i++; } } else { project.setBudgetsCluserActvities(new ArrayList<>()); } ProjectBudgetsCluserActvity projectBudget = new ProjectBudgetsCluserActvity(); projectBudget.setCrpClusterOfActivity(crpClusterOfActivityManager .getCrpClusterOfActivityByIdentifierPhase(activitiyId, this.getActualPhase())); projectBudget.setYear(year); projectBudget.setBudgetType(budgetTypeManager.getBudgetTypeById(type)); project.getBudgetsCluserActvities().add(projectBudget); return this.getIndexBudget(activitiyId, year, type); } public GlobalUnit getLoggedCrp() { return loggedCrp; } public Project getProject() { return project; } public long getProjectID() { return projectID; } public double getRemaining(Long type, int year) throws ParseException { double remaining = 100; if (project.getBudgetsCluserActvities() != null) { for (ProjectBudgetsCluserActvity projectBudgetsCluserActvity : project.getBudgetsCluserActvities()) { if (projectBudgetsCluserActvity.getYear() == year && projectBudgetsCluserActvity.getBudgetType().getId().longValue() == type.longValue()) { if (projectBudgetsCluserActvity.getAmount() != null) { remaining = remaining - projectBudgetsCluserActvity.getAmount().doubleValue(); remaining = this.round(remaining, 2); } } } } return remaining; } public double getRemainingGender(Long type, int year) throws ParseException { double remaining = 100; DecimalFormat df = new DecimalFormat("0.00"); if (project.getBudgetsCluserActvities() != null) { for (ProjectBudgetsCluserActvity projectBudgetsCluserActvity : project.getBudgetsCluserActvities()) { if (projectBudgetsCluserActvity.getYear() == year && projectBudgetsCluserActvity.getBudgetType().getId().longValue() == type.longValue()) { if (projectBudgetsCluserActvity.getGenderPercentage() != null) { remaining = remaining - projectBudgetsCluserActvity.getGenderPercentage().doubleValue(); remaining = this.round(remaining, 2); } } } } return remaining; } public Long getTotalAmount(Long type, int year) { long totalAmount = 0; double porcentage; try { porcentage = Math.abs(this.getRemaining(type, year) - 100); totalAmount = (long) (this.getTotalYearPartners(year, type) * (porcentage / 100)); return totalAmount; } catch (ParseException e) { return new Long(0); } } public Long getTotalGender(Long type, int year) { long totalAmount = 0; double porcentage; try { porcentage = Math.abs(this.getRemainingGender(type, year) - 100); totalAmount = (long) (this.getTotalGenderPartners(year, type) * (porcentage / 100)); return totalAmount; } catch (ParseException e) { return new Long(0); } } public long getTotalGenderPartners(int year, long type) { long total = 0; Project projectBD = projectManager.getProjectById(projectID); for (ProjectBudget projectBudget : projectBD.getProjectBudgets()) { if (year == projectBudget.getYear() && type == projectBudget.getBudgetType().getId().longValue() && projectBudget.getPhase().equals(this.getActualPhase()) && projectBudget.isActive()) { if (projectBudget.getGenderPercentage() != null && projectBudget.getAmount() != null) { total = (long) (total + (projectBudget.getAmount() * (projectBudget.getGenderPercentage() / 100))); } } } return total; } public double getTotalYearPartners(int year, long type) { double total = 0; Project projectBD = projectManager.getProjectById(projectID); for (ProjectBudget projectBudget : projectBD.getProjectBudgets()) { if (year == projectBudget.getYear() && type == projectBudget.getBudgetType().getId().longValue() && projectBudget.getPhase().equals(this.getActualPhase()) && projectBudget.isActive()) { if (projectBudget.getAmount() != null) { total = total + projectBudget.getAmount(); } } } return total; } public String getTransaction() { return transaction; } public boolean hasBudgets(Long type, int year) { Project projectBD = projectManager.getProjectById(projectID); List<ProjectBudget> budgets = projectBD.getProjectBudgets().stream() .filter(c -> c.isActive() && c.getYear() == year && c.getPhase().equals(this.getActualPhase()) && c.getBudgetType().getId().longValue() == type.longValue() && (c.getAmount() != null && c.getAmount() >= 0)) .collect(Collectors.toList()); return budgets.size() > 0; } @Override public void prepare() throws Exception { projectID = Long .parseLong(StringUtils.trim(this.getRequest().getParameter(APConstants.PROJECT_REQUEST_ID))); loggedCrp = (GlobalUnit) this.getSession().get(APConstants.SESSION_CRP); loggedCrp = crpManager.getGlobalUnitById(loggedCrp.getId()); // Budget Types list budgetTypesList = budgetTypeManager.findAll(); if (this.getRequest().getParameter(APConstants.TRANSACTION_ID) != null) { transaction = StringUtils.trim(this.getRequest().getParameter(APConstants.TRANSACTION_ID)); Project history = (Project) auditLogManager.getHistory(transaction); if (history != null) { project = history; } else { this.transaction = null; this.setTransaction("-1"); } } else { project = projectManager.getProjectById(projectID); } if (project != null) { Path path = this.getAutoSaveFilePath(); if (path.toFile().exists() && this.getCurrentUser().isAutoSave()) { BufferedReader reader = null; reader = new BufferedReader(new FileReader(path.toFile())); Gson gson = new GsonBuilder().create(); JsonObject jReader = gson.fromJson(reader, JsonObject.class); reader.close(); AutoSaveReader autoSaveReader = new AutoSaveReader(); project = (Project) autoSaveReader.readFromJson(jReader); Project projectDb = projectManager.getProjectById(project.getId()); project.setProjectInfo(projectDb.getProjecInfoPhase(this.getActualPhase())); project.getProjectInfo().setProjectEditLeader( projectDb.getProjecInfoPhase(this.getActualPhase()).isProjectEditLeader()); reader.close(); this.setDraft(true); } else { this.setDraft(false); project.setProjectInfo(project.getProjecInfoPhase(this.getActualPhase())); project.setBudgetsCluserActvities(project.getProjectBudgetsCluserActvities().stream() .filter(c -> c.isActive() && c.getPhase().equals(this.getActualPhase())) .collect(Collectors.toList())); } /** * There is an issue where a CoA that is unmapped from the project - still appears here, this happens for * both auto-save files and non auto-save updates. */ project.getBudgetsCluserActvities().removeIf(Objects::isNull); Project projectBD = projectManager.getProjectById(projectID); project.setProjectInfo(projectBD.getProjecInfoPhase(this.getActualPhase())); List<CrpClusterOfActivity> activities = new ArrayList<CrpClusterOfActivity>(); for (ProjectClusterActivity crpClusterOfActivity : projectBD.getProjectClusterActivities().stream() .filter(c -> c.isActive() && c.getPhase().equals(this.getActualPhase())) .collect(Collectors.toList())) { activities.add(crpClusterOfActivity.getCrpClusterOfActivity()); } project.setCrpActivities(activities); } if (project.getBudgetsCluserActvities() != null) { for (ProjectBudgetsCluserActvity projectBudgetsCluserActvity : project.getBudgetsCluserActvities()) { // This additional null check is required for auto save file after a CoA has been deleted from the project if (projectBudgetsCluserActvity.getCrpClusterOfActivity() != null) { projectBudgetsCluserActvity .setCrpClusterOfActivity(crpClusterOfActivityManager.getCrpClusterOfActivityById( projectBudgetsCluserActvity.getCrpClusterOfActivity().getId())); } } } String params[] = { loggedCrp.getAcronym(), project.getId() + "" }; this.setBasePermission(this.getText(Permission.PROJECT_BUDGET_CLUSTER_BASE_PERMISSION, params)); if (this.isHttpPost()) { // if (project.getCrpActivities() != null) { // project.getCrpActivities().clear(); // } // // if (project.getBudgetsCluserActvities() != null) { // project.getBudgetsCluserActvities().clear(); // } if (project.getBudgetsCluserActvities() != null) { project.getBudgetsCluserActvities().clear(); } } } public double round(double value, int places) { if (places < 0) { throw new IllegalArgumentException(); } BigDecimal bd = new BigDecimal(value); bd = bd.setScale(places, RoundingMode.HALF_UP); return bd.doubleValue(); } @Override public String save() { if (this.hasPermission("canEdit")) { this.saveBasicBudgets(); List<String> relationsName = new ArrayList<>(); relationsName.add(APConstants.PROJECT_BUDGETS_ACTVITIES_RELATION); relationsName.add(APConstants.PROJECT_INFO_RELATION); project = projectManager.getProjectById(projectID); /** * The following is required because we need to update something on the @Project if we want a row created in * the auditlog table. */ this.setModificationJustification(project); projectManager.saveProject(project, this.getActionName(), relationsName, this.getActualPhase()); Path path = this.getAutoSaveFilePath(); if (path.toFile().exists()) { path.toFile().delete(); } Collection<String> messages = this.getActionMessages(); if (!this.getInvalidFields().isEmpty()) { this.setActionMessages(null); // this.addActionMessage(Map.toString(this.getInvalidFields().toArray())); List<String> keys = new ArrayList<String>(this.getInvalidFields().keySet()); for (String key : keys) { this.addActionMessage(key + ": " + this.getInvalidFields().get(key)); } } else { this.addActionMessage("message:" + this.getText("saving.saved")); } return SUCCESS; } else { return NOT_AUTHORIZED; } } public void saveBasicBudgets() { Project projectDB = projectManager.getProjectById(projectID); for (ProjectBudgetsCluserActvity projectBudget : projectDB.getProjectBudgetsCluserActvities().stream() .filter(c -> c.isActive() && c.getPhase().equals(this.getActualPhase())) .collect(Collectors.toList())) { if (project.getBudgetsCluserActvities() == null) { project.setBudgetsCluserActvities(new ArrayList<>()); } if (projectBudget.getYear() == this.getCurrentCycleYear()) { if (!project.getBudgetsCluserActvities().contains(projectBudget)) { projectBudgetsCluserActvityManager.deleteProjectBudgetsCluserActvity(projectBudget.getId()); } } } if (project.getBudgetsCluserActvities() != null) { for (ProjectBudgetsCluserActvity projectBudgetCluserActivityUI : project.getBudgetsCluserActvities()) { if (projectBudgetCluserActivityUI != null) { if (projectBudgetCluserActivityUI.getId() == null) { projectBudgetCluserActivityUI.setProject(project); projectBudgetCluserActivityUI.setPhase(this.getActualPhase()); if (projectBudgetCluserActivityUI.getCrpClusterOfActivity() != null) { projectBudgetsCluserActvityManager .saveProjectBudgetsCluserActvity(projectBudgetCluserActivityUI); } } else { ProjectBudgetsCluserActvity projectBudgetCluserActivityDB = projectBudgetsCluserActvityManager .getProjectBudgetsCluserActvityById(projectBudgetCluserActivityUI.getId()); projectBudgetCluserActivityDB .setGenderPercentage(projectBudgetCluserActivityUI.getGenderPercentage()); projectBudgetCluserActivityDB.setAmount(projectBudgetCluserActivityUI.getAmount()); projectBudgetCluserActivityDB.setPhase(this.getActualPhase()); projectBudgetCluserActivityDB.setProject(project); projectBudgetCluserActivityDB = projectBudgetsCluserActvityManager .saveProjectBudgetsCluserActvity(projectBudgetCluserActivityDB); } } } } } public void setBudgetTypesList(List<BudgetType> budgetTypesList) { this.budgetTypesList = budgetTypesList; } public void setLoggedCrp(GlobalUnit loggedCrp) { this.loggedCrp = loggedCrp; } public void setProject(Project project) { this.project = project; } public void setProjectID(long projectID) { this.projectID = projectID; } public void setTransaction(String transaction) { this.transaction = transaction; } @Override public void validate() { if (save) { validator.validate(this, project, true); } } }