diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/advance/entities/DirectAdvanceAssignment.java b/navalplanner-business/src/main/java/org/navalplanner/business/advance/entities/DirectAdvanceAssignment.java index 0c2912b48..954619edf 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/advance/entities/DirectAdvanceAssignment.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/advance/entities/DirectAdvanceAssignment.java @@ -144,6 +144,12 @@ public class DirectAdvanceAssignment extends AdvanceAssignment { RoundingMode.DOWN); } + public void addAdvanceMeasurements(Set measurements) { + for (AdvanceMeasurement each: measurements) { + addAdvanceMeasurements(each); + } + } + public boolean addAdvanceMeasurements(AdvanceMeasurement advanceMeasurement) { boolean result = this.advanceMeasurements.add(advanceMeasurement); if (result) { @@ -156,7 +162,7 @@ public class DirectAdvanceAssignment extends AdvanceAssignment { return result; } - public void removeAdvanceMeasurements(AdvanceMeasurement advanceMeasurement) { + public void removeAdvanceMeasurement(AdvanceMeasurement advanceMeasurement) { this.advanceMeasurements.remove(advanceMeasurement); advanceMeasurement.setAdvanceAssignment(null); getOrderElement().markAsDirtyLastAdvanceMeasurementForSpreading(); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/ManageOrderElementAdvancesModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/ManageOrderElementAdvancesModel.java index 778d672cf..036aed734 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/ManageOrderElementAdvancesModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/ManageOrderElementAdvancesModel.java @@ -29,9 +29,11 @@ import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -64,9 +66,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.zkoss.zul.SimpleXYModel; import org.zkoss.zul.XYModel; + /** * Service to manage the advance of a selected order element + * * @author Susana Montes Pedreira + * @author Diego Pino García */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) @@ -92,6 +97,8 @@ public class ManageOrderElementAdvancesModel implements private List listAdvanceTypes; + private CancelOperation cancelOperation = new CancelOperation(); + @Autowired public ManageOrderElementAdvancesModel( IAdvanceMeasurementDAO advanceMeasurementDAO, @@ -279,26 +286,7 @@ public class ManageOrderElementAdvancesModel implements @Override public void cancel() { - for (AdvanceAssignment each : listAdvanceAssignments) { - if (each instanceof DirectAdvanceAssignment) { - DirectAdvanceAssignment directAdvanceAssignment = (DirectAdvanceAssignment) each; - Set advanceMeasurements = getNewAdvanceMeasurementsFor(directAdvanceAssignment); - directAdvanceAssignment - .removeAdvanceMeasurements(advanceMeasurements); - } - } - } - - private Set getNewAdvanceMeasurementsFor( - DirectAdvanceAssignment directAdvanceAssignment) { - Set result = new HashSet(); - for (AdvanceMeasurement each : directAdvanceAssignment - .getAdvanceMeasurements()) { - if (each.getId() == null) { - result.add(each); - } - } - return result; + cancelOperation.restoreOriginalState(); } @Override @@ -346,20 +334,29 @@ public class ManageOrderElementAdvancesModel implements @Override public AdvanceMeasurement addNewLineAdvaceMeasurement() { - if (this.advanceAssignment != null) { - AdvanceMeasurement newMeasurement = AdvanceMeasurement.create(); - newMeasurement.setDate(new LocalDate()); - newMeasurement.setAdvanceAssignment(this.advanceAssignment); - if (!this.advanceAssignment.addAdvanceMeasurements( - newMeasurement)) { - newMeasurement.setDate(null); - this.advanceAssignment.addAdvanceMeasurements(newMeasurement); - } + if (advanceAssignment != null) { + AdvanceMeasurement newMeasurement = createMeasurement(); + addMeasurement(advanceAssignment, newMeasurement); return newMeasurement; } return null; } + private AdvanceMeasurement createMeasurement() { + AdvanceMeasurement result = AdvanceMeasurement.create(); + result.setDate(new LocalDate()); + result.setAdvanceAssignment(advanceAssignment); + return result; + } + + private void addMeasurement(AdvanceAssignment assignment, AdvanceMeasurement measurement) { + if (!advanceAssignment.addAdvanceMeasurements(measurement)) { + measurement.setDate(null); + advanceAssignment.addAdvanceMeasurements(measurement); + } + cancelOperation.markAsAdded(measurement); + } + @Override public void removeLineAdvanceAssignment(AdvanceAssignment advance) { advance.setOrderElement(null); @@ -369,8 +366,9 @@ public class ManageOrderElementAdvancesModel implements } @Override - public void removeLineAdvanceMeasurement(AdvanceMeasurement advance) { - this.advanceAssignment.removeAdvanceMeasurements(advance); + public void removeLineAdvanceMeasurement(AdvanceMeasurement measurement) { + cancelOperation.markAsRemoved(measurement); + this.advanceAssignment.removeAdvanceMeasurement(measurement); } @Override @@ -475,6 +473,7 @@ public class ManageOrderElementAdvancesModel implements orderElementDAO.checkVersion(orderElement); reattachmentOrderElement(); validateBasicData(); + cancelOperation.clear(); } private void validateBasicData() throws InstanceNotFoundException, @@ -840,4 +839,78 @@ public class ManageOrderElementAdvancesModel implements return false; } + /** + * @author Diego Pino García + * + * Keeps track of added and removed measurements. When the cancel button is + * pressed, restores the original state of the advance assignments + * + */ + private class CancelOperation { + + private Set addedMeasurements = new HashSet(); + + private Map> removedMeasurements = new HashMap>(); + + public void restoreOriginalState() { + removeAddedMeasurements(); + addRemovedMeasurements(); + clear(); + } + + private void clear() { + addedMeasurements.clear(); + removedMeasurements.clear(); + } + + private void removeAddedMeasurements() { + for (AdvanceAssignment each : removedMeasurements.keySet()) { + if (each instanceof DirectAdvanceAssignment) { + DirectAdvanceAssignment directAdvanceAssignment = (DirectAdvanceAssignment) each; + directAdvanceAssignment + .addAdvanceMeasurements(removedMeasurements + .get(each)); + } + } + removedMeasurements.clear(); + } + + private void addRemovedMeasurements() { + for (AdvanceMeasurement each : addedMeasurements) { + AdvanceAssignment assignment = each.getAdvanceAssignment(); + if (assignment instanceof DirectAdvanceAssignment) { + DirectAdvanceAssignment directAdvanceAssignment = (DirectAdvanceAssignment) assignment; + directAdvanceAssignment.removeAdvanceMeasurement(each); + } + } + addedMeasurements.clear(); + } + + /** + * Keeps track of new measurement added to {@link AdvanceAssignment}. If + * the user later clicks cancel these elements will be removed + * + * @param measurement + */ + public void markAsAdded(AdvanceMeasurement measurement) { + addedMeasurements.add(measurement); + } + + /** + * Keeps track of measurement removed from {@link AdvanceAssignment}. If + * the user later clicks cancel these elements will be added back again + * + * @param measurement + */ + public void markAsRemoved(AdvanceMeasurement measurement) { + AdvanceAssignment assignment = measurement.getAdvanceAssignment(); + if (!removedMeasurements.containsKey(assignment)) { + removedMeasurements.put(assignment, new HashSet()); + } + Set measurements = removedMeasurements.get(assignment); + measurements.add(measurement); + } + + } + }