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/IMonthlyTimesheetsAreaModel.java
index d1fe00664..0548fa816 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/IMonthlyTimesheetsAreaModel.java
@@ -22,6 +22,7 @@ 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;
@@ -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/MonthlyTimesheetDTO.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/MonthlyTimesheetDTO.java
index 87b6b141a..10a3cc9ce 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/MonthlyTimesheetDTO.java
@@ -19,7 +19,10 @@
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;
@@ -45,8 +48,7 @@ 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
* null if it doesn't exist yet.
@@ -62,7 +64,7 @@ public class MonthlyTimesheetDTO {
MonthlyTimesheetDTO(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,18 @@ public class MonthlyTimesheetDTO {
return tasksNumber;
}
+ public String toString(PersonalTimesheetsPeriodicityEnum periodicity) {
+ switch (periodicity) {
+ case WEEKLY:
+ return _("Week {0}", date.toString("w"));
+ case TWICE_MONTHLY:
+ return (date.getDayOfMonth() <= 15) ?
+ _("{0} 1st fortnight",date.toString("MMMM")) :
+ _("{0} 2nd fortnight",date.toString("MMMM"));
+ case MONTHLY:
+ default:
+ return date.toString("MMMM y");
+ }
+ }
+
}
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/MonthlyTimesheetsAreaController.java
index 66e98ed71..3eaf4ed8e 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/MonthlyTimesheetsAreaController.java
@@ -51,7 +51,9 @@ public class MonthlyTimesheetsAreaController extends GenericForwardComposer {
final MonthlyTimesheetDTO monthlyTimesheet = (MonthlyTimesheetDTO) data;
row.setValue(monthlyTimesheet);
- Util.appendLabel(row, monthlyTimesheet.getDate().toString("MMMM y"));
+ Util.appendLabel(row, monthlyTimesheet
+ .toString(monthlyTimesheetsAreaModel
+ .getPersonalTimesheetsPeriodicity()));
Util.appendLabel(row, monthlyTimesheet.getResourceCapacity()
.toFormattedString());
Util.appendLabel(row, monthlyTimesheet.getTotalHours()
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/MonthlyTimesheetsAreaModel.java
index fa28d7ddf..9622cc749 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/MonthlyTimesheetsAreaModel.java
@@ -25,6 +25,9 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.joda.time.Months;
+import org.joda.time.Weeks;
+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;
@@ -56,6 +59,9 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel {
@Autowired
private IWorkReportDAO workReportDAO;
+ @Autowired
+ private IConfigurationDAO configurationDAO;
+
@Override
@Transactional(readOnly = true)
public List getMonthlyTimesheets() {
@@ -69,19 +75,68 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel {
LocalDate activationDate = getActivationDate(user.getWorker());
LocalDate currentDate = new LocalDate();
return getMonthlyTimesheets(user.getWorker(), activationDate,
- currentDate.plusMonths(1));
+ currentDate.plusMonths(1), getPersonalTimesheetsPeriodicity());
}
private List getMonthlyTimesheets(Resource resource,
- LocalDate start, LocalDate end) {
- int months = Months.monthsBetween(start, end).getMonths();
+ LocalDate start, LocalDate end,
+ PersonalTimesheetsPeriodicityEnum periodicity) {
+ int items;
+ switch (periodicity) {
+ case WEEKLY:
+ start = start.dayOfWeek().withMinimumValue();
+ end = end.dayOfWeek().withMaximumValue();
+ items = Weeks.weeksBetween(start, end).getWeeks();
+ break;
+ case TWICE_MONTHLY:
+ if (start.getDayOfMonth() <= 15) {
+ start = start.dayOfMonth().withMinimumValue();
+ } else {
+ start = start.dayOfMonth().withMinimumValue().plusDays(15);
+ }
+ if (end.getDayOfMonth() <= 15) {
+ end = end.dayOfMonth().withMinimumValue().plusDays(14);
+ } else {
+ end = end.dayOfMonth().withMaximumValue();
+ }
+ items = Months.monthsBetween(start, end).getMonths() * 2;
+ break;
+ case MONTHLY:
+ default:
+ start = start.dayOfMonth().withMinimumValue();
+ end = end.dayOfMonth().withMaximumValue();
+ items = Months.monthsBetween(start, end).getMonths();
+ break;
+ }
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);
+ for (int i = items; i >= 0; i--) {
+ LocalDate date;
+ switch (periodicity) {
+ case WEEKLY:
+ date = start.plusWeeks(i);
+ break;
+ case TWICE_MONTHLY:
+ int months = (i % 2 == 0) ? (i / 2) : ((i - 1) / 2);
+ date = start.plusMonths(months);
+ if (i % 2 != 0) {
+ if (date.getDayOfMonth() <= 15) {
+ date = date.dayOfMonth().withMinimumValue()
+ .plusDays(15);
+ } else {
+ date = date.plusMonths(1).dayOfMonth()
+ .withMinimumValue();
+ }
+ }
+ break;
+ case MONTHLY:
+ default:
+ date = start.plusMonths(i);
+ break;
+ }
WorkReport workReport = getWorkReport(resource, date);
@@ -93,7 +148,8 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel {
}
result.add(new MonthlyTimesheetDTO(date, workReport,
- getResourceCapcity(resource, date), hours, tasksNumber));
+ getResourceCapcity(resource, date, periodicity), hours,
+ tasksNumber));
}
return result;
@@ -106,10 +162,33 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel {
return workReport;
}
- private EffortDuration getResourceCapcity(Resource resource, LocalDate date) {
+ private EffortDuration getResourceCapcity(Resource resource,
+ LocalDate date, PersonalTimesheetsPeriodicityEnum periodicity) {
+ LocalDate start;
+ LocalDate end;
+ switch (periodicity) {
+ case WEEKLY:
+ start = date.dayOfWeek().withMinimumValue();
+ end = date.dayOfWeek().withMaximumValue();
+ break;
+ case TWICE_MONTHLY:
+ if (date.getDayOfMonth() <= 15) {
+ start = date.dayOfMonth().withMinimumValue();
+ end = start.plusDays(14);
+ } else {
+ start = date.dayOfMonth().withMinimumValue().plusDays(15);
+ end = date.dayOfMonth().withMaximumValue();
+ }
+ break;
+ default:
+ case MONTHLY:
+ start = date.dayOfMonth().withMinimumValue();
+ end = date.dayOfMonth().withMaximumValue();
+ break;
+ }
+
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 +228,11 @@ public class MonthlyTimesheetsAreaModel implements IMonthlyTimesheetsAreaModel {
return orderElements.size();
}
+ @Override
+ @Transactional(readOnly = true)
+ public PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() {
+ return configurationDAO.getConfiguration()
+ .getPersonalTimesheetsPeriodicity();
+ }
+
}