diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/Configuration.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/Configuration.java index 59cbd304b..7594dd6a7 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/Configuration.java +++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/Configuration.java @@ -109,8 +109,9 @@ public class Configuration extends BaseEntity { private String currencyCode = "EUR"; private String currencySymbol = "€"; - private TypeOfWorkHours monthlyTimesheetsTypeOfWorkHours; + private TypeOfWorkHours personalTimesheetsTypeOfWorkHours; + private PersonalTimesheetsPeriodicityEnum personalTimesheetsPeriodicity = PersonalTimesheetsPeriodicityEnum.MONTHLY; public void setDefaultCalendar(BaseCalendar defaultCalendar) { this.defaultCalendar = defaultCalendar; @@ -451,13 +452,22 @@ public class Configuration extends BaseEntity { this.currencySymbol = currencySymbol; } - public TypeOfWorkHours getMonthlyTimesheetsTypeOfWorkHours() { - return monthlyTimesheetsTypeOfWorkHours; + public TypeOfWorkHours getPersonalTimesheetsTypeOfWorkHours() { + return personalTimesheetsTypeOfWorkHours; } - public void setMonthlyTimesheetsTypeOfWorkHours( + public void setPersonalTimesheetsTypeOfWorkHours( TypeOfWorkHours typeOfWorkHours) { - monthlyTimesheetsTypeOfWorkHours = typeOfWorkHours; + personalTimesheetsTypeOfWorkHours = typeOfWorkHours; + } + + public PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() { + return personalTimesheetsPeriodicity; + } + + public void setPersonalTimesheetsPeriodicity( + PersonalTimesheetsPeriodicityEnum personalTimesheetsPeriodicity) { + this.personalTimesheetsPeriodicity = personalTimesheetsPeriodicity; } } diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/IMonthlyTimesheetsTypeOfWorkHoursBootstrap.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/IPersonalTimesheetsTypeOfWorkHoursBootstrap.java similarity index 87% rename from libreplan-business/src/main/java/org/libreplan/business/common/entities/IMonthlyTimesheetsTypeOfWorkHoursBootstrap.java rename to libreplan-business/src/main/java/org/libreplan/business/common/entities/IPersonalTimesheetsTypeOfWorkHoursBootstrap.java index 02be6d9d9..163ac00ee 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/IMonthlyTimesheetsTypeOfWorkHoursBootstrap.java +++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/IPersonalTimesheetsTypeOfWorkHoursBootstrap.java @@ -22,11 +22,11 @@ package org.libreplan.business.common.entities; import org.libreplan.business.IDataBootstrap; /** - * Contract for {@link MonthlyTimesheetsTypeOfWorkHoursBootstrap}. + * Contract for {@link PersonalTimesheetsTypeOfWorkHoursBootstrap}. * * @author Manuel Rego Casasnovas */ -public interface IMonthlyTimesheetsTypeOfWorkHoursBootstrap extends +public interface IPersonalTimesheetsTypeOfWorkHoursBootstrap extends IDataBootstrap { void loadRequiredData(); diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/PersonalTimesheetsPeriodicityEnum.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PersonalTimesheetsPeriodicityEnum.java new file mode 100644 index 000000000..943bd4b79 --- /dev/null +++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PersonalTimesheetsPeriodicityEnum.java @@ -0,0 +1,201 @@ +/* + * This file is part of LibrePlan + * + * Copyright (C) 2012 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 . + */ + +package org.libreplan.business.common.entities; + +import static org.libreplan.business.i18n.I18nHelper._; + +import org.joda.time.LocalDate; +import org.joda.time.Months; +import org.joda.time.Weeks; + +/** + * Different values for personal timesheets periodicity. + * + * @author Manuel Rego Casasnovas + */ +public enum PersonalTimesheetsPeriodicityEnum { + + MONTHLY(_("Monthly")) { + @Override + public LocalDate getStart(LocalDate date) { + return date.dayOfMonth().withMinimumValue(); + } + + @Override + public LocalDate getEnd(LocalDate date) { + return date.dayOfMonth().withMaximumValue(); + } + + @Override + public int getItemsBetween(LocalDate start, LocalDate end) { + return Months.monthsBetween(start, end).getMonths(); + } + + @Override + public LocalDate getDateForItemFromDate(int item, LocalDate fromDate) { + return fromDate.plusMonths(item); + } + + @Override + public LocalDate previous(LocalDate date) { + return getStart(date).minusMonths(1); + } + + @Override + public LocalDate next(LocalDate date) { + return getStart(date).plusMonths(1); + } + }, + TWICE_MONTHLY(_("Twice-monthly")) { + @Override + public LocalDate getStart(LocalDate date) { + if (date.getDayOfMonth() <= 15) { + return date.dayOfMonth().withMinimumValue(); + } else { + return date.dayOfMonth().withMinimumValue().plusDays(15); + } + } + + @Override + public LocalDate getEnd(LocalDate date) { + if (date.getDayOfMonth() <= 15) { + return date.dayOfMonth().withMinimumValue().plusDays(14); + } else { + return date.dayOfMonth().withMaximumValue(); + } + } + + @Override + public int getItemsBetween(LocalDate start, LocalDate end) { + return Months.monthsBetween(start, end).getMonths() * 2; + } + + @Override + public LocalDate getDateForItemFromDate(int item, LocalDate fromDate) { + int months = (item % 2 == 0) ? (item / 2) : ((item - 1) / 2); + LocalDate date = fromDate.plusMonths(months); + if (item % 2 != 0) { + if (date.getDayOfMonth() <= 15) { + date = date.dayOfMonth().withMinimumValue().plusDays(15); + } else { + date = date.plusMonths(1).dayOfMonth().withMinimumValue(); + } + } + return date; + } + + @Override + public LocalDate previous(LocalDate date) { + if (date.getDayOfMonth() <= 15) { + return date.minusMonths(1).dayOfMonth().withMinimumValue() + .plusDays(15); + } else { + return date.dayOfMonth().withMinimumValue(); + } + } + + @Override + public LocalDate next(LocalDate date) { + if (date.getDayOfMonth() <= 15) { + return date.dayOfMonth().withMinimumValue().plusDays(15); + } else { + return date.plusMonths(1).dayOfMonth().withMinimumValue(); + } + } + }, + WEEKLY(_("Weekly")) { + @Override + public LocalDate getStart(LocalDate date) { + return date.dayOfWeek().withMinimumValue(); + } + + @Override + public LocalDate getEnd(LocalDate date) { + return date.dayOfWeek().withMaximumValue(); + } + + @Override + public int getItemsBetween(LocalDate start, LocalDate end) { + return Weeks.weeksBetween(start, end).getWeeks(); + } + + @Override + public LocalDate getDateForItemFromDate(int item, LocalDate fromDate) { + return fromDate.plusWeeks(item); + } + + @Override + public LocalDate previous(LocalDate date) { + return getStart(date).minusWeeks(1); + } + + @Override + public LocalDate next(LocalDate date) { + return getStart(date).plusWeeks(1); + } + }; + + private String name; + + private PersonalTimesheetsPeriodicityEnum(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + /** + * Returns the start date of the personal timesheet which includes the + * specified date. + */ + public abstract LocalDate getStart(LocalDate date); + + /** + * Returns the end date of the personal timesheet which includes the + * specified date. + */ + public abstract LocalDate getEnd(LocalDate date); + + /** + * Returns the number of personal timesheets between the specified dates. + */ + public abstract int getItemsBetween(LocalDate start, LocalDate end); + + /** + * Returns the date of the personal timesheet in the position specified by + * item taking into account the fromDate. + */ + public abstract LocalDate getDateForItemFromDate(int item, + LocalDate fromDate); + + /** + * Returns the date of the previous personal timesheet to the one which + * includes the specified date. + */ + public abstract LocalDate previous(LocalDate date); + + /** + * Returns the date of the next personal timesheet to the one which includes + * the specified date. + */ + public abstract LocalDate next(LocalDate date); + +} diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/MonthlyTimesheetsTypeOfWorkHoursBootstrap.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PersonalTimesheetsTypeOfWorkHoursBootstrap.java similarity index 91% rename from libreplan-business/src/main/java/org/libreplan/business/common/entities/MonthlyTimesheetsTypeOfWorkHoursBootstrap.java rename to libreplan-business/src/main/java/org/libreplan/business/common/entities/PersonalTimesheetsTypeOfWorkHoursBootstrap.java index c5597b094..4b338a165 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/MonthlyTimesheetsTypeOfWorkHoursBootstrap.java +++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PersonalTimesheetsTypeOfWorkHoursBootstrap.java @@ -32,7 +32,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; /** - * Fills the attribute {@link Configuration#monthlyTimesheetsTypeOfWorkHours} + * Fills the attribute {@link Configuration#personalTimesheetsTypeOfWorkHours} * with a default value.
* * If possible it uses the "Default" {@link TypeOfWorkHours}, but if it doesn't @@ -47,8 +47,8 @@ import org.springframework.transaction.annotation.Transactional; @Component @Scope("singleton") @BootstrapOrder(1) -public class MonthlyTimesheetsTypeOfWorkHoursBootstrap implements - IMonthlyTimesheetsTypeOfWorkHoursBootstrap { +public class PersonalTimesheetsTypeOfWorkHoursBootstrap implements + IPersonalTimesheetsTypeOfWorkHoursBootstrap { @Autowired private IConfigurationDAO configurationDAO; @@ -73,7 +73,7 @@ public class MonthlyTimesheetsTypeOfWorkHoursBootstrap implements typeOfWorkHours = typeOfWorkHoursDAO.findActive().get(0); } - configuration.setMonthlyTimesheetsTypeOfWorkHours(typeOfWorkHours); + configuration.setPersonalTimesheetsTypeOfWorkHours(typeOfWorkHours); configurationDAO.save(configuration); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/costcategories/daos/TypeOfWorkHoursDAO.java b/libreplan-business/src/main/java/org/libreplan/business/costcategories/daos/TypeOfWorkHoursDAO.java index bfa585272..f20dae7f5 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/costcategories/daos/TypeOfWorkHoursDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/costcategories/daos/TypeOfWorkHoursDAO.java @@ -148,7 +148,7 @@ public class TypeOfWorkHoursDAO extends IntegrationEntityDAO public void checkIsReferencedByOtherEntities(TypeOfWorkHours type) throws ValidationException { checkHasHourCost(type); checkHasWorkReportLine(type); - checkIsMonthlyTimesheetsTypeOfWorkHours(type); + checkIsPersonalTimesheetsTypeOfWorkHours(type); } private void checkHasWorkReportLine(TypeOfWorkHours type) { @@ -174,13 +174,13 @@ public class TypeOfWorkHoursDAO extends IntegrationEntityDAO } } - private void checkIsMonthlyTimesheetsTypeOfWorkHours(TypeOfWorkHours type) { + private void checkIsPersonalTimesheetsTypeOfWorkHours(TypeOfWorkHours type) { Configuration configuration = configurationDAO.getConfiguration(); - if (configuration.getMonthlyTimesheetsTypeOfWorkHours().getId() + if (configuration.getPersonalTimesheetsTypeOfWorkHours().getId() .equals(type.getId())) { throw ValidationException .invalidValue( - "Cannot delete the type of work hours. It is configured as type of work hours for monthly timesheets.", + "Cannot delete the type of work hours. It is configured as type of work hours for personal timesheets.", type); } } diff --git a/libreplan-business/src/main/java/org/libreplan/business/costcategories/entities/TypeOfWorkHours.java b/libreplan-business/src/main/java/org/libreplan/business/costcategories/entities/TypeOfWorkHours.java index d40956e34..1f8c5bbb5 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/costcategories/entities/TypeOfWorkHours.java +++ b/libreplan-business/src/main/java/org/libreplan/business/costcategories/entities/TypeOfWorkHours.java @@ -143,11 +143,11 @@ public class TypeOfWorkHours extends IntegrationEntity implements IHumanIdentifi } } - @AssertTrue(message = "type of work hours for monthly timesheets cannot be disabled") - public boolean checkMonthlyTimesheetsTypeOfWorkHoursNotDisabled() { + @AssertTrue(message = "type of work hours for personal timesheets cannot be disabled") + public boolean checkPersonalTimesheetsTypeOfWorkHoursNotDisabled() { if (!isNewObject() && !getEnabled()) { TypeOfWorkHours typeOfWorkHours = Registry.getConfigurationDAO() - .getConfiguration().getMonthlyTimesheetsTypeOfWorkHours(); + .getConfiguration().getPersonalTimesheetsTypeOfWorkHours(); if (typeOfWorkHours.getId().equals(getId())) { return false; } diff --git a/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/IWorkReportDAO.java b/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/IWorkReportDAO.java index 9add69c28..657d7eba1 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/IWorkReportDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/IWorkReportDAO.java @@ -25,6 +25,7 @@ import java.util.List; import org.joda.time.LocalDate; import org.libreplan.business.common.daos.IIntegrationEntityDAO; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.resources.entities.Resource; import org.libreplan.business.workreports.entities.WorkReport; import org.libreplan.business.workreports.entities.WorkReportType; @@ -47,11 +48,15 @@ public interface IWorkReportDAO extends IIntegrationEntityDAO { int getLastReportYear(); /** - * Returns the {@link WorkReport} of the predefined type monthly timesheet - * for the given resource in the specified date.
+ * Returns the {@link WorkReport} of the predefined type personal timesheet + * for the given resource in the specified date + * depending on the configured periodicity.
* * If there isn't any, it returns null. */ - WorkReport getMonthlyTimesheetWorkReport(Resource resource, LocalDate date); + WorkReport getPersonalTimesheetWorkReport(Resource resource, LocalDate date, + PersonalTimesheetsPeriodicityEnum periodicity); + + boolean isAnyPersonalTimesheetAlreadySaved(); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/WorkReportDAO.java b/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/WorkReportDAO.java index 7b4440ea2..dfd62ad74 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/WorkReportDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/workreports/daos/WorkReportDAO.java @@ -36,6 +36,7 @@ import org.joda.time.LocalDate; import org.libreplan.business.common.IAdHocTransactionService; import org.libreplan.business.common.IOnTransaction; import org.libreplan.business.common.daos.IntegrationEntityDAO; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.orders.daos.IOrderDAO; import org.libreplan.business.orders.entities.OrderElement; @@ -140,12 +141,12 @@ public class WorkReportDAO extends IntegrationEntityDAO @Override @SuppressWarnings("unchecked") - public WorkReport getMonthlyTimesheetWorkReport(Resource resource, - LocalDate date) { + public WorkReport getPersonalTimesheetWorkReport(Resource resource, + LocalDate date, PersonalTimesheetsPeriodicityEnum periodicity) { WorkReportType workReportType; try { workReportType = workReportTypeDAO - .findUniqueByName(PredefinedWorkReportTypes.MONTHLY_TIMESHEETS + .findUniqueByName(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS .getName()); } catch (NonUniqueResultException e) { throw new RuntimeException(e); @@ -155,17 +156,21 @@ public class WorkReportDAO extends IntegrationEntityDAO Criteria criteria = getSession().createCriteria(WorkReport.class); criteria.add(Restrictions.eq("workReportType", workReportType)); - List monthlyTimesheets = criteria.add( + List personalTimesheets = criteria.add( Restrictions.eq("resource", resource)).list(); - for (WorkReport workReport : monthlyTimesheets) { + LocalDate start = periodicity.getStart(date); + LocalDate end = periodicity.getEnd(date); + + for (WorkReport workReport : personalTimesheets) { Set workReportLines = workReport .getWorkReportLines(); if (workReportLines.size() > 0) { - Date workReportDate = workReportLines.iterator().next() - .getDate(); - if (LocalDate.fromDateFields(workReportDate).monthOfYear() - .equals(date.monthOfYear())) { + LocalDate workReportDate = LocalDate + .fromDateFields(workReportLines.iterator().next() + .getDate()); + if (workReportDate.compareTo(start) >= 0 + && workReportDate.compareTo(end) <= 0) { return workReport; } } @@ -174,4 +179,22 @@ public class WorkReportDAO extends IntegrationEntityDAO return null; } + @Override + public boolean isAnyPersonalTimesheetAlreadySaved() { + WorkReportType workReportType; + try { + workReportType = workReportTypeDAO + .findUniqueByName(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS + .getName()); + } catch (NonUniqueResultException e) { + throw new RuntimeException(e); + } catch (InstanceNotFoundException e) { + throw new RuntimeException(e); + } + + Criteria criteria = getSession().createCriteria(WorkReport.class); + criteria.add(Restrictions.eq("workReportType", workReportType)); + return criteria.list().isEmpty(); + } + } diff --git a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/PredefinedWorkReportTypes.java b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/PredefinedWorkReportTypes.java index 920ce3640..f6d243cab 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/PredefinedWorkReportTypes.java +++ b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/PredefinedWorkReportTypes.java @@ -27,7 +27,7 @@ package org.libreplan.business.workreports.entities; */ public enum PredefinedWorkReportTypes { DEFAULT("Default", false, false, false), - MONTHLY_TIMESHEETS("Monthly timesheets", false, true, false); + PERSONAL_TIMESHEETS("Personal timesheets", false, true, false); private WorkReportType workReportType; diff --git a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReport.java b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReport.java index 2ba500d53..b1d501fba 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReport.java +++ b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReport.java @@ -34,10 +34,10 @@ import org.hibernate.validator.AssertTrue; import org.hibernate.validator.NotNull; import org.hibernate.validator.Valid; import org.joda.time.LocalDate; -import org.joda.time.LocalDate.Property; import org.libreplan.business.common.IntegrationEntity; import org.libreplan.business.common.Registry; import org.libreplan.business.common.entities.EntitySequence; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.labels.entities.Label; import org.libreplan.business.labels.entities.LabelType; @@ -470,9 +470,9 @@ public class WorkReport extends IntegrationEntity implements return result; } - @AssertTrue(message = "only one timesheet line per day and task is allowed in monthly timesheets") - public boolean checkConstraintOnlyOneWorkReportLinePerDayAndOrderElementInMonthlyTimesheet() { - if (!getWorkReportType().isMonthlyTimesheetsType()) { + @AssertTrue(message = "only one timesheet line per day and task is allowed in personal timesheets") + public boolean checkConstraintOnlyOneWorkReportLinePerDayAndOrderElementInPersonalTimesheet() { + if (!getWorkReportType().isPersonalTimesheetsType()) { return true; } @@ -492,9 +492,9 @@ public class WorkReport extends IntegrationEntity implements return true; } - @AssertTrue(message = "In monthly timesheets, all timesheet lines should be in the same month") - public boolean checkConstraintAllWorkReportLinesInTheSameMonthInMonthlyTimesheet() { - if (!getWorkReportType().isMonthlyTimesheetsType()) { + @AssertTrue(message = "In personal timesheets, all timesheet lines should be in the same period") + public boolean checkConstraintAllWorkReportLinesInTheSamePeriodInPersonalTimesheet() { + if (!getWorkReportType().isPersonalTimesheetsType()) { return true; } @@ -502,10 +502,14 @@ public class WorkReport extends IntegrationEntity implements return true; } - Property dayOfMonth = LocalDate.fromDateFields( - workReportLines.iterator().next().getDate()).dayOfMonth(); - LocalDate min = dayOfMonth.withMinimumValue(); - LocalDate max = dayOfMonth.withMaximumValue(); + LocalDate workReportDate = LocalDate.fromDateFields(workReportLines + .iterator().next().getDate()); + PersonalTimesheetsPeriodicityEnum periodicity = Registry + .getConfigurationDAO() + .getConfigurationWithReadOnlyTransaction() + .getPersonalTimesheetsPeriodicity(); + LocalDate min = periodicity.getStart(workReportDate); + LocalDate max = periodicity.getEnd(workReportDate); for (WorkReportLine line : workReportLines) { LocalDate date = LocalDate.fromDateFields(line.getDate()); @@ -516,9 +520,9 @@ public class WorkReport extends IntegrationEntity implements return true; } - @AssertTrue(message = "resource has to be bound to a user in monthly timesheets") - public boolean checkConstraintResourceIsBoundInMonthlyTimesheet() { - if (!getWorkReportType().isMonthlyTimesheetsType()) { + @AssertTrue(message = "resource has to be bound to a user in personal timesheets") + public boolean checkConstraintResourceIsBoundInPersonalTimesheet() { + if (!getWorkReportType().isPersonalTimesheetsType()) { return true; } diff --git a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportType.java b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportType.java index cae7e4853..f644dd7b5 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportType.java +++ b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportType.java @@ -524,11 +524,11 @@ public class WorkReportType extends IntegrationEntity implements IHumanIdentifia return name; } - public boolean isMonthlyTimesheetsType() { + public boolean isPersonalTimesheetsType() { if (StringUtils.isBlank(name)) { return false; } - return name.equals(PredefinedWorkReportTypes.MONTHLY_TIMESHEETS + return name.equals(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS .getName()); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportTypeBootstrap.java b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportTypeBootstrap.java index 1f80ff776..a6bee16dd 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportTypeBootstrap.java +++ b/libreplan-business/src/main/java/org/libreplan/business/workreports/entities/WorkReportTypeBootstrap.java @@ -35,7 +35,7 @@ import org.springframework.transaction.annotation.Transactional; * If there is no work report types, it creates a default work report type.
* * Even if there are already some work report types defined, it creates a work - * report type for monthly timesheets if it is not present in the database yet. + * report type for personal timesheets if it is not present in the database yet. * * @author Ignacio Díaz Teijido * @author Manuel Rego Casasnovas @@ -59,7 +59,7 @@ public class WorkReportTypeBootstrap implements IWorkReportTypeBootstrap { createAndSaveWorkReportType(predefinedWorkReportType); } } else { - createMonthlyTimesheetsWorkReportTypeIfNeeded(); + createPersonalTimesheetsWorkReportTypeIfNeeded(); } } @@ -74,15 +74,15 @@ public class WorkReportTypeBootstrap implements IWorkReportTypeBootstrap { workReportTypeDAO.save(workReportType); } - private void createMonthlyTimesheetsWorkReportTypeIfNeeded() { + private void createPersonalTimesheetsWorkReportTypeIfNeeded() { try { workReportTypeDAO - .findUniqueByName(PredefinedWorkReportTypes.MONTHLY_TIMESHEETS + .findUniqueByName(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS .getName()); } catch (NonUniqueResultException e) { throw new RuntimeException(e); } catch (InstanceNotFoundException e) { - createAndSaveWorkReportType(PredefinedWorkReportTypes.MONTHLY_TIMESHEETS); + createAndSaveWorkReportType(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS); } } diff --git a/libreplan-business/src/main/resources/db.changelog-1.3.xml b/libreplan-business/src/main/resources/db.changelog-1.3.xml index 5d7b3b7e4..681b51255 100644 --- a/libreplan-business/src/main/resources/db.changelog-1.3.xml +++ b/libreplan-business/src/main/resources/db.changelog-1.3.xml @@ -16,4 +16,44 @@ ALTER TABLE task_element MODIFY notes TEXT - \ No newline at end of file + + + Update work_report_type name from "Monthly timesheets" to "Personal + timehsheets" + + + + name='Monthly timesheets' + + + + + Add personal_timesheets_periodicity column to configuration + + + + + + + + + + + Rename column monthly_timesheets_type_of_work_hours to + personal_timesheets_type_of_work_hours in configuration table + + + + + + + diff --git a/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Configuration.hbm.xml b/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Configuration.hbm.xml index 7da305270..3df6cd30d 100644 --- a/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Configuration.hbm.xml +++ b/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Configuration.hbm.xml @@ -79,8 +79,14 @@ - + + + + + org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum + + diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java index ef3517f47..218cb25c7 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java @@ -40,6 +40,7 @@ import org.libreplan.business.common.entities.Configuration; import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.entities.EntitySequence; import org.libreplan.business.common.entities.LDAPConfiguration; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.common.entities.ProgressType; import org.libreplan.business.common.exceptions.ValidationException; import org.libreplan.business.costcategories.entities.TypeOfWorkHours; @@ -869,13 +870,49 @@ public class ConfigurationController extends GenericForwardComposer { configurationModel.setCurrency(currencyCode); } - public TypeOfWorkHours getMonthlyTimesheetsTypeOfWorkHours() { - return configurationModel.getMonthlyTimesheetsTypeOfWorkHours(); + public TypeOfWorkHours getPersonalTimesheetsTypeOfWorkHours() { + return configurationModel.getPersonalTimesheetsTypeOfWorkHours(); } - public void setMonthlyTimesheetsTypeOfWorkHours( + public void setPersonalTimesheetsTypeOfWorkHours( TypeOfWorkHours typeOfWorkHours) { - configurationModel.setMonthlyTimesheetsTypeOfWorkHours(typeOfWorkHours); + configurationModel.setPersonalTimesheetsTypeOfWorkHours(typeOfWorkHours); + } + + public List getPersonalTimesheetsPeriodicities() { + return Arrays.asList(PersonalTimesheetsPeriodicityEnum.values()); + } + + public ListitemRenderer getPersonalTimesheetsPeriodicityRenderer() { + return new ListitemRenderer() { + @Override + public void render(Listitem item, Object data) throws Exception { + PersonalTimesheetsPeriodicityEnum periodicity = (PersonalTimesheetsPeriodicityEnum) data; + item.setLabel(_(periodicity.getName())); + item.setValue(periodicity); + } + }; + } + + public PersonalTimesheetsPeriodicityEnum getSelectedPersonalTimesheetsPeriodicity() { + return configurationModel.getPersonalTimesheetsPeriodicity(); + } + + public void setSelectedPersonalTimesheetsPeriodicity( + PersonalTimesheetsPeriodicityEnum personalTimesheetsPeriodicity) { + configurationModel + .setPersonalTimesheetsPeriodicity(personalTimesheetsPeriodicity); + } + + public boolean isPersonalTimesheetsPeriodicityDisabled() { + return configurationModel.isAnyPersonalTimesheetAlreadySaved(); + } + + public String getPersonalTimesheetsPeriodicityTooltip() { + if (isPersonalTimesheetsPeriodicityDisabled()) { + return _("Periocity cannot be changed because there is already any personal timesheet stored"); + } + return ""; } } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationModel.java index 1e819dae3..ccb6d75df 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationModel.java @@ -43,10 +43,12 @@ import org.libreplan.business.common.entities.Configuration; import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.entities.EntitySequence; import org.libreplan.business.common.entities.LDAPConfiguration; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.common.entities.ProgressType; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.common.exceptions.ValidationException; import org.libreplan.business.costcategories.entities.TypeOfWorkHours; +import org.libreplan.business.workreports.daos.IWorkReportDAO; import org.libreplan.web.common.concurrentdetection.OnConcurrentModification; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; @@ -82,6 +84,9 @@ public class ConfigurationModel implements IConfigurationModel { @Autowired private IEntitySequenceDAO entitySequenceDAO; + @Autowired + private IWorkReportDAO workReportDAO; + @Override @Transactional(readOnly = true) public List getCalendars() { @@ -132,7 +137,7 @@ public class ConfigurationModel implements IConfigurationModel { private void forceLoad(Configuration configuration) { forceLoad(configuration.getDefaultCalendar()); - forceLoad(configuration.getMonthlyTimesheetsTypeOfWorkHours()); + forceLoad(configuration.getPersonalTimesheetsTypeOfWorkHours()); } private void forceLoad(BaseCalendar calendar) { @@ -622,16 +627,34 @@ public class ConfigurationModel implements IConfigurationModel { } @Override - public TypeOfWorkHours getMonthlyTimesheetsTypeOfWorkHours() { - return configuration.getMonthlyTimesheetsTypeOfWorkHours(); + public TypeOfWorkHours getPersonalTimesheetsTypeOfWorkHours() { + return configuration.getPersonalTimesheetsTypeOfWorkHours(); } @Override - public void setMonthlyTimesheetsTypeOfWorkHours( + public void setPersonalTimesheetsTypeOfWorkHours( TypeOfWorkHours typeOfWorkHours) { if (configuration != null) { - configuration.setMonthlyTimesheetsTypeOfWorkHours(typeOfWorkHours); + configuration.setPersonalTimesheetsTypeOfWorkHours(typeOfWorkHours); } } + @Override + public PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() { + return configuration.getPersonalTimesheetsPeriodicity(); + } + + @Override + public void setPersonalTimesheetsPeriodicity( + PersonalTimesheetsPeriodicityEnum personalTimesheetsPeriodicity) { + configuration + .setPersonalTimesheetsPeriodicity(personalTimesheetsPeriodicity); + } + + @Override + @Transactional(readOnly = true) + public boolean isAnyPersonalTimesheetAlreadySaved() { + return !workReportDAO.isAnyPersonalTimesheetAlreadySaved(); + } + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/IConfigurationModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/IConfigurationModel.java index 8579cd6cb..6430a17b8 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/IConfigurationModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/IConfigurationModel.java @@ -28,6 +28,7 @@ import org.libreplan.business.calendars.entities.BaseCalendar; import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.entities.EntitySequence; import org.libreplan.business.common.entities.LDAPConfiguration; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.common.entities.ProgressType; import org.libreplan.business.costcategories.entities.TypeOfWorkHours; @@ -168,8 +169,15 @@ public interface IConfigurationModel { void setCurrency(String currencyCode); - TypeOfWorkHours getMonthlyTimesheetsTypeOfWorkHours(); + TypeOfWorkHours getPersonalTimesheetsTypeOfWorkHours(); - void setMonthlyTimesheetsTypeOfWorkHours(TypeOfWorkHours typeOfWorkHours); + void setPersonalTimesheetsTypeOfWorkHours(TypeOfWorkHours typeOfWorkHours); + + PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity(); + + void setPersonalTimesheetsPeriodicity( + PersonalTimesheetsPeriodicityEnum personalTimesheetsPeriodicity); + + boolean isAnyPersonalTimesheetAlreadySaved(); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMyTasksAreaModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMyTasksAreaModel.java index 7a1388b6b..18b15674a 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMyTasksAreaModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMyTasksAreaModel.java @@ -21,6 +21,8 @@ package org.libreplan.web.users.dashboard; import java.util.List; +import org.libreplan.business.common.entities.Configuration; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.planner.entities.SpecificResourceAllocation; import org.libreplan.business.planner.entities.Task; import org.libreplan.business.planner.entities.TaskElement; @@ -40,4 +42,10 @@ public interface IMyTasksAreaModel { */ List getTasks(); + /** + * Returns the {@link PersonalTimesheetsPeriodicityEnum} from + * {@link Configuration}. + */ + PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity(); + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetController.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetController.java similarity index 85% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetController.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetController.java index 6308b09e2..4e5aa4614 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetController.java @@ -25,12 +25,12 @@ import org.libreplan.web.common.entrypoints.EntryPoint; import org.libreplan.web.common.entrypoints.EntryPoints; /** - * Entry points for monthly timesheet creation/edition window + * Entry points for personal timesheet creation/edition window * * @author Manuel Rego Casasnovas */ -@EntryPoints(page = "/myaccount/monthlyTimesheet.zul", registerAs = "monthlyTimesheetController") -public interface IMonthlyTimesheetController { +@EntryPoints(page = "/myaccount/personalTimesheet.zul", registerAs = "personalTimesheetController") +public interface IPersonalTimesheetController { @EntryPoint("date") void goToCreateOrEditForm(LocalDate date); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetModel.java similarity index 67% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetModel.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetModel.java index 908a8cddd..02fdf6019 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetModel.java @@ -22,6 +22,8 @@ package org.libreplan.web.users.dashboard; import java.util.List; import org.joda.time.LocalDate; +import org.libreplan.business.common.entities.Configuration; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.orders.entities.Order; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.resources.entities.Resource; @@ -30,40 +32,38 @@ import org.libreplan.business.workingday.EffortDuration; import org.libreplan.business.workreports.entities.WorkReport; /** - * Interface for creation/edition of a monthly timesheet model + * Interface for creation/edition of a personal timesheet model * * @author Manuel Rego Casasnovas */ -public interface IMonthlyTimesheetModel { +public interface IPersonalTimesheetModel { /** - * Edits the monthly timesheet for the specified date and + * Edits the personal timesheet for the specified date and * resource bound to current user or creates a new one if it doesn't exist * yet. */ void initCreateOrEdit(LocalDate date); /** - * Edits the monthly timesheet for the specified date and + * Edits the personal timesheet for the specified date and * resource bound to the {@link Worker} specified by the * resource or creates a new one if it doesn't exist yet. */ void initCreateOrEdit(LocalDate date, Resource resource); /** - * Returns the date of the monthly timesheet (only year and month should - * take into account as the day is not important to define a monthly - * timesheet). + * Returns the date of the personal timesheet. */ LocalDate getDate(); /** - * Returns the first day of the month of the current monthly timesheet. + * Returns the first day of the current personal timesheet. */ LocalDate getFirstDay(); /** - * Returns the last day of the month of the current monthly timesheet. + * Returns the last day of the current personal timesheet. */ LocalDate getLastDate(); @@ -79,45 +79,45 @@ public interface IMonthlyTimesheetModel { List getOrderElements(); /** - * Returns the {@link EffortDuration} in the current monthly timesheet for + * Returns the {@link EffortDuration} in the current personal timesheet for * the specified orderElement and date. */ EffortDuration getEffortDuration(OrderElement orderElement, LocalDate date); /** - * Sets the {@link EffortDuration} in the current monthly timesheet for the + * Sets the {@link EffortDuration} in the current personal timesheet for the * specified orderElement and date.
* - * Marks the current monthly timesheet as modified. + * Marks the current personal timesheet as modified. */ void setEffortDuration(OrderElement orderElement, LocalDate date, EffortDuration effortDuration); /** - * Save {@link WorkReport} for the monthly timesheet. + * Save {@link WorkReport} for the personal timesheet. */ void save(); /** - * Cancel changes in {@link WorkReport} for the monthly timesheet. + * Cancel changes in {@link WorkReport} for the personal timesheet. */ void cancel(); /** - * Returns the {@link EffortDuration} in the current monthly timesheet for + * Returns the {@link EffortDuration} in the current personal timesheet for * the specified orderElement. */ EffortDuration getEffortDuration(OrderElement orderElement); /** * Returns the {@link EffortDuration} for all the {@link OrderElement - * OrderElements} in the current monthly timesheet in the specified + * OrderElements} in the current personal timesheet in the specified * date. */ EffortDuration getEffortDuration(LocalDate date); /** - * Returns the total {@link EffortDuration} for the currently monthly + * Returns the total {@link EffortDuration} for the currently personal * timesheet. */ EffortDuration getTotalEffortDuration(); @@ -129,7 +129,7 @@ public interface IMonthlyTimesheetModel { EffortDuration getResourceCapacity(LocalDate date); /** - * Adds the orderElement to the current monthly timehseet. + * Adds the orderElement to the current personal timehseet. */ void addOrderElement(OrderElement orderElement); @@ -140,22 +140,22 @@ public interface IMonthlyTimesheetModel { Order getOrder(OrderElement orderElement); /** - * Returns true if current monthly timesheet has been modified + * Returns true if current personal timesheet has been modified * by the user. */ boolean isModified(); /** - * Checks if current monthly timesheet is the first month, that means the + * Checks if current personal timesheet is the first period, that means the * first activation period of the resource. */ - boolean isFirstMonth(); + boolean isFirstPeriod(); /** - * Checks if current monthly timesheet is the last month, that means the + * Checks if current personal timesheet is the last period, that means the * next month of current date. */ - boolean isLastMonth(); + boolean isLastPeriod(); /** * Returns true if the value for the specified orderElement in @@ -165,7 +165,7 @@ public interface IMonthlyTimesheetModel { /** * Returns true or false depending on if it's - * editing a monthly timesheet of the current user or not.
+ * editing a personal timesheet of the current user or not.
* * That means if you entered via: *
    @@ -177,30 +177,54 @@ public interface IMonthlyTimesheetModel { boolean isCurrentUser(); /** - * Returns true if the resource of the current monthly + * Returns true if the resource of the current personal * timesheet has any effort reported in other {@link WorkReport WorkReports} - * in the month of the timesheet. + * in the period of the timesheet. */ boolean hasOtherReports(); /** * Returns the {@link EffortDuration} of the specified * orderElement from other {@link WorkReport WorkReports} for - * the current resource in the month of the timesheet.
    + * the current resource in the period of the timesheet.
    */ EffortDuration getOtherEffortDuration(OrderElement orderElement); /** * Returns the {@link EffortDuration} in the specified date * from other {@link WorkReport WorkReports} for the current resource in the - * month of the timesheet. + * period of the timesheet. */ EffortDuration getOtherEffortDuration(LocalDate date); /** * Returns the total {@link EffortDuration} from other {@link WorkReport - * WorkReports} for the current resource in the month of the timesheet. + * WorkReports} for the current resource in the period of the timesheet. */ EffortDuration getTotalOtherEffortDuration(); + /** + * Returns the {@link PersonalTimesheetsPeriodicityEnum} from + * {@link Configuration}. + */ + PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity(); + + /** + * Returns the string that represents the personal timesheet depending on + * the configured periodicity. + */ + String getTimesheetString(); + + /** + * Returns the previous personal timesheet to the current one depending on + * the configured periodicity. + */ + LocalDate getPrevious(); + + /** + * Returns the next personal timesheet to the current one depending on the + * configured periodicity. + */ + LocalDate getNext(); + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetsAreaModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetsAreaModel.java similarity index 67% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetsAreaModel.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetsAreaModel.java index d1fe00664..4fc7bd3a9 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IMonthlyTimesheetsAreaModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/IPersonalTimesheetsAreaModel.java @@ -22,30 +22,31 @@ package org.libreplan.web.users.dashboard; import java.util.List; import org.libreplan.business.calendars.entities.CalendarAvailability; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.users.entities.User; import org.libreplan.business.workreports.entities.WorkReport; /** - * Interface for "Monthly timesheets" area model + * Interface for "Personal timesheets" area model * * @author Manuel Rego Casasnovas */ -public interface IMonthlyTimesheetsAreaModel { +public interface IPersonalTimesheetsAreaModel { /** - * Returns the list of {@link MonthlyTimesheetDTO MonthlyTimesheets} for the - * resource bound to current {@link User}.
    + * Returns the list of {@link PersonalTimesheetDTO PersonalTimesheetDTOs} + * for the resource bound to current {@link User}.
    * * There's no need that a {@link WorkReport} is saved in order to a - * {@link MonthlyTimesheetDTO} exists for a month.
    + * {@link PersonalTimesheetDTO} exists for a period.
    * - * The list of {@link MonthlyTimesheetDTO MonthlyTimesheets} will be since the - * date the resource is activated in the system (checking + * The list of {@link PersonalTimesheetDTO PersonalTimesheetDTOs} will be + * since the date the resource is activated in the system (checking * {@link CalendarAvailability} for the resource) to next month of current * date. */ - List getMonthlyTimesheets(); + List getPersonalTimesheets(); /** * Returns the number of different {@link OrderElement OrderElements} with @@ -53,4 +54,9 @@ public interface IMonthlyTimesheetsAreaModel { */ int getNumberOfOrderElementsWithTrackedTime(WorkReport workReport); + /** + * Returns configured periodicity for personal timesheets. + */ + PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity(); + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaController.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaController.java index 82ae894e2..75b214b94 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaController.java @@ -29,6 +29,7 @@ import javax.annotation.Resource; import org.joda.time.LocalDate; import org.libreplan.business.advance.entities.AdvanceMeasurement; import org.libreplan.business.advance.entities.DirectAdvanceAssignment; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.orders.entities.SumChargedEffort; import org.libreplan.business.planner.entities.Task; @@ -54,7 +55,7 @@ public class MyTasksAreaController extends GenericForwardComposer { private IMyTasksAreaModel myTasksAreaModel; @Resource - private IMonthlyTimesheetController monthlyTimesheetController; + private IPersonalTimesheetController personalTimesheetController; private RowRenderer tasksRenderer = new RowRenderer() { @@ -112,17 +113,19 @@ public class MyTasksAreaController extends GenericForwardComposer { EventListener trackTimeButtonListener = new EventListener() { @Override public void onEvent(Event event) throws Exception { - monthlyTimesheetController - .goToCreateOrEditForm(getMonthlyTimesheetDateForTask(task)); + personalTimesheetController + .goToCreateOrEditForm(getPersonalTimesheetDateForTask(task)); } - private LocalDate getMonthlyTimesheetDateForTask(Task task) { + private LocalDate getPersonalTimesheetDateForTask(Task task) { LocalDate start = task.getStartAsLocalDate(); LocalDate end = task.getEndAsLocalDate(); LocalDate currentDate = new LocalDate(); - LocalDate min = currentDate.dayOfMonth().withMinimumValue(); - LocalDate max = currentDate.dayOfMonth().withMaximumValue(); + PersonalTimesheetsPeriodicityEnum periodicity = myTasksAreaModel + .getPersonalTimesheetsPeriodicity(); + LocalDate min = periodicity.getStart(currentDate); + LocalDate max = periodicity.getEnd(currentDate); if (dateBetween(start, min, max)) { return start; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaModel.java index b1cb9eff3..5b6675d78 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MyTasksAreaModel.java @@ -26,6 +26,8 @@ import java.util.List; import org.libreplan.business.advance.entities.AdvanceMeasurement; import org.libreplan.business.advance.entities.DirectAdvanceAssignment; +import org.libreplan.business.common.daos.IConfigurationDAO; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.planner.daos.IResourceAllocationDAO; import org.libreplan.business.planner.entities.SpecificResourceAllocation; import org.libreplan.business.planner.entities.Task; @@ -53,6 +55,9 @@ public class MyTasksAreaModel implements IMyTasksAreaModel { @Autowired private IScenarioManager scenarioManager; + @Autowired + private IConfigurationDAO configurationDAO; + @Override @Transactional(readOnly = true) public List getTasks() { @@ -103,4 +108,11 @@ public class MyTasksAreaModel implements IMyTasksAreaModel { } } + @Override + @Transactional(readOnly = true) + public PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() { + return configurationDAO.getConfiguration() + .getPersonalTimesheetsPeriodicity(); + } + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetController.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetController.java similarity index 78% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetController.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetController.java index d6b47cc74..6894e195c 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetController.java @@ -67,20 +67,20 @@ import org.zkoss.zul.Textbox; import org.zkoss.zul.api.Grid; /** - * Controller for creation/edition of a monthly timesheet + * Controller for creation/edition of a personal timesheet * * @author Manuel Rego Casasnovas */ @SuppressWarnings("serial") -public class MonthlyTimesheetController extends GenericForwardComposer - implements IMonthlyTimesheetController { +public class PersonalTimesheetController extends GenericForwardComposer + implements IPersonalTimesheetController { private final static String EFFORT_DURATION_TEXTBOX_WIDTH = "30px"; private final static String TOTAL_DURATION_TEXTBOX_WIDTH = "50px"; private final static String WORK_REPORTS_URL = "/workreports/workReport.zul"; - private IMonthlyTimesheetModel monthlyTimesheetModel; + private IPersonalTimesheetModel personalTimesheetModel; private IURLHandlerRegistry URLHandlerRegistry; @@ -90,15 +90,15 @@ public class MonthlyTimesheetController extends GenericForwardComposer private BandboxSearch orderElementBandboxSearch; - private Button previousMonth; + private Button previousPeriod; - private Button nextMonth; + private Button nextPeriod; private Component messagesContainer; private IMessagesForUser messagesForUser; - private Label summaryTotalMonthlyTimesheet; + private Label summaryTotalPersonalTimesheet; private Label summaryTotalOther; @@ -111,7 +111,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer private Label summaryTotalExtra; @Resource - private IMonthlyTimesheetController monthlyTimesheetController; + private IPersonalTimesheetController personalTimesheetController; private RowRenderer rowRenderer = new RowRenderer() { @@ -120,14 +120,14 @@ public class MonthlyTimesheetController extends GenericForwardComposer @Override public void render(Row row, Object data) throws Exception { - MonthlyTimesheetRow monthlyTimesheetRow = (MonthlyTimesheetRow) data; + PersonalTimesheetRow personalTimesheetRow = (PersonalTimesheetRow) data; - initMonthlyTimesheetDates(); + initPersonalTimesheetDates(); - switch (monthlyTimesheetRow.getType()) { + switch (personalTimesheetRow.getType()) { case ORDER_ELEMENT: renderOrderElementRow(row, - monthlyTimesheetRow.getOrderElemement()); + personalTimesheetRow.getOrderElemement()); break; case OTHER: renderOtherRow(row); @@ -146,24 +146,24 @@ public class MonthlyTimesheetController extends GenericForwardComposer break; default: throw new IllegalStateException( - "Unknown MonthlyTimesheetRow type: " - + monthlyTimesheetRow.getType()); + "Unknown PersonalTimesheetRow type: " + + personalTimesheetRow.getType()); } } - private void initMonthlyTimesheetDates() { - first = monthlyTimesheetModel.getFirstDay(); - last = monthlyTimesheetModel.getLastDate(); + private void initPersonalTimesheetDates() { + first = personalTimesheetModel.getFirstDay(); + last = personalTimesheetModel.getLastDate(); } private void renderOrderElementRow(Row row, OrderElement orderElement) { - Util.appendLabel(row, monthlyTimesheetModel.getOrder(orderElement) + Util.appendLabel(row, personalTimesheetModel.getOrder(orderElement) .getName()); Util.appendLabel(row, orderElement.getName()); appendInputsForDays(row, orderElement); - if (monthlyTimesheetModel.hasOtherReports()) { + if (personalTimesheetModel.hasOtherReports()) { appendOtherColumn(row, orderElement); } @@ -182,7 +182,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer Util.bind(textbox, new Util.Getter() { @Override public String get() { - EffortDuration effortDuration = monthlyTimesheetModel + EffortDuration effortDuration = personalTimesheetModel .getEffortDuration(orderElement, textboxDate); return effortDurationToString(effortDuration); } @@ -194,7 +194,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer throw new WrongValueException(textbox, _("Invalid Effort Duration")); } - monthlyTimesheetModel.setEffortDuration(orderElement, + personalTimesheetModel.setEffortDuration(orderElement, textboxDate, effortDuration); markAsModified(textbox); updateTotals(orderElement, textboxDate); @@ -212,13 +212,13 @@ public class MonthlyTimesheetController extends GenericForwardComposer }); - if (monthlyTimesheetModel + if (personalTimesheetModel .wasModified(orderElement, textboxDate)) { markAsModified(textbox); } Cell cell = getCenteredCell(textbox); - if (monthlyTimesheetModel.getResourceCapacity(day).isZero()) { + if (personalTimesheetModel.getResourceCapacity(day).isZero()) { setBackgroundNonCapacityCell(cell); } row.appendChild(cell); @@ -232,7 +232,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer private void appendOtherColumn(Row row, final OrderElement orderElement) { Textbox other = getDisabledTextbox(getOtherRowTextboxId(orderElement)); - other.setValue(effortDurationToString(monthlyTimesheetModel.getOtherEffortDuration(orderElement))); + other.setValue(effortDurationToString(personalTimesheetModel.getOtherEffortDuration(orderElement))); row.appendChild(getCenteredCell(other)); } @@ -242,9 +242,9 @@ public class MonthlyTimesheetController extends GenericForwardComposer } private void updateTotalColumn(OrderElement orderElement) { - EffortDuration effort = monthlyTimesheetModel + EffortDuration effort = personalTimesheetModel .getEffortDuration(orderElement); - effort = effort.plus(monthlyTimesheetModel + effort = effort.plus(personalTimesheetModel .getOtherEffortDuration(orderElement)); Textbox textbox = (Textbox) timesheet @@ -272,7 +272,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer for (LocalDate day = first; day.compareTo(last) <= 0; day = day .plusDays(1)) { Cell cell = getCenteredCell(getDisabledTextbox(getTotalColumnTextboxId(day))); - if (monthlyTimesheetModel.getResourceCapacity(day).isZero()) { + if (personalTimesheetModel.getResourceCapacity(day).isZero()) { setBackgroundNonCapacityCell(cell); } row.appendChild(cell); @@ -282,9 +282,9 @@ public class MonthlyTimesheetController extends GenericForwardComposer } private void updateTotalRow(LocalDate date) { - EffortDuration effort = monthlyTimesheetModel + EffortDuration effort = personalTimesheetModel .getEffortDuration(date); - effort = effort.plus(monthlyTimesheetModel + effort = effort.plus(personalTimesheetModel .getOtherEffortDuration(date)); Textbox textbox = (Textbox) timesheet @@ -294,7 +294,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer private void appendTotalColumn(Row row) { Cell totalCell = getCenteredCell(getDisabledTextbox(getTotalTextboxId())); - if (monthlyTimesheetModel.hasOtherReports()) { + if (personalTimesheetModel.hasOtherReports()) { totalCell.setColspan(2); } row.appendChild(totalCell); @@ -302,9 +302,9 @@ public class MonthlyTimesheetController extends GenericForwardComposer } private void updateTotalColumn() { - EffortDuration effort = monthlyTimesheetModel + EffortDuration effort = personalTimesheetModel .getTotalEffortDuration(); - effort = effort.plus(monthlyTimesheetModel + effort = effort.plus(personalTimesheetModel .getTotalOtherEffortDuration()); Textbox textbox = (Textbox) timesheet @@ -322,12 +322,12 @@ public class MonthlyTimesheetController extends GenericForwardComposer for (LocalDate day = first; day.compareTo(last) <= 0; day = day .plusDays(1)) { - EffortDuration other = monthlyTimesheetModel + EffortDuration other = personalTimesheetModel .getOtherEffortDuration(day); Cell cell = getCenteredCell(getDisabledTextbox( getOtherColumnTextboxId(day), other)); - if (monthlyTimesheetModel.getResourceCapacity(day).isZero()) { + if (personalTimesheetModel.getResourceCapacity(day).isZero()) { setBackgroundNonCapacityCell(cell); } row.appendChild(cell); @@ -351,12 +351,12 @@ public class MonthlyTimesheetController extends GenericForwardComposer for (LocalDate day = first; day.compareTo(last) <= 0; day = day .plusDays(1)) { - EffortDuration capacity = monthlyTimesheetModel + EffortDuration capacity = personalTimesheetModel .getResourceCapacity(day); Cell cell = getCenteredCell(getDisabledTextbox( getCapcityColumnTextboxId(day), capacity)); - if (monthlyTimesheetModel.getResourceCapacity(day).isZero()) { + if (personalTimesheetModel.getResourceCapacity(day).isZero()) { setBackgroundNonCapacityCell(cell); } row.appendChild(cell); @@ -366,7 +366,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer Cell totalCapacityCell = getCenteredCell(getDisabledTextbox( getTotalCapacityTextboxId(), totalCapacity)); - if (monthlyTimesheetModel.hasOtherReports()) { + if (personalTimesheetModel.hasOtherReports()) { totalCapacityCell.setColspan(2); } row.appendChild(totalCapacityCell); @@ -382,7 +382,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer for (LocalDate day = first; day.compareTo(last) <= 0; day = day .plusDays(1)) { Cell cell = getCenteredCell(getDisabledTextbox(getExtraColumnTextboxId(day))); - if (monthlyTimesheetModel.getResourceCapacity(day).isZero()) { + if (personalTimesheetModel.getResourceCapacity(day).isZero()) { setBackgroundNonCapacityCell(cell); } row.appendChild(cell); @@ -414,7 +414,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer private void appendTotalExtra(Row row) { Cell totalExtraCell = getCenteredCell(getDisabledTextbox(getTotalExtraTextboxId())); - if (monthlyTimesheetModel.hasOtherReports()) { + if (personalTimesheetModel.hasOtherReports()) { totalExtraCell.setColspan(2); } row.appendChild(totalExtraCell); @@ -478,7 +478,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer checkUserComesFromEntryPointsOrSendForbiddenCode(); - URLHandlerRegistry.getRedirectorFor(IMonthlyTimesheetController.class) + URLHandlerRegistry.getRedirectorFor(IPersonalTimesheetController.class) .register(this, page); } @@ -508,7 +508,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR)); breadcrumbs.appendChild(new Label(_("My dashboard"))); breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR)); - breadcrumbs.appendChild(new Label(_("Monthly timesheet"))); + breadcrumbs.appendChild(new Label(_("Personal timesheet"))); } @Override @@ -517,7 +517,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer Util.sendForbiddenStatusCodeInHttpServletResponse(); } - monthlyTimesheetModel.initCreateOrEdit(date); + personalTimesheetModel.initCreateOrEdit(date); initTimesheet(date); } @@ -528,7 +528,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer Util.sendForbiddenStatusCodeInHttpServletResponse(); } - monthlyTimesheetModel.initCreateOrEdit(date, resource); + personalTimesheetModel.initCreateOrEdit(date, resource); initTimesheet(date); } @@ -549,7 +549,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer private void createColumns(LocalDate date) { createProjectAndTaskColumns(); createColumnsForDays(date); - if (monthlyTimesheetModel.hasOtherReports()) { + if (personalTimesheetModel.hasOtherReports()) { createOtherColumn(); } createTotalColumn(); @@ -568,8 +568,10 @@ public class MonthlyTimesheetController extends GenericForwardComposer } private void createColumnsForDays(LocalDate date) { - LocalDate start = date.dayOfMonth().withMinimumValue(); - LocalDate end = date.dayOfMonth().withMaximumValue(); + LocalDate start = personalTimesheetModel + .getPersonalTimesheetsPeriodicity().getStart(date); + LocalDate end = personalTimesheetModel + .getPersonalTimesheetsPeriodicity().getEnd(date); for (LocalDate day = start; day.compareTo(end) <= 0; day = day .plusDays(1)) { @@ -596,24 +598,24 @@ public class MonthlyTimesheetController extends GenericForwardComposer columns.appendChild(total); } - public String getDate() { - return monthlyTimesheetModel.getDate().toString("MMMM y"); + public String getTimesheetString() { + return personalTimesheetModel.getTimesheetString(); } public String getResource() { - return monthlyTimesheetModel.getWorker().getShortDescription(); + return personalTimesheetModel.getWorker().getShortDescription(); } - public List getRows() { - List result = MonthlyTimesheetRow - .wrap(monthlyTimesheetModel + public List getRows() { + List result = PersonalTimesheetRow + .wrap(personalTimesheetModel .getOrderElements()); - if (monthlyTimesheetModel.hasOtherReports()) { - result.add(MonthlyTimesheetRow.createOtherRow()); + if (personalTimesheetModel.hasOtherReports()) { + result.add(PersonalTimesheetRow.createOtherRow()); } - result.add(MonthlyTimesheetRow.createTotalRow()); - result.add(MonthlyTimesheetRow.createCapacityRow()); - result.add(MonthlyTimesheetRow.createExtraRow()); + result.add(PersonalTimesheetRow.createTotalRow()); + result.add(PersonalTimesheetRow.createCapacityRow()); + result.add(PersonalTimesheetRow.createExtraRow()); return result; } @@ -622,31 +624,31 @@ public class MonthlyTimesheetController extends GenericForwardComposer } public void save() { - monthlyTimesheetModel.save(); + personalTimesheetModel.save(); String url = CustomTargetUrlResolver.USER_DASHBOARD_URL - + "?timesheet_saved=" + monthlyTimesheetModel.getDate(); - if (!monthlyTimesheetModel.isCurrentUser()) { + + "?timesheet_saved=" + personalTimesheetModel.getDate(); + if (!personalTimesheetModel.isCurrentUser()) { url = WORK_REPORTS_URL + "?timesheet_saved=true"; } Executions.getCurrent().sendRedirect(url); } public void saveAndContinue() { - monthlyTimesheetModel.save(); - if (monthlyTimesheetModel.isCurrentUser()) { - goToCreateOrEditForm(monthlyTimesheetModel.getDate()); + personalTimesheetModel.save(); + if (personalTimesheetModel.isCurrentUser()) { + goToCreateOrEditForm(personalTimesheetModel.getDate()); } else { - goToCreateOrEditFormForResource(monthlyTimesheetModel.getDate(), - monthlyTimesheetModel.getWorker()); + goToCreateOrEditFormForResource(personalTimesheetModel.getDate(), + personalTimesheetModel.getWorker()); } - messagesForUser.showMessage(Level.INFO, _("Monthly timesheet saved")); + messagesForUser.showMessage(Level.INFO, _("Personal timesheet saved")); Util.reloadBindings(timesheet); } public void cancel() { - monthlyTimesheetModel.cancel(); + personalTimesheetModel.cancel(); String url = CustomTargetUrlResolver.USER_DASHBOARD_URL; - if (!monthlyTimesheetModel.isCurrentUser()) { + if (!personalTimesheetModel.isCurrentUser()) { url = WORK_REPORTS_URL; } Executions.getCurrent().sendRedirect(url); @@ -656,56 +658,56 @@ public class MonthlyTimesheetController extends GenericForwardComposer OrderElement orderElement = (OrderElement) orderElementBandboxSearch .getSelectedElement(); if (orderElement != null) { - monthlyTimesheetModel.addOrderElement(orderElement); + personalTimesheetModel.addOrderElement(orderElement); orderElementBandboxSearch.setSelectedElement(null); Util.reloadBindings(timesheet); adjustFrozenWidth(); } } - public boolean isFirstMonth() { - return monthlyTimesheetModel.isFirstMonth(); + public boolean isFirstPeriod() { + return personalTimesheetModel.isFirstPeriod(); } - public boolean isLastMonth() { - return monthlyTimesheetModel.isLastMonth(); + public boolean isLastPeriod() { + return personalTimesheetModel.isLastPeriod(); } - public void previousMonth() { - if (monthlyTimesheetModel.isModified()) { + public void previousPeriod() { + if (personalTimesheetModel.isModified()) { throw new WrongValueException( - previousMonth, - _("There are unsaved changes in the current monthly timesheet, please save before moving")); + previousPeriod, + _("There are unsaved changes in the current personal timesheet, please save before moving")); } - sendToMonthlyTimesheet(monthlyTimesheetModel.getDate().minusMonths(1)); + sendToPersonalTimesheet(personalTimesheetModel.getPrevious()); } - public void nextMonth() { - if (monthlyTimesheetModel.isModified()) { + public void nextPeriod() { + if (personalTimesheetModel.isModified()) { throw new WrongValueException( - nextMonth, - _("There are unsaved changes in the current monthly timesheet, please save before moving")); + nextPeriod, + _("There are unsaved changes in the current personal timesheet, please save before moving")); } - sendToMonthlyTimesheet(monthlyTimesheetModel.getDate().plusMonths(1)); + sendToPersonalTimesheet(personalTimesheetModel.getNext()); } - private void sendToMonthlyTimesheet(final LocalDate date) { + private void sendToPersonalTimesheet(final LocalDate date) { String capturePath = EntryPointsHandler.capturePath(new ICapture() { @Override public void capture() { - monthlyTimesheetController.goToCreateOrEditForm(date); + personalTimesheetController.goToCreateOrEditForm(date); } }); Executions.getCurrent().sendRedirect(capturePath); } public boolean isCurrentUser() { - return monthlyTimesheetModel.isCurrentUser(); + return personalTimesheetModel.isCurrentUser(); } public boolean isNotCurrentUser() { - return !monthlyTimesheetModel.isCurrentUser(); + return !personalTimesheetModel.isCurrentUser(); } private static String getTotalRowTextboxId(final OrderElement orderElement) { @@ -781,7 +783,7 @@ public class MonthlyTimesheetController extends GenericForwardComposer public void updateSummary() { EffortDuration total = getEffortDurationFromTextbox(getTotalTextboxId()); EffortDuration other = EffortDuration.zero(); - if (monthlyTimesheetModel.hasOtherReports()) { + if (personalTimesheetModel.hasOtherReports()) { other = getEffortDurationFromTextbox(getTotalOtherTextboxId()); } EffortDuration capacity = getEffortDurationFromTextbox(getTotalCapacityTextboxId()); @@ -793,8 +795,8 @@ public class MonthlyTimesheetController extends GenericForwardComposer extra = total.minus(capacity); } - if (monthlyTimesheetModel.hasOtherReports()) { - summaryTotalMonthlyTimesheet + if (personalTimesheetModel.hasOtherReports()) { + summaryTotalPersonalTimesheet .setValue(timesheet.toFormattedString()); summaryTotalOther.setValue(other.toFormattedString()); } @@ -811,64 +813,64 @@ public class MonthlyTimesheetController extends GenericForwardComposer } public boolean hasOtherReports() { - return monthlyTimesheetModel.hasOtherReports(); + return personalTimesheetModel.hasOtherReports(); } } /** - * Simple class to represent the the rows in the monthly timesheet grid.
    + * Simple class to represent the the rows in the personal timesheet grid.
    * * This is used to mark the special rows like capacity and total. */ -class MonthlyTimesheetRow { - enum MonthlyTimesheetRowType { +class PersonalTimesheetRow { + enum PersonalTimesheetRowType { ORDER_ELEMENT, OTHER, CAPACITY, TOTAL, EXTRA }; - private MonthlyTimesheetRowType type; + private PersonalTimesheetRowType type; private OrderElement orderElemement; - public static MonthlyTimesheetRow createOrderElementRow( + public static PersonalTimesheetRow createOrderElementRow( OrderElement orderElemement) { - MonthlyTimesheetRow row = new MonthlyTimesheetRow( - MonthlyTimesheetRowType.ORDER_ELEMENT); + PersonalTimesheetRow row = new PersonalTimesheetRow( + PersonalTimesheetRowType.ORDER_ELEMENT); Assert.notNull(orderElemement); row.orderElemement = orderElemement; return row; } - public static MonthlyTimesheetRow createOtherRow() { - return new MonthlyTimesheetRow(MonthlyTimesheetRowType.OTHER); + public static PersonalTimesheetRow createOtherRow() { + return new PersonalTimesheetRow(PersonalTimesheetRowType.OTHER); } - public static MonthlyTimesheetRow createCapacityRow() { - return new MonthlyTimesheetRow(MonthlyTimesheetRowType.CAPACITY); + public static PersonalTimesheetRow createCapacityRow() { + return new PersonalTimesheetRow(PersonalTimesheetRowType.CAPACITY); } - public static MonthlyTimesheetRow createTotalRow() { - return new MonthlyTimesheetRow(MonthlyTimesheetRowType.TOTAL); + public static PersonalTimesheetRow createTotalRow() { + return new PersonalTimesheetRow(PersonalTimesheetRowType.TOTAL); } - public static MonthlyTimesheetRow createExtraRow() { - return new MonthlyTimesheetRow(MonthlyTimesheetRowType.EXTRA); + public static PersonalTimesheetRow createExtraRow() { + return new PersonalTimesheetRow(PersonalTimesheetRowType.EXTRA); } - public static List wrap( + public static List wrap( List orderElements) { - List result = new ArrayList(); + List result = new ArrayList(); for (OrderElement each : orderElements) { result.add(createOrderElementRow(each)); } return result; } - private MonthlyTimesheetRow(MonthlyTimesheetRowType type) { + private PersonalTimesheetRow(PersonalTimesheetRowType type) { this.type = type; } - public MonthlyTimesheetRowType getType() { + public PersonalTimesheetRowType getType() { return type; } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetDTO.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetDTO.java similarity index 51% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetDTO.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetDTO.java index 87b6b141a..3153853dc 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetDTO.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetDTO.java @@ -19,19 +19,22 @@ package org.libreplan.web.users.dashboard; +import static org.libreplan.web.I18nHelper._; + import org.joda.time.LocalDate; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.workingday.EffortDuration; import org.libreplan.business.workreports.entities.WorkReport; /** - * Simple class to represent the monthly timesheets to be shown in the list.
    + * Simple class to represent the personal timesheets to be shown in the list.
    * * This is only a utility class for the UI, everything will be saved using * {@link WorkReport} class. * * @author Manuel Rego Casasnovas */ -public class MonthlyTimesheetDTO { +public class PersonalTimesheetDTO { private LocalDate date; @@ -45,24 +48,23 @@ public class MonthlyTimesheetDTO { /** * @param date - * Only the year and month are used, the day is reseted to first - * day of the month. As there's only one timesheet per month. + * The date of the timesheet. * @param workReport - * The work report of the monthly timesheet, it could be + * The work report of the personal timesheet, it could be * null if it doesn't exist yet. * @param resourceCapacity * The capacity of the resource bound to current user in the - * month of this timesheet. + * period of this timesheet. * @param totalHours * Total hours worked by the resource bound to the current user - * in the monthly timesheet + * in the personal timesheet * @param tasksNumber - * Number of tasks in the monthly timesheet + * Number of tasks in the personal timesheet */ - MonthlyTimesheetDTO(LocalDate date, WorkReport workReport, + PersonalTimesheetDTO(LocalDate date, WorkReport workReport, EffortDuration resourceCapacity, EffortDuration totalHours, int tasksNumber) { - this.date = date.dayOfMonth().withMaximumValue(); + this.date = date; this.workReport = workReport; this.resourceCapacity = resourceCapacity; this.totalHours = totalHours; @@ -89,4 +91,41 @@ public class MonthlyTimesheetDTO { return tasksNumber; } + public String toString(PersonalTimesheetsPeriodicityEnum periodicity) { + return toString(periodicity, date); + } + + /** + * Returns a string representing the personal timehseet in a given + * date depending on the periodicity. + */ + public static String toString(PersonalTimesheetsPeriodicityEnum periodicity, LocalDate date) { + switch (periodicity) { + case WEEKLY: + LocalDate start = periodicity.getStart(date); + LocalDate end = periodicity.getEnd(date); + + String string = date.toString("w"); + if (start.getMonthOfYear() == end.getMonthOfYear()) { + string += " (" + date.toString("MMMM y") + ")"; + } else { + if (start.getYear() == end.getYear()) { + string += " (" + start.toString("MMMM") + " - " + + end.toString("MMMM y") + ")"; + } else { + string += " (" + start.toString("MMMM y") + " - " + + end.toString("MMMM y") + ")"; + } + } + return _("Week {0}", string); + case TWICE_MONTHLY: + return (date.getDayOfMonth() <= 15) ? + _("{0} 1st fortnight", date.toString("MMMM y")) : + _("{0} 2nd fortnight", date.toString("MMMM y")); + case MONTHLY: + default: + return date.toString("MMMM y"); + } + } + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetModel.java similarity index 90% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetModel.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetModel.java index 51ce3a3b2..df067c439 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetModel.java @@ -34,6 +34,7 @@ import org.libreplan.business.calendars.entities.ResourceCalendar; 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.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.costcategories.entities.TypeOfWorkHours; import org.libreplan.business.orders.daos.IOrderDAO; @@ -67,14 +68,14 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** - * Model for creation/edition of a monthly timesheet + * Model for creation/edition of a personal timesheet * * @author Manuel Rego Casasnovas */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) @OnConcurrentModification(goToPage = "/myaccount/userDashboard.zul") -public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { +public class PersonalTimesheetModel implements IPersonalTimesheetModel { private User user; @@ -102,6 +103,8 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { private Map otherEffortPerDay; + private PersonalTimesheetsPeriodicityEnum periodicity; + @Autowired private IResourceAllocationDAO resourceAllocationDAO; @@ -147,6 +150,8 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { private void initFields(LocalDate date) { this.date = date; + periodicity = getPersonalTimesheetsPeriodicity(); + initDates(); initCapacityMap(); @@ -173,8 +178,8 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { } private void initDates() { - firstDay = date.dayOfMonth().withMinimumValue(); - lastDay = date.dayOfMonth().withMaximumValue(); + firstDay = periodicity.getStart(date); + lastDay = periodicity.getEnd(date); } private void initCapacityMap() { @@ -195,13 +200,13 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { } private void initWorkReport() { - // Get work report representing this monthly timesheet - workReport = workReportDAO.getMonthlyTimesheetWorkReport( - user.getWorker(), date); + // Get work report representing this personal timesheet + workReport = workReportDAO.getPersonalTimesheetWorkReport( + user.getWorker(), date, periodicity); if (workReport == null) { // If it doesn't exist yet create a new one workReport = WorkReport - .create(getMonthlyTimesheetsWorkReportType()); + .create(getPersonalTimesheetsWorkReportType()); workReport .setCode(entitySequenceDAO .getNextEntityCodeWithoutTransaction(EntityNameEnum.WORK_REPORT)); @@ -211,10 +216,10 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { forceLoad(workReport.getWorkReportType()); } - private WorkReportType getMonthlyTimesheetsWorkReportType() { + private WorkReportType getPersonalTimesheetsWorkReportType() { try { WorkReportType workReportType = workReportTypeDAO - .findUniqueByName(PredefinedWorkReportTypes.MONTHLY_TIMESHEETS + .findUniqueByName(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS .getName()); return workReportType; } catch (NonUniqueResultException e) { @@ -413,7 +418,7 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { private TypeOfWorkHours getTypeOfWorkHours() { return configurationDAO.getConfiguration() - .getMonthlyTimesheetsTypeOfWorkHours(); + .getPersonalTimesheetsTypeOfWorkHours(); } @Override @@ -424,7 +429,7 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { // Do nothing. // A new work report if it doesn't have work report lines is not // saved as it will not be possible to find it later with - // WorkReportDAO.getMonthlyTimesheetWorkReport() method. + // WorkReportDAO.getPersonalTimesheetWorkReport() method. } else { sumChargedEffortDAO .updateRelatedSumChargedEffortWithWorkReportLineSet(workReport @@ -502,16 +507,18 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { } @Override - public boolean isFirstMonth() { + @Transactional(readOnly = true) + public boolean isFirstPeriod() { LocalDate activationDate = getWorker().getCalendar() .getFistCalendarAvailability().getStartDate(); - return firstDay.equals(activationDate.dayOfMonth().withMinimumValue()); + return firstDay.equals(periodicity.getStart(activationDate)); } @Override - public boolean isLastMonth() { - return firstDay.equals(new LocalDate().plusMonths(1).dayOfMonth() - .withMinimumValue()); + @Transactional(readOnly = true) + public boolean isLastPeriod() { + return firstDay.equals(periodicity.getStart(new LocalDate() + .plusMonths(1))); } @Override @@ -552,4 +559,26 @@ public class MonthlyTimesheetModel implements IMonthlyTimesheetModel { return result; } + @Override + @Transactional(readOnly = true) + public PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() { + return configurationDAO.getConfiguration() + .getPersonalTimesheetsPeriodicity(); + } + + @Override + public String getTimesheetString() { + return PersonalTimesheetDTO.toString(periodicity, date); + } + + @Override + public LocalDate getPrevious() { + return periodicity.previous(date); + } + + @Override + public LocalDate getNext() { + return periodicity.next(date); + } + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetsAreaController.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetsAreaController.java similarity index 60% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetsAreaController.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetsAreaController.java index 66e98ed71..615d29170 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetsAreaController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetsAreaController.java @@ -32,37 +32,39 @@ import org.zkoss.zul.Row; import org.zkoss.zul.RowRenderer; /** - * Controller for "Monthly timesheets" area in the user dashboard window + * Controller for "Personal timesheets" area in the user dashboard window * * @author Manuel Rego Casasnovas */ @SuppressWarnings("serial") -public class MonthlyTimesheetsAreaController extends GenericForwardComposer { +public class PersonalTimesheetsAreaController extends GenericForwardComposer { - private IMonthlyTimesheetsAreaModel monthlyTimesheetsAreaModel; + private IPersonalTimesheetsAreaModel personalTimesheetsAreaModel; @Resource - private IMonthlyTimesheetController monthlyTimesheetController; + private IPersonalTimesheetController personalTimesheetController; - private RowRenderer monthlyTimesheetsRenderer = new RowRenderer() { + private RowRenderer personalTimesheetsRenderer = new RowRenderer() { @Override public void render(Row row, Object data) throws Exception { - final MonthlyTimesheetDTO monthlyTimesheet = (MonthlyTimesheetDTO) data; - row.setValue(monthlyTimesheet); + final PersonalTimesheetDTO personalTimesheet = (PersonalTimesheetDTO) data; + row.setValue(personalTimesheet); - Util.appendLabel(row, monthlyTimesheet.getDate().toString("MMMM y")); - Util.appendLabel(row, monthlyTimesheet.getResourceCapacity() + Util.appendLabel(row, personalTimesheet + .toString(personalTimesheetsAreaModel + .getPersonalTimesheetsPeriodicity())); + Util.appendLabel(row, personalTimesheet.getResourceCapacity() .toFormattedString()); - Util.appendLabel(row, monthlyTimesheet.getTotalHours() + Util.appendLabel(row, personalTimesheet.getTotalHours() .toFormattedString()); - Util.appendLabel(row, monthlyTimesheet.getTasksNumber() + ""); + Util.appendLabel(row, personalTimesheet.getTasksNumber() + ""); Util.appendOperationsAndOnClickEvent(row, new EventListener() { @Override public void onEvent(Event event) throws Exception { - monthlyTimesheetController.goToCreateOrEditForm(monthlyTimesheet + personalTimesheetController.goToCreateOrEditForm(personalTimesheet .getDate()); } }, null); @@ -76,12 +78,12 @@ public class MonthlyTimesheetsAreaController extends GenericForwardComposer { comp.setAttribute("controller", this); } - public List getMonthlyTimesheets() { - return monthlyTimesheetsAreaModel.getMonthlyTimesheets(); + public List getPersonalTimesheets() { + return personalTimesheetsAreaModel.getPersonalTimesheets(); } - public RowRenderer getMonthlyTimesheetsRenderer() { - return monthlyTimesheetsRenderer; + public RowRenderer getPersonalTimesheetsRenderer() { + return personalTimesheetsRenderer; } -} \ No newline at end of file +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetsAreaModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetsAreaModel.java similarity index 69% rename from libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetsAreaModel.java rename to libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetsAreaModel.java index fa28d7ddf..3a52d5c46 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetsAreaModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetsAreaModel.java @@ -24,7 +24,8 @@ import java.util.Collections; import java.util.List; import org.joda.time.LocalDate; -import org.joda.time.Months; +import org.libreplan.business.common.daos.IConfigurationDAO; +import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.resources.entities.Resource; import org.libreplan.business.resources.entities.Worker; @@ -45,20 +46,23 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** - * Model for for "Monthly timesheets" area in the user dashboard window + * Model for for "Personal timesheets" area in the user dashboard window * * @author Manuel Rego Casasnovas */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel { +public class PersonalTimesheetsAreaModel implements IPersonalTimesheetsAreaModel { @Autowired private IWorkReportDAO workReportDAO; + @Autowired + private IConfigurationDAO configurationDAO; + @Override @Transactional(readOnly = true) - public List getMonthlyTimesheets() { + public List getPersonalTimesheets() { User user = UserUtil.getUserFromSession(); if (!user.isBound()) { return Collections.emptyList(); @@ -68,22 +72,25 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel { LocalDate activationDate = getActivationDate(user.getWorker()); LocalDate currentDate = new LocalDate(); - return getMonthlyTimesheets(user.getWorker(), activationDate, - currentDate.plusMonths(1)); + return getPersonalTimesheets(user.getWorker(), activationDate, + currentDate.plusMonths(1), getPersonalTimesheetsPeriodicity()); } - private List getMonthlyTimesheets(Resource resource, - LocalDate start, LocalDate end) { - int months = Months.monthsBetween(start, end).getMonths(); + private List getPersonalTimesheets(Resource resource, + LocalDate start, LocalDate end, + PersonalTimesheetsPeriodicityEnum periodicity) { + start = periodicity.getStart(start); + end = periodicity.getEnd(end); + int items = periodicity.getItemsBetween(start, end); - List result = new ArrayList(); + List result = new ArrayList(); // In decreasing order to provide a list sorted with the more recent - // monthly timesheets at the beginning - for (int i = months; i >= 0; i--) { - LocalDate date = start.plusMonths(i); + // personal timesheets at the beginning + for (int i = items; i >= 0; i--) { + LocalDate date = periodicity.getDateForItemFromDate(i, start); - WorkReport workReport = getWorkReport(resource, date); + WorkReport workReport = getWorkReport(resource, date, periodicity); EffortDuration hours = EffortDuration.zero(); int tasksNumber = 0; @@ -92,24 +99,29 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel { tasksNumber = getNumberOfOrderElementsWithTrackedTime(workReport); } - result.add(new MonthlyTimesheetDTO(date, workReport, - getResourceCapcity(resource, date), hours, tasksNumber)); + result.add(new PersonalTimesheetDTO(date, workReport, + getResourceCapcity(resource, date, periodicity), hours, + tasksNumber)); } return result; } - private WorkReport getWorkReport(Resource resource, LocalDate date) { - WorkReport workReport = workReportDAO.getMonthlyTimesheetWorkReport( - resource, date); + private WorkReport getWorkReport(Resource resource, LocalDate date, + PersonalTimesheetsPeriodicityEnum periodicity) { + WorkReport workReport = workReportDAO.getPersonalTimesheetWorkReport( + resource, date, periodicity); forceLoad(workReport); return workReport; } - private EffortDuration getResourceCapcity(Resource resource, LocalDate date) { + private EffortDuration getResourceCapcity(Resource resource, + LocalDate date, PersonalTimesheetsPeriodicityEnum periodicity) { + LocalDate start = periodicity.getStart(date); + LocalDate end = periodicity.getEnd(date); + EffortDuration capacity = EffortDuration.zero(); - for (LocalDate day = date.dayOfMonth().withMinimumValue(); day - .compareTo(date.dayOfMonth().withMaximumValue()) <= 0; day = day + for (LocalDate day = start; day.compareTo(end) <= 0; day = day .plusDays(1)) { capacity = capacity.plus(resource.getCalendar().getCapacityOn( PartialDay.wholeDay(day))); @@ -149,4 +161,11 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel { return orderElements.size(); } + @Override + @Transactional(readOnly = true) + public PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() { + return configurationDAO.getConfiguration() + .getPersonalTimesheetsPeriodicity(); + } + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/UserDashboardController.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/UserDashboardController.java index 417943795..af3e7fa68 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/UserDashboardController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/UserDashboardController.java @@ -23,6 +23,7 @@ import static org.libreplan.web.I18nHelper._; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.libreplan.business.common.Registry; import org.libreplan.web.common.IMessagesForUser; import org.libreplan.web.common.Level; import org.libreplan.web.common.MessagesForUser; @@ -34,7 +35,7 @@ import org.zkoss.zk.ui.util.GenericForwardComposer; * Controller for user dashboard window.
    * * At this moment it's only used to show a message to user after saving a - * monthly timesheet. + * personal timesheet. * * @author Manuel Rego Casasnovas */ @@ -54,10 +55,13 @@ public class UserDashboardController extends GenericForwardComposer { String timesheetSave = Executions.getCurrent().getParameter( "timesheet_saved"); if (!StringUtils.isBlank(timesheetSave)) { - String monthlyTimesheet = new LocalDate(timesheetSave) - .toString("MMMM y"); + String personalTimesheet = PersonalTimesheetDTO.toString(Registry + .getConfigurationDAO() + .getConfigurationWithReadOnlyTransaction() + .getPersonalTimesheetsPeriodicity(), new LocalDate( + timesheetSave)); messagesForUser.showMessage(Level.INFO, - _("Monthly timesheet \"{0}\" saved", monthlyTimesheet)); + _("Personal timesheet \"{0}\" saved", personalTimesheet)); } String expenseSheetSaved = Executions.getCurrent().getParameter( diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportModel.java index 6fdf67f67..789507fd7 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportModel.java @@ -239,9 +239,9 @@ public interface IWorkReportModel extends IIntegrationEntityModel { List getBoundWorkers(); /** - * Checks if a {@link WorkReport} is or not a monthly timesheet. + * Checks if a {@link WorkReport} is or not a personal timesheet. */ - boolean isMonthlyTimesheet(WorkReport workReport); + boolean isPersonalTimesheet(WorkReport workReport); WorkReportLine getFirstWorkReportLine(); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportTypeModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportTypeModel.java index c45d1b9f7..7df4f44a2 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportTypeModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/IWorkReportTypeModel.java @@ -52,11 +52,11 @@ public interface IWorkReportTypeModel extends IIntegrationEntityModel { /** * Gets the {@link List} of {@link WorkReportType WorkReportTypes} except - * the {@link WorkReportType} used for monthly timesheets. + * the {@link WorkReportType} used for personal timesheets. * * @return A {@link List} of {@link WorkReportType} */ - List getWorkReportTypesExceptMonthlyTimeSheets(); + List getWorkReportTypesExceptPersonalTimeSheets(); /** * Stores the current {@link WorkReportType}. diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportCRUDController.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportCRUDController.java index 195197f13..f9311bde7 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportCRUDController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportCRUDController.java @@ -60,7 +60,7 @@ import org.libreplan.web.common.components.NewDataSortableGrid; import org.libreplan.web.common.components.bandboxsearch.BandboxSearch; import org.libreplan.web.common.entrypoints.EntryPointsHandler; import org.libreplan.web.common.entrypoints.IURLHandlerRegistry; -import org.libreplan.web.users.dashboard.IMonthlyTimesheetController; +import org.libreplan.web.users.dashboard.IPersonalTimesheetController; import org.zkoss.ganttz.IPredicate; import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.zk.ui.Component; @@ -157,13 +157,13 @@ public class WorkReportCRUDController extends GenericForwardComposer implements private Datebox filterFinishDate; @javax.annotation.Resource - private IMonthlyTimesheetController monthlyTimesheetController; + private IPersonalTimesheetController personalTimesheetController; - private Popup monthlyTimesheetsPopup; + private Popup personalTimesheetsPopup; - private Datebox monthlyTimesheetsDatebox; + private Datebox personalTimesheetsDatebox; - private BandboxSearch monthlyTimesheetsBandboxSearch; + private BandboxSearch personalTimesheetsBandboxSearch; @Override public void doAfterCompose(Component comp) throws Exception { @@ -171,7 +171,7 @@ public class WorkReportCRUDController extends GenericForwardComposer implements listWorkReportLines = (NewDataSortableGrid) createWindow .getFellowIfAny("listWorkReportLines"); messagesForUser = new MessagesForUser(messagesContainer); - showMessageIfMonthlyTimesheetWasSaved(); + showMessageIfPersonalTimesheetWasSaved(); comp.setAttribute("controller", this); goToList(); @@ -185,12 +185,12 @@ public class WorkReportCRUDController extends GenericForwardComposer implements handler.register(this, page); } - private void showMessageIfMonthlyTimesheetWasSaved() { + private void showMessageIfPersonalTimesheetWasSaved() { String timesheetSave = Executions.getCurrent().getParameter( "timesheet_saved"); if (!StringUtils.isBlank(timesheetSave)) { messagesForUser.showMessage(Level.INFO, - _("Monthly timesheet saved")); + _("Personal timesheet saved")); } } @@ -598,8 +598,8 @@ public class WorkReportCRUDController extends GenericForwardComposer implements @Override public void goToCreateForm(WorkReportType workReportType) { - if (workReportType.isMonthlyTimesheetsType()) { - monthlyTimesheetsPopup.open(listTypeToAssign); + if (workReportType.isPersonalTimesheetsType()) { + personalTimesheetsPopup.open(listTypeToAssign); } else { cameBackList = false; workReportModel.initCreate(workReportType); @@ -617,8 +617,8 @@ public class WorkReportCRUDController extends GenericForwardComposer implements @Override public void goToEditForm(WorkReport workReport) { - if (workReportModel.isMonthlyTimesheet(workReport)) { - goToEditMonthlyTimeSheet(workReport); + if (workReportModel.isPersonalTimesheet(workReport)) { + goToEditPersonalTimeSheet(workReport); } else { workReportModel.initEdit(workReport); createWindow.setTitle(_("Edit Timesheet")); @@ -629,11 +629,11 @@ public class WorkReportCRUDController extends GenericForwardComposer implements } } - private void goToEditMonthlyTimeSheet(WorkReport workReport) { + private void goToEditPersonalTimeSheet(WorkReport workReport) { workReportModel.initEdit(workReport); Date date = workReportModel.getFirstWorkReportLine().getDate(); Resource resource = workReport.getResource(); - monthlyTimesheetController.goToCreateOrEditFormForResource( + personalTimesheetController.goToCreateOrEditFormForResource( LocalDate.fromDateFields(date), resource); } @@ -682,12 +682,12 @@ public class WorkReportCRUDController extends GenericForwardComposer implements listTypeToAssign = (Listbox) window.getFellow("listTypeToAssign"); filterStartDate = (Datebox) window.getFellow("filterStartDate"); filterFinishDate = (Datebox) window.getFellow("filterFinishDate"); - monthlyTimesheetsPopup = (Popup) window - .getFellow("monthlyTimesheetsPopup"); - monthlyTimesheetsDatebox = (Datebox) window - .getFellow("monthlyTimesheetsDatebox"); - monthlyTimesheetsBandboxSearch = (BandboxSearch) window - .getFellow("monthlyTimesheetsBandboxSearch"); + personalTimesheetsPopup = (Popup) window + .getFellow("personalTimesheetsPopup"); + personalTimesheetsDatebox = (Datebox) window + .getFellow("personalTimesheetsDatebox"); + personalTimesheetsBandboxSearch = (BandboxSearch) window + .getFellow("personalTimesheetsBandboxSearch"); clearFilterDates(); } @@ -1616,20 +1616,20 @@ public class WorkReportCRUDController extends GenericForwardComposer implements return workReportModel.getBoundWorkers(); } - public void createOrEditMonthlyTimesheet() { - Date date = monthlyTimesheetsDatebox.getValue(); + public void createOrEditPersonalTimesheet() { + Date date = personalTimesheetsDatebox.getValue(); if (date == null) { - throw new WrongValueException(monthlyTimesheetsDatebox, + throw new WrongValueException(personalTimesheetsDatebox, _("Please set a date")); } - Resource resource = (Resource) monthlyTimesheetsBandboxSearch + Resource resource = (Resource) personalTimesheetsBandboxSearch .getSelectedElement(); if (resource == null) { - throw new WrongValueException(monthlyTimesheetsBandboxSearch, + throw new WrongValueException(personalTimesheetsBandboxSearch, _("Please select a worker")); } - monthlyTimesheetController.goToCreateOrEditFormForResource( + personalTimesheetController.goToCreateOrEditFormForResource( LocalDate.fromDateFields(date), resource); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportDTO.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportDTO.java index db012187f..d6f81c07a 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportDTO.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportDTO.java @@ -42,7 +42,7 @@ public class WorkReportDTO { WorkReportType workReportType = workReport.getWorkReportType(); this.type = workReportType.getName(); - if (workReportType.isMonthlyTimesheetsType()) { + if (workReportType.isPersonalTimesheetsType()) { this.type += " - " + workReport.getResource().getShortDescription(); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportModel.java index 1e5977a62..f05831956 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportModel.java @@ -629,11 +629,11 @@ public class WorkReportModel extends IntegrationEntityModel implements @Override @Transactional(readOnly = true) - public boolean isMonthlyTimesheet(WorkReport workReport) { + public boolean isPersonalTimesheet(WorkReport workReport) { try { return workReportTypeDAO.find( workReport.getWorkReportType().getId()) - .isMonthlyTimesheetsType(); + .isPersonalTimesheetsType(); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportQueryController.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportQueryController.java index dd989f9a5..e70ea6228 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportQueryController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportQueryController.java @@ -47,7 +47,7 @@ import org.libreplan.web.common.MessagesForUser; import org.libreplan.web.common.components.Autocomplete; import org.libreplan.web.common.components.bandboxsearch.BandboxSearch; import org.libreplan.web.security.SecurityUtils; -import org.libreplan.web.users.dashboard.IMonthlyTimesheetController; +import org.libreplan.web.users.dashboard.IPersonalTimesheetController; import org.zkoss.ganttz.IPredicate; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.WrongValueException; @@ -109,7 +109,7 @@ public class WorkReportQueryController extends GenericForwardComposer { private IWorkReportCRUDControllerEntryPoints workReportCRUD; @javax.annotation.Resource - private IMonthlyTimesheetController monthlyTimesheetController; + private IPersonalTimesheetController personalTimesheetController; @Override public void doAfterCompose(Component comp) throws Exception { @@ -329,9 +329,9 @@ public class WorkReportQueryController extends GenericForwardComposer { if (SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEETS)) { workReportCRUD.goToEditForm(workReport); } else if (SecurityUtils.isUserInRole(UserRole.ROLE_BOUND_USER) - && workReportModel.isMonthlyTimesheet(workReport) + && workReportModel.isPersonalTimesheet(workReport) && belongsToCurrentUser(line)) { - monthlyTimesheetController + personalTimesheetController .goToCreateOrEditForm(line.getLocalDate()); } else { messagesForUser.showMessage(Level.WARNING, diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeCRUDController.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeCRUDController.java index fee990da0..d4aba980b 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeCRUDController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeCRUDController.java @@ -116,7 +116,7 @@ public class WorkReportTypeCRUDController extends BaseCRUDController getWorkReportTypes() { - return workReportTypeModel.getWorkReportTypesExceptMonthlyTimeSheets(); + return workReportTypeModel.getWorkReportTypesExceptPersonalTimeSheets(); } public WorkReportType getWorkReportType() { diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeModel.java index 32b40a70c..7a242fa73 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/workreports/WorkReportTypeModel.java @@ -118,11 +118,11 @@ public class WorkReportTypeModel extends IntegrationEntityModel implements @Override @Transactional(readOnly = true) - public List getWorkReportTypesExceptMonthlyTimeSheets() { + public List getWorkReportTypesExceptPersonalTimeSheets() { List list = workReportTypeDAO.list(WorkReportType.class); try { list.remove(workReportTypeDAO - .findUniqueByName(PredefinedWorkReportTypes.MONTHLY_TIMESHEETS + .findUniqueByName(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS .getName())); } catch (NonUniqueResultException e) { throw new RuntimeException(e); @@ -151,9 +151,9 @@ public class WorkReportTypeModel extends IntegrationEntityModel implements @Override @Transactional(readOnly = true) public void initEdit(WorkReportType workReportType) { - if (workReportType.isMonthlyTimesheetsType()) { + if (workReportType.isPersonalTimesheetsType()) { throw new IllegalArgumentException( - "Monthly timesheets timesheet template cannot be edited"); + "Personal timesheets timesheet template cannot be edited"); } setListing(false); @@ -220,9 +220,9 @@ public class WorkReportTypeModel extends IntegrationEntityModel implements @Override @Transactional public void confirmRemove(WorkReportType workReportType) { - if (workReportType.isMonthlyTimesheetsType()) { + if (workReportType.isPersonalTimesheetsType()) { throw new IllegalArgumentException( - "Monthly timesheets timesheet template cannot be removed"); + "Personal timesheets timesheet template cannot be removed"); } try { diff --git a/libreplan-webapp/src/main/webapp/common/configuration.zul b/libreplan-webapp/src/main/webapp/common/configuration.zul index de1a5da71..0c09fbb82 100644 --- a/libreplan-webapp/src/main/webapp/common/configuration.zul +++ b/libreplan-webapp/src/main/webapp/common/configuration.zul @@ -69,10 +69,19 @@ selectedElement="@{configurationController.defaultCalendar}" /> - + +