diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/ISumChargedEffortDAO.java b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/ISumChargedEffortDAO.java
index 10301a50a..19d0fc17c 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/ISumChargedEffortDAO.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/ISumChargedEffortDAO.java
@@ -74,4 +74,26 @@ public interface ISumChargedEffortDAO extends
*/
void recalculateSumChargedEfforts(Long orderId);
+ /**
+ * Returns a {@link Set} of {@link OrderElement OrderElements} affected by
+ * any change taking into account the lines in the report and the ones to be
+ * removed.
+ *
+ * Usually you call this method to get the set before saving the work
+ * report. After saving the work report you call
+ * {@link ISumChargedEffortDAO#recalculateTimesheetDates(Set)} with the
+ * result of this method.
+ *
+ * You can pass null as param if you only have one of the sets.
+ */
+ Set getOrderElementsToRecalculateTimsheetDates(
+ Set workReportLines,
+ Set deletedWorkReportLinesSet);
+
+ /**
+ * Recalulates the first and last timesheets dates for each
+ * {@link OrderElement} in the {@link Set}.
+ */
+ void recalculateTimesheetDates(Set orderElements);
+
}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/SumChargedEffortDAO.java b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/SumChargedEffortDAO.java
index aad876f66..907ce3bb9 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/SumChargedEffortDAO.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/SumChargedEffortDAO.java
@@ -70,6 +70,9 @@ public class SumChargedEffortDAO extends
@Autowired
private IOrderDAO orderDAO;
+ @Autowired
+ private IOrderElementDAO orderElementDAO;
+
private Map mapSumChargedEfforts;
@Override
@@ -118,6 +121,7 @@ public class SumChargedEffortDAO extends
forceLoadParents(parent);
}
}
+
});
previousEffort = previous.getFirst();
@@ -252,7 +256,7 @@ public class SumChargedEffortDAO extends
resetMapSumChargedEfforts();
resetSumChargedEffort(order);
calculateDirectChargedEffort(order);
- calculateFirstAndLastTimesheetDates(order);
+ calculateTimesheetDates(order);
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
@@ -280,7 +284,7 @@ public class SumChargedEffortDAO extends
addDirectChargedEffort(orderElement, effort);
}
- private Pair calculateFirstAndLastTimesheetDates(
+ private Pair calculateTimesheetDates(
OrderElement orderElement) {
Pair minMax = workReportLineDAO
.findMinAndMaxDatesByOrderElement(orderElement);
@@ -292,18 +296,21 @@ public class SumChargedEffortDAO extends
addIfNotNull(maxDates, minMax.getSecond());
for (OrderElement child : orderElement.getChildren()) {
- Pair minMaxChild = calculateFirstAndLastTimesheetDates(child);
+ Pair minMaxChild = calculateTimesheetDates(child);
addIfNotNull(minDates, minMaxChild.getFirst());
addIfNotNull(maxDates, minMaxChild.getSecond());
}
- SumChargedEffort sumChargedEffort = getByOrderElement(orderElement);
- sumChargedEffort.setTimesheetDates(minMax.getFirst(),
- minMax.getSecond());
-
- return Pair.create(
+ Pair result = Pair.create(
minDates.isEmpty() ? null : Collections.min(minDates),
maxDates.isEmpty() ? null : Collections.max(maxDates));
+
+ SumChargedEffort sumChargedEffort = getByOrderElement(orderElement);
+ sumChargedEffort.setTimesheetDates(result.getFirst(),
+ result.getSecond());
+ save(sumChargedEffort);
+
+ return result;
}
private void addIfNotNull(Collection list, Date date) {
@@ -312,4 +319,101 @@ public class SumChargedEffortDAO extends
}
}
+ @Override
+ @Transactional(readOnly = true)
+ public Set getOrderElementsToRecalculateTimsheetDates(
+ Set workReportLines,
+ Set deletedWorkReportLines) {
+ Set orderElements = new HashSet();
+
+ if (workReportLines != null) {
+ for (final WorkReportLine workReportLine : workReportLines) {
+ if (!workReportLine.isNewObject()) {
+ OrderElement previousOrderElement = transactionService
+ .runOnAnotherTransaction(new IOnTransaction() {
+ @Override
+ public OrderElement execute() {
+ try {
+ WorkReportLine line = workReportLineDAO
+ .find(workReportLine.getId());
+
+ return line.getOrderElement();
+ } catch (InstanceNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ orderElements.add(previousOrderElement);
+ }
+ orderElements.add(workReportLine.getOrderElement());
+ }
+ }
+
+ if (deletedWorkReportLines != null) {
+ for (WorkReportLine workReportLine : deletedWorkReportLines) {
+ if (workReportLine.isNewObject()) {
+ // If the line hasn't been saved, we don't take it into
+ // account
+ continue;
+ }
+
+ // Refresh data from database, because of changes not saved are
+ // not
+ // useful for the following operations
+ sessionFactory.getCurrentSession().refresh(workReportLine);
+
+ orderElements.add(workReportLine.getOrderElement());
+ }
+ }
+
+ return orderElements;
+ }
+
+ @Override
+ @Transactional
+ public void recalculateTimesheetDates(Set orderElements) {
+ try {
+ for (OrderElement orderElement : orderElements) {
+ saveTimesheetDatesRecursively(orderElementDAO.find(orderElement
+ .getId()));
+ }
+ } catch (InstanceNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void saveTimesheetDatesRecursively(OrderElement orderElement) {
+ if (orderElement != null) {
+ saveTimesheetDates(orderElement);
+ saveTimesheetDatesRecursively(orderElement.getParent());
+ }
+ }
+
+ private void saveTimesheetDates(OrderElement orderElement) {
+ Pair minMax = workReportLineDAO
+ .findMinAndMaxDatesByOrderElement(orderElement);
+
+ Set minDates = new HashSet();
+ Set maxDates = new HashSet();
+
+ addIfNotNull(minDates, minMax.getFirst());
+ addIfNotNull(maxDates, minMax.getSecond());
+
+ for (OrderElement child : orderElement.getChildren()) {
+ SumChargedEffort childSumChargedEffort = getByOrderElement(child);
+ addIfNotNull(minDates,
+ childSumChargedEffort.getFirstTimesheetDate());
+ addIfNotNull(maxDates, childSumChargedEffort.getLastTimesheetDate());
+ }
+
+ Pair result = Pair.create(minDates.isEmpty() ? null
+ : Collections.min(minDates), maxDates.isEmpty() ? null
+ : Collections.max(maxDates));
+
+ SumChargedEffort sumChargedEffort = getByOrderElement(orderElement);
+ sumChargedEffort.setTimesheetDates(result.getFirst(),
+ result.getSecond());
+ save(sumChargedEffort);
+ }
+
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetModel.java
index df067c439..95dd7796f 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetModel.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetModel.java
@@ -431,12 +431,16 @@ public class PersonalTimesheetModel implements IPersonalTimesheetModel {
// saved as it will not be possible to find it later with
// WorkReportDAO.getPersonalTimesheetWorkReport() method.
} else {
+ Set orderElements = sumChargedEffortDAO
+ .getOrderElementsToRecalculateTimsheetDates(
+ workReport.getWorkReportLines(), null);
sumChargedEffortDAO
.updateRelatedSumChargedEffortWithWorkReportLineSet(workReport
.getWorkReportLines());
workReport.generateWorkReportLineCodes(entitySequenceDAO
.getNumberOfDigitsCode(EntityNameEnum.WORK_REPORT));
workReportDAO.save(workReport);
+ sumChargedEffortDAO.recalculateTimesheetDates(orderElements);
}
resetModifiedFields();
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 f05831956..70de3ad76 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
@@ -274,12 +274,17 @@ public class WorkReportModel extends IntegrationEntityModel implements
@Override
@Transactional
public void confirmSave() throws ValidationException {
+ Set orderElements = sumChargedEffortDAO
+ .getOrderElementsToRecalculateTimsheetDates(
+ workReport.getWorkReportLines(),
+ deletedWorkReportLinesSet);
sumChargedEffortDAO.updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(deletedWorkReportLinesSet);
sumChargedEffortDAO
.updateRelatedSumChargedEffortWithWorkReportLineSet(workReport
.getWorkReportLines());
workReportDAO.save(workReport);
+ sumChargedEffortDAO.recalculateTimesheetDates(orderElements);
}
@Override
@@ -412,10 +417,14 @@ public class WorkReportModel extends IntegrationEntityModel implements
//before deleting the report, update OrderElement.SumChargedHours
try {
workReportDAO.reattach(workReport);
+ Set orderElements = sumChargedEffortDAO
+ .getOrderElementsToRecalculateTimsheetDates(null,
+ workReport.getWorkReportLines());
sumChargedEffortDAO
.updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(workReport
.getWorkReportLines());
workReportDAO.remove(workReport.getId());
+ sumChargedEffortDAO.recalculateTimesheetDates(orderElements);
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/ws/common/impl/GenericRESTService.java b/libreplan-webapp/src/main/java/org/libreplan/ws/common/impl/GenericRESTService.java
index 278bad001..2e324e383 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/ws/common/impl/GenericRESTService.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/ws/common/impl/GenericRESTService.java
@@ -143,6 +143,7 @@ public abstract class GenericRESTService implements
IWorkReportService {
+ private Set orderElements;
+
@Autowired
private IWorkReportDAO workReportDAO;
@Autowired
private IWorkReportLineDAO workReportLineDAO;
- @Autowired
- private IOrderElementDAO orderElementDAO;
-
@Autowired
private ISumChargedEffortDAO sumChargedEffortDAO;
@@ -120,11 +121,19 @@ public class WorkReportServiceREST extends
@Override
protected void beforeSaving(WorkReport entity) {
+ orderElements = sumChargedEffortDAO
+ .getOrderElementsToRecalculateTimsheetDates(
+ entity.getWorkReportLines(), null);
sumChargedEffortDAO
.updateRelatedSumChargedEffortWithWorkReportLineSet(entity
.getWorkReportLines());
}
+ @Override
+ protected void afterSaving(WorkReport entity) {
+ sumChargedEffortDAO.recalculateTimesheetDates(orderElements);
+ }
+
@Override
@GET
@Path("/{code}/")
@@ -140,10 +149,14 @@ public class WorkReportServiceREST extends
public Response removeWorkReport(@PathParam("code") String code) {
try {
WorkReport workReport = workReportDAO.findByCode(code);
+ Set orderElements = sumChargedEffortDAO
+ .getOrderElementsToRecalculateTimsheetDates(null,
+ workReport.getWorkReportLines());
sumChargedEffortDAO
.updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(workReport
.getWorkReportLines());
workReportDAO.remove(workReport.getId());
+ sumChargedEffortDAO.recalculateTimesheetDates(orderElements);
return Response.ok().build();
} catch (InstanceNotFoundException e) {
return Response.status(Status.NOT_FOUND).build();
@@ -157,10 +170,14 @@ public class WorkReportServiceREST extends
public Response removeWorkReportLine(@PathParam("code") String code) {
try {
WorkReportLine workReportLine = workReportLineDAO.findByCode(code);
+ Set orderElements = sumChargedEffortDAO
+ .getOrderElementsToRecalculateTimsheetDates(null,
+ Collections.singleton(workReportLine));
sumChargedEffortDAO
.updateRelatedSumChargedEffortWithDeletedWorkReportLineSet(new HashSet(
Arrays.asList(workReportLine)));
workReportLineDAO.remove(workReportLine.getId());
+ sumChargedEffortDAO.recalculateTimesheetDates(orderElements);
return Response.ok().build();
} catch (InstanceNotFoundException e) {
return Response.status(Status.NOT_FOUND).build();