Java tutorial
/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundacin para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolxico de Galicia * Copyright (C) 2010-2011 Igalia, S.L. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.libreplan.web.works; import static org.libreplan.business.common.exceptions.ValidationException.invalidValue; import static org.libreplan.web.I18nHelper._; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import org.apache.commons.lang.Validate; import org.hibernate.NonUniqueResultException; import org.joda.time.LocalDate; import org.libreplan.business.common.IOnTransaction; import org.libreplan.business.common.Registry; import org.libreplan.business.common.daos.IConfigurationDAO; import org.libreplan.business.common.daos.IEntitySequenceDAO; import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.common.exceptions.ValidationException; import org.libreplan.business.documents.daos.IDocumentDAO; import org.libreplan.business.orders.daos.ISumChargedEffortDAO; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.users.daos.IUserCoachDAO; import org.libreplan.business.users.daos.IUserDAO; import org.libreplan.business.users.daos.IUserDepartmentDAO; import org.libreplan.business.users.daos.IUserSuperiorDAO; import org.libreplan.business.users.entities.User; import org.libreplan.business.users.entities.UserCoach; import org.libreplan.business.users.entities.UserSuperior; import org.libreplan.business.workingday.EffortDuration; import org.libreplan.business.workingday.EffortDuration.Granularity; import org.libreplan.business.workreports.daos.IWorkReportDAO; import org.libreplan.business.workreports.daos.IWorkReportTypeDAO; import org.libreplan.business.workreports.entities.PredefinedWorkReportTypes; import org.libreplan.business.workreports.entities.WorkReport; import org.libreplan.business.workreports.entities.WorkReportLine; import org.libreplan.business.workreports.entities.WorkReportType; import org.libreplan.business.works.daos.IWorkDAO; import org.libreplan.business.works.entities.Work; import org.libreplan.business.works.entities.WorkStateEnum; import org.libreplan.business.works.entities.WorkStatusEnum; import org.libreplan.business.works.entities.WorkTypeEnum; import org.libreplan.web.UserUtil; import org.libreplan.web.common.Util; import org.libreplan.web.common.concurrentdetection.OnConcurrentModification; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.zkoss.zul.Textbox; @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) @OnConcurrentModification(goToPage = "/works/work.zul") public class WorkModel implements IWorkModel { @Autowired private IWorkDAO workDAO; @Autowired private IDocumentDAO documentDAO; @Autowired private IUserDAO userDAO; @Autowired private IUserSuperiorDAO userSuperiorDAO; @Autowired private IUserCoachDAO userCoachDAO; @Autowired private IWorkReportDAO workReportDAO; @Autowired private IConfigurationDAO configurationDAO; @Autowired private IEntitySequenceDAO entitySequenceDAO; @Autowired private IWorkReportTypeDAO workReportTypeDAO; @Autowired private ISumChargedEffortDAO sumChargedEffortDAO; private Work work; private BigDecimal previousUsedHours = BigDecimal.ZERO; public WorkModel() { } @Override @Transactional(readOnly = true) public List<Work> getWorks() { User user = UserUtil.getUserFromSession(); return workDAO.getWorksOfUser(user); } @Override @Transactional public void confirmDelete(Work work) throws InstanceNotFoundException { if (work.getType() == WorkTypeEnum.TASK) { updateWorkReport(work, true); } workDAO.remove(work); workDAO.flush(); } @Override @Transactional public void confirmSave() throws ValidationException { Validate.notEmpty(work.getTitle()); if (!Util.isSameDate(work.getFromTime(), work.getToTime())) { throw new ValidationException(invalidValue(_("From time and end time should be in same date."), "title", work.getTitle(), work)); } if (work.getFromTime().compareTo(work.getToTime()) > 0) { throw new ValidationException( invalidValue(_("From time should not be after end time ."), "title", work.getTitle(), work)); } if (work.getType() == WorkTypeEnum.TASK && work.getTask() == null) { throw new ValidationException( invalidValue(_("Work of task must has a task related to it."), "title", work.getTitle(), work)); } if (work.getType() == WorkTypeEnum.PROJECT && work.getProject() == null) { throw new ValidationException(invalidValue(_("Work of project must has a project related to it."), "title", work.getTitle(), work)); } if (work.isNewObject()) { work.setRegisterTime(new Date()); } workDAO.saveWithoutValidating(work); workDAO.flush(); } @Override @Transactional public void acceptOrRejectWork(boolean accept, String comment) throws ValidationException { User user = UserUtil.getUserFromSession(); String ocomment = work.getReviewComment(); if (comment == null) comment = ""; comment = ocomment + "\n\n" + _((accept ? " reviewed" : " rejected") + " by {0} at {1}.", user.getFullName(), Util.formatDateTime(new Date(), "")) + "\n\t" + _("Comment: ") + comment; work.setReviewComment(comment); if (accept) { work.setReviewTime(new Date()); work.setReviewUser(user); if (work.getType() == WorkTypeEnum.TASK) { updateWorkReport(work, false); } } work.setStatus(accept ? WorkStatusEnum.REVIEWED : WorkStatusEnum.REJECTED); confirmSave(); } private void updateWorkReport(Work work, boolean delete) { LocalDate date = LocalDate.fromDateFields(work.getFromTime()); WorkReport wr = workReportDAO.getPersonalTimesheetWorkReport(work.getUser().getWorker(), date, configurationDAO.getConfiguration().getPersonalTimesheetsPeriodicity()); if (wr == null) { wr = WorkReport.create(getPersonalTimesheetsWorkReportType()); wr.setCode(entitySequenceDAO.getNextEntityCodeWithoutTransaction(EntityNameEnum.WORK_REPORT)); wr.setCodeAutogenerated(true); wr.setResource(work.getUser().getWorker()); } else { forceLoad(wr.getWorkReportLines()); } WorkReportLine wrl = null; OrderElement orderElement = work.getTask(); for (WorkReportLine line : wr.getWorkReportLines()) { if (line.getOrderElement().getId().equals(orderElement.getId()) && LocalDate.fromDateFields(line.getDate()).equals(date)) { wrl = line; break; } } if (wrl == null) { wrl = createWorkReportLine(wr, orderElement, date); wr.addWorkReportLine(wrl); } BigDecimal diff = (delete) ? work.getUsedHours().negate() : work.getUsedHours().subtract(previousUsedHours); EffortDuration de = EffortDuration.seconds((int) (diff.doubleValue() * 3600)); EffortDuration effort = wrl.getEffort().plus(de); if (effort.compareTo(EffortDuration.zero()) < 0) effort = EffortDuration.zero(); wrl.setEffort(effort); sumChargedEffortDAO.updateRelatedSumChargedEffortWithWorkReportLineSet(wr.getWorkReportLines()); wr.generateWorkReportLineCodes(entitySequenceDAO.getNumberOfDigitsCode(EntityNameEnum.WORK_REPORT)); workReportDAO.save(wr); workReportDAO.flush(); } private void forceLoad(Set<WorkReportLine> workReportLines) { for (WorkReportLine line : workReportLines) { line.getOrderElement().getName(); } } private WorkReportLine createWorkReportLine(WorkReport workReport, OrderElement orderElement, LocalDate date) { WorkReportLine workReportLine = WorkReportLine.create(workReport); workReportLine.setCodeAutogenerated(true); workReportLine.setOrderElement(orderElement); workReportLine.setDate(date.toDateTimeAtStartOfDay().toDate()); workReportLine .setTypeOfWorkHours(configurationDAO.getConfiguration().getPersonalTimesheetsTypeOfWorkHours()); workReportLine.setEffort(EffortDuration.zero()); return workReportLine; } private WorkReportType getPersonalTimesheetsWorkReportType() { try { WorkReportType workReportType = workReportTypeDAO .findUniqueByName(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS.getName()); return workReportType; } catch (NonUniqueResultException e) { throw new RuntimeException(e); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } } @Override public Work getWork() { return work; } @Override public void initCreate() { User user = UserUtil.getUserFromSession(); work = Work.create(user, "", ""); work.setFromTime(Util.getRoundedDate(new Date(), 8)); work.setToTime(Util.getRoundedDate(new Date(), 18)); work.setUsedHours(new BigDecimal("1")); work.setType(WorkTypeEnum.DAILY); work.setState(WorkStateEnum.FINISHED); work.setStatus(WorkStatusEnum.RECORDED); previousUsedHours = BigDecimal.ZERO; } @Override @Transactional(readOnly = true) public void initEdit(Work wrk) { Validate.notNull(wrk); this.work = getFromDB(wrk); previousUsedHours = this.work.getUsedHours(); } private Work getFromDB(Work wrk) { try { return workDAO.find(wrk.getId()); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } } @Override public void initCreate(Object data, Object parent) { initCreate(); if (data instanceof WorkTypeEnum) { WorkTypeEnum type = (WorkTypeEnum) data; if ((parent instanceof String) && ((String) parent).equals(_("My Own Works"))) { work.setType(type); } } } @Override public void initCreate(Work preceding) { initCreate(); work.setType(preceding.getType()); work.setPreceding(preceding); work.setTask(preceding.getTask()); work.setProject(preceding.getProject()); } @Override @Transactional(readOnly = true) public List<Work> search(User user, boolean onlyTitle, String searchString) { String[] keyWords = searchString.split("[\\,\\;\\s]"); List<Work> works = workDAO.search(user, onlyTitle, keyWords); List<Work> result = new ArrayList<Work>(); for (Work wrk : works) { if (canViewWork(wrk)) { result.add(wrk); } } return result; } /** * * @param work * @return boolean:if current user can read work * user can view works: * >>his own work * >>his subordinate's work which work type is daily,interim,schudled; * >>his apprentice's work which work type is apprenticeship work * >>work of tasks which which the user can access * >>work of project which the user can access */ @Override @Transactional(readOnly = true) public boolean canViewWork(final Work work) { if (work != null) { LocalDate date = LocalDate.fromDateFields(work.getFromTime()); User user = UserUtil.getUserFromSession(); User wuser = work.getUser(); if (wuser != null) { if (wuser.getId().equals(user.getId())) return true; if (work.getType() == WorkTypeEnum.DAILY || work.getType() == WorkTypeEnum.INTERIM || work.getType() == WorkTypeEnum.SCHEDULED) { return userSuperiorDAO.isSuperior(user, wuser, date); } else if (work.getType() == WorkTypeEnum.APPRENTICESHIP) { return userCoachDAO.isCoach(user, wuser, date); } } else if (work.getType() == WorkTypeEnum.PROJECT) { } else if (work.getType() == WorkTypeEnum.TASK) { } return false; } return false; } /** * * @param work * @return boolean:if current user can edit work * user can edit works: * >>his own work that hasn't been reviewed */ @Override @Transactional(readOnly = true) public boolean canEditWork(Work work) { if (work != null) { User user = UserUtil.getUserFromSession(); User wuser = work.getUser(); return (wuser != null && wuser.getId().equals(user.getId()) && work.getStatus() != WorkStatusEnum.REVIEWED); } return false; } /** * * @param work * @return boolean:if current user can delete work * user can delete works: * >>his own work that hasn't been reviewed and rejected */ @Override @Transactional(readOnly = true) public boolean canDeleteWork(Work work) { if (work != null) { User user = UserUtil.getUserFromSession(); User wuser = work.getUser(); return (wuser != null && wuser.getId().equals(user.getId()) && work.getStatus() != WorkStatusEnum.REVIEWED && work.getStatus() != WorkStatusEnum.REJECTED); } return false; } /** * * @param work * @return boolean:if current user can continue work * user can continue works: * >>his own work * >>work of tasks which which the user can access * >>work of project which the user can access */ @Override @Transactional(readOnly = true) public boolean canContinueWork(final Work work) { if (work != null) { User user = UserUtil.getUserFromSession(); User wuser = work.getUser(); if (wuser != null) { if (wuser.getId().equals(user.getId())) return true; } else if (work.getType() == WorkTypeEnum.PROJECT) { } else if (work.getType() == WorkTypeEnum.TASK) { } return false; } return false; } /** * * @param work * @return boolean:if current user can continue work * user can review works: * >>his directive apprentice's apprenticeship work * >>his directive subordinate' daily,scheduled,interim work * >>work of task which the user is manager * >>work of project which the user is manager */ @Override @Transactional(readOnly = true) public boolean canReviewWork(final Work work) { if (work != null) { if (work.getStatus() == WorkStatusEnum.REVIEWED || work.getStatus() == WorkStatusEnum.DRAFT) return false; } User user = UserUtil.getUserFromSession(); User wuser = work.getUser(); LocalDate date = LocalDate.fromDateFields(work.getFromTime()); if (work.getType() == WorkTypeEnum.DAILY || work.getType() == WorkTypeEnum.INTERIM || work.getType() == WorkTypeEnum.SCHEDULED) { UserSuperior us = userSuperiorDAO.findByUser(wuser, date); return us != null && us.getSuperior() != null && us.getSuperior().getId().equals(user.getId()); } else if (work.getType() == WorkTypeEnum.APPRENTICESHIP) { UserCoach uc = userCoachDAO.findByUser(wuser, date); return uc != null && uc.getCoach() != null && uc.getCoach().getId().equals(user.getId()); } else if (work.getType() == WorkTypeEnum.PROJECT) { } else if (work.getType() == WorkTypeEnum.TASK) { } return false; } }