diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java index 8dd4299fb..f4a55dba1 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/BaseCalendar.java @@ -25,6 +25,7 @@ import static org.navalplanner.business.workingday.EffortDuration.hours; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -45,10 +46,10 @@ import org.navalplanner.business.common.entities.EntitySequence; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.resources.entities.VirtualWorker; import org.navalplanner.business.workingday.EffortDuration; -import org.navalplanner.business.workingday.EffortDuration.IEffortFrom; import org.navalplanner.business.workingday.IntraDayDate; -import org.navalplanner.business.workingday.IntraDayDate.PartialDay; import org.navalplanner.business.workingday.ResourcesPerDay; +import org.navalplanner.business.workingday.EffortDuration.IEffortFrom; +import org.navalplanner.business.workingday.IntraDayDate.PartialDay; /** * Represents a calendar with some exception days. A calendar is valid till the @@ -72,6 +73,11 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { public static BaseCalendar createBasicCalendar() { BaseCalendar calendar = create(); + resetDefaultCapacities(calendar); + return calendar; + } + + private static void resetDefaultCapacities(BaseCalendar calendar) { Capacity eightHours = Capacity.create(hours(8)) .overAssignableWithoutLimit(); calendar.setCapacityAt(Days.MONDAY, eightHours); @@ -81,7 +87,6 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { calendar.setCapacityAt(Days.FRIDAY, eightHours); calendar.setCapacityAt(Days.SATURDAY, Capacity.zero()); calendar.setCapacityAt(Days.SUNDAY, Capacity.zero()); - return calendar; } public static BaseCalendar createUnvalidated(String code, String name, @@ -149,6 +154,8 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { protected BaseCalendar(CalendarData calendarData) { calendarDataVersions.add(calendarData); + Collections.sort(calendarDataVersions, + CalendarData.BY_EXPIRING_DATE_COMPARATOR); } public void setName(String name) { @@ -389,19 +396,133 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { * new calendar will be used from that date onwards. */ public void newVersion(LocalDate date) throws IllegalArgumentException { + BaseCalendar lastParent = null; + if (getLastCalendarData() != null) { + lastParent = getLastCalendarData().getParent(); + } + CalendarData newCalendarData = createLastVersion(date); + newCalendarData.setParent(lastParent); + } + + public CalendarData createNewVersionInsideIntersection(LocalDate startDate, + LocalDate expiringDate) { + for (CalendarData nextVersion : calendarDataVersions) { + if ((nextVersion.getExpiringDate() == null) + || (expiringDate.compareTo(nextVersion.getExpiringDate()) < 0)) { + int index = calendarDataVersions.indexOf(nextVersion); + if (index > 0) { + CalendarData prevVersion = calendarDataVersions + .get(index - 1); + + if (startDate.compareTo(prevVersion.getExpiringDate()) >= 0) { + prevVersion.setExpiringDate(startDate); + + CalendarData newCalendarData = CalendarData.create(); + newCalendarData.setExpiringDate(expiringDate); + calendarDataVersions.add(newCalendarData); + Collections.sort(calendarDataVersions, + CalendarData.BY_EXPIRING_DATE_COMPARATOR); + return newCalendarData; + }else{ + throw new IllegalArgumentException( + "the new version includes a whole version already exists"); + } + } else { + throw new IllegalArgumentException( + "the new version will be the first one, and the start date must be empty"); + } + } + } + throw new IllegalArgumentException( + "the new version will be the last one, and the expiring date must be empty"); + } + + public CalendarData createLastVersion(LocalDate startDate) + throws IllegalArgumentException { CalendarData calendarData = getCalendarDataBeforeTheLastIfAny(); if ((calendarData.getExpiringDate() != null) - && (date.compareTo(calendarData.getExpiringDate()) <= 0)) { + && (startDate.compareTo(calendarData.getExpiringDate()) <= 0)) { throw new IllegalArgumentException( "Version date must be greater than expiring date of " + "all versions of this calendar"); } - getLastCalendarData().setExpiringDate(date); + getLastCalendarData().setExpiringDate(startDate); CalendarData newCalendarData = CalendarData.create(); - newCalendarData.setParent(getLastCalendarData().getParent()); calendarDataVersions.add(newCalendarData); + Collections.sort(calendarDataVersions, + CalendarData.BY_EXPIRING_DATE_COMPARATOR); + return newCalendarData; + } + + public CalendarData createFirstVersion(LocalDate expiringDate) + throws IllegalArgumentException { + CalendarData firstVersion = getFirstCalendarData(); + if ((firstVersion.getExpiringDate() != null) + && (expiringDate.compareTo(firstVersion.getExpiringDate()) >= 0)) { + throw new IllegalArgumentException( + "Version expiring date must be lower than expiring date of " + + "all versions of this calendar"); + } + + CalendarData newCalendarData = CalendarData.create(); + newCalendarData.setExpiringDate(expiringDate); + calendarDataVersions.add(newCalendarData); + Collections.sort(calendarDataVersions, + CalendarData.BY_EXPIRING_DATE_COMPARATOR); + return newCalendarData; + } + + public void newVersion(LocalDate startDate, LocalDate expiringDate, + BaseCalendar parent) throws IllegalArgumentException { + + CalendarData newCalendarData; + if (startDate != null && expiringDate != null) { + if (startDate.compareTo(expiringDate) > 0) { + throw new IllegalArgumentException( + "the start date must be lower than expiring date"); + } + if (calendarDataVersions.size() == 1) { + BaseCalendar lastParent = getLastCalendarData().getParent(); + newCalendarData = createLastVersion(startDate); + createLastVersion(expiringDate).setParent(lastParent); + } else { + newCalendarData = createNewVersionInsideIntersection(startDate, + expiringDate); + } + } else if (startDate != null) { + newCalendarData = createLastVersion(startDate); + } else if (expiringDate != null) { + newCalendarData = createFirstVersion(expiringDate); + } else { + throw new IllegalArgumentException( + "At least the start date must be specified"); + } + + if (parent != null) { + newCalendarData.setParent(parent); + } else { + newCalendarData.setParent(getLastCalendarData().getParent()); + } + + resetDefaultCapacities(newCalendarData); + } + + private void resetDefaultCapacities(CalendarData version){ + if(version.getParent() == null){ + CalendarData.resetDefaultCapacities(version); + }else{ + BaseCalendar parent = version.getParent(); + CalendarData currentVersion = parent.getCalendarData(LocalDate + .fromDateFields(new Date())); + if (currentVersion != null) { + for (Days day : Days.values()) { + version.setCapacityAt(day, currentVersion + .getCapacityOn(day)); + } + } + } } public void addNewVersion(CalendarData version){ @@ -412,6 +533,8 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { } else{ calendarDataVersions.add(version); + Collections.sort(calendarDataVersions, + CalendarData.BY_EXPIRING_DATE_COMPARATOR); return; } } @@ -438,6 +561,8 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { } calendarDataVersions.add(version); + Collections.sort(calendarDataVersions, + CalendarData.BY_EXPIRING_DATE_COMPARATOR); } @@ -502,6 +627,13 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { return calendarDataVersions.get(calendarDataVersions.size() - 1); } + public CalendarData getFirstCalendarData() { + if (calendarDataVersions.isEmpty()) { + return null; + } + return calendarDataVersions.get(0); + } + public void setCapacityAt(Days day, Capacity capacity) { CalendarData calendarData = getLastCalendarData(); calendarData.setCapacityAt(day, capacity); @@ -579,6 +711,10 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar { private CalendarData getPreviousCalendarData(LocalDate date) { CalendarData calendarData = getCalendarData(date); + return getPrevious(calendarData); + } + + public CalendarData getPrevious(CalendarData calendarData) { Integer index = calendarDataVersions.indexOf(calendarData) - 1; if (index < 0) { return null; diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarData.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarData.java index 2313fdac6..9c561c265 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarData.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarData.java @@ -21,7 +21,10 @@ package org.navalplanner.business.calendars.entities; +import static org.navalplanner.business.workingday.EffortDuration.hours; + import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -43,6 +46,19 @@ public class CalendarData extends IntegrationEntity { return create(new CalendarData()); } + public static final Comparator BY_EXPIRING_DATE_COMPARATOR = new Comparator() { + @Override + public int compare(CalendarData o1, CalendarData o2) { + if (o2.getExpiringDate() != null && o1.getExpiringDate() != null) { + return o1.getExpiringDate().compareTo(o2.getExpiringDate()); + } + if (o1.getExpiringDate() == null) { + return 1; + } + return -1; + } + }; + public static CalendarData createUnvalidated(String code, LocalDate expiringDate, BaseCalendar parent) { CalendarData calendarData = create(new CalendarData(), code); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarCRUDController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarCRUDController.java index a490b085b..ff40f940e 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarCRUDController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarCRUDController.java @@ -23,9 +23,12 @@ package org.navalplanner.web.calendars; import static org.navalplanner.web.I18nHelper._; +import java.util.Date; + import org.apache.commons.logging.LogFactory; import org.joda.time.LocalDate; import org.navalplanner.business.calendars.entities.BaseCalendar; +import org.navalplanner.business.calendars.entities.CalendarData; import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.web.common.IMessagesForUser; import org.navalplanner.web.common.Level; diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarEditionController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarEditionController.java index 36aca798c..54b5c80b6 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarEditionController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarEditionController.java @@ -70,6 +70,7 @@ import org.zkoss.zul.Button; import org.zkoss.zul.Checkbox; import org.zkoss.zul.Combobox; import org.zkoss.zul.Comboitem; +import org.zkoss.zul.Constraint; import org.zkoss.zul.Datebox; import org.zkoss.zul.Hbox; import org.zkoss.zul.Label; @@ -130,6 +131,10 @@ public abstract class BaseCalendarEditionController extends private boolean creatingNewVersion = false; + private Date newWorkWeekStartDate; + + private Date newWorkWeekExpiringDate; + private CapacityPicker capacityPicker; private IMessagesForUser messagesForUser; @@ -154,9 +159,6 @@ public abstract class BaseCalendarEditionController extends @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); - if (baseCalendarModel.isDerived()) { - prepareParentCombo(); - } prepareExceptionTypeCombo(); capacityPicker = addEffortDurationPickerAtWorkableTimeRow(comp); updateWithCapacityFrom(getSelectedExceptionType()); @@ -274,43 +276,6 @@ public abstract class BaseCalendarEditionController extends } } - private void prepareParentCombo() { - Combobox parentCalendars = (Combobox) window - .getFellow("parentCalendars"); - - fillParentComboAndMarkSelectedItem(parentCalendars); - addListenerParentCombo(parentCalendars); - } - - private void fillParentComboAndMarkSelectedItem(Combobox parentCalendars) { - parentCalendars.getChildren().clear(); - BaseCalendar parent = baseCalendarModel.getParent(); - - List possibleParentCalendars = getParentCalendars(); - for (BaseCalendar baseCalendar : possibleParentCalendars) { - Comboitem item = new Comboitem(baseCalendar.getName()); - item.setValue(baseCalendar); - parentCalendars.appendChild(item); - if (baseCalendar.getId().equals(parent.getId())) { - parentCalendars.setSelectedItem(item); - } - } - } - - private void addListenerParentCombo(final Combobox parentCalendars) { - parentCalendars.addEventListener(Events.ON_SELECT, new EventListener() { - - @Override - public void onEvent(Event event) { - BaseCalendar selected = (BaseCalendar) parentCalendars - .getSelectedItem().getValue(); - baseCalendarModel.setParent(selected); - reloadCurrentWindow(); - } - - }); - } - public boolean isEditing() { return baseCalendarModel.isEditing(); } @@ -441,27 +406,21 @@ public abstract class BaseCalendarEditionController extends private void reloadDayInformation() { Util.reloadBindings(window.getFellow("dayInformation")); Util.reloadBindings(window.getFellow("exceptionInformation")); - Util.reloadBindings(window.getFellow("historyInformation")); + reloadWorkWeeksList(); reloadTypeDatesAndDuration(); - reloadParentCombo(); highlightDaysOnCalendar(); } - private void reloadParentCombo() { - if (baseCalendarModel.isDerived()) { - BaseCalendar parent = baseCalendarModel.getParent(); - Combobox parentCalendars = (Combobox) window - .getFellow("parentCalendars"); - @SuppressWarnings("unchecked") - List items = parentCalendars.getItems(); - for (Comboitem item : items) { - BaseCalendar baseCalendar = (BaseCalendar) item.getValue(); - if (baseCalendar.getId().equals(parent.getId())) { - parentCalendars.setSelectedItem(item); - break; - } - } - } + private void reloadSelectDayInformation() { + Util.reloadBindings(window.getFellow("dayInformation")); + Util.reloadBindings(window.getFellow("exceptionInformation")); + Util.reloadBindings(window.getFellow("hoursPerDay")); + reloadTypeDatesAndDuration(); + highlightDaysOnCalendar(); + } + + private void reloadWorkWeeksList() { + Util.reloadBindings(window.getFellow("historyInformation")); } private void reloadTypeDatesAndDuration() { @@ -507,7 +466,7 @@ public abstract class BaseCalendarEditionController extends return selectedDay; } - private static Date toDate(LocalDate date){ + private static Date toDate(LocalDate date) { if (date == null) { return null; } @@ -523,8 +482,7 @@ public abstract class BaseCalendarEditionController extends public void setSelectedDay(LocalDate date) { baseCalendarModel.setSelectedDay(date); - - reloadDayInformation(); + reloadSelectDayInformation(); } private Map getDaysCurrentMonthByType() { @@ -645,9 +603,9 @@ public abstract class BaseCalendarEditionController extends } Capacity capacity = capacityPicker.getValue(); - baseCalendarModel.createException(type, - LocalDate.fromDateFields(startDate), - LocalDate.fromDateFields(endDate), capacity); + baseCalendarModel.createException(type, LocalDate + .fromDateFields(startDate), LocalDate.fromDateFields(endDate), + capacity); reloadDayInformation(); } @@ -661,44 +619,6 @@ public abstract class BaseCalendarEditionController extends reloadDayInformation(); } - public Date getDateValidFrom() { - return toDate(baseCalendarModel.getDateValidFrom()); - } - - public void setDateValidFrom(Date date) { - Component component = window.getFellow("dateValidFrom"); - - try { - baseCalendarModel.setDateValidFrom(toLocalDate(date)); - } catch (IllegalArgumentException e) { - throw new WrongValueException(component, e.getMessage()); - } catch (UnsupportedOperationException e) { - throw new WrongValueException(component, e.getMessage()); - } - Clients.closeErrorBox(component); - baseCalendarModel.setSelectedDay(toLocalDate(date)); - reloadCurrentWindow(); - } - - public Date getExpiringDate() { - return baseCalendarModel.getExpiringDate(); - } - - public void setExpiringDate(Date date) { - Component component = window.getFellow("expiringDate"); - - try { - baseCalendarModel.setExpiringDate(toLocalDate(date).plusDays(1)); - } catch (IllegalArgumentException e) { - throw new WrongValueException(component, e.getMessage()); - } catch (UnsupportedOperationException e) { - throw new WrongValueException(component, e.getMessage()); - } - Clients.closeErrorBox(component); - baseCalendarModel.setSelectedDay(toLocalDate(date)); - reloadCurrentWindow(); - } - public List getHistoryVersions() { return baseCalendarModel.getHistoryVersions(); } @@ -714,59 +634,205 @@ public abstract class BaseCalendarEditionController extends CalendarData calendarData = (CalendarData) data; item.setValue(calendarData); - Listcell parentListcell = new Listcell(); - Label parentLabel = new Label(); - BaseCalendar parent = calendarData.getParent(); - if (parent != null) { - parentLabel.setValue(parent.getName()); + if (isDerived()) { + appendParentCombobox(item, calendarData); + } else { + appendParentLabel(item, calendarData); } - parentListcell.appendChild(parentLabel); - item.appendChild(parentListcell); + appendStartDatebox(item, calendarData); + appendExpiringDatebox(item, calendarData); + appendSummaryLabel(item, calendarData); + appendOperationsListcell(item, calendarData); + markAsSelected(item, calendarData); + addEventListener(item); + } - Listcell validFromListcell = new Listcell(); - Label validFromLabel = new Label(); - final LocalDate dateValidFrom = baseCalendarModel - .getValidFrom(calendarData); - if (dateValidFrom != null) { - validFromLabel.setValue(dateValidFrom.toString()); - } - validFromListcell.appendChild(validFromLabel); - item.appendChild(validFromListcell); + private void appendSummaryLabel(final Listitem listItem, + final CalendarData version) { + BaseCalendar parent = version.getParent(); - Listcell expiringDateListcell = new Listcell(); - final LocalDate expiringDate = calendarData.getExpiringDate(); - Label expiringDateLabel = new Label(); - if (expiringDate != null) { - LocalDate date = new LocalDate(expiringDate).minusDays(1); - expiringDateLabel.setValue(date.toString()); - } - expiringDateListcell.appendChild(expiringDateLabel); - item.appendChild(expiringDateListcell); - - Listcell summaryListcell = new Listcell(); List summary = new ArrayList(); for (Days day : Days.values()) { - if (calendarData.isDefault(day)) { + if (version.isDefault(day)) { if (parent == null) { summary.add("0"); } else { summary.add(_("D")); } } else { - summary.add(asString(calendarData.getCapacityOn(day))); + summary.add(asString(version.getCapacityOn(day))); } } - summaryListcell.appendChild(new Label(StringUtils.join(summary, - " - "))); - item.appendChild(summaryListcell); + Label summaryLabel = new Label(StringUtils.join(summary, " - ")); - appendOperationsListcell(item, calendarData); - markAsSelected(item, calendarData); - addEventListener(item); + Listcell listCell = new Listcell(); + listCell.appendChild(summaryLabel); + listItem.appendChild(listCell); } - private void markAsSelected(Listitem item, - CalendarData calendarData) { + private void appendStartDatebox(final Listitem listItem, + final CalendarData version) { + Datebox datebox = new Datebox(); + + final LocalDate dateValidFrom = baseCalendarModel + .getValidFrom(version); + if (dateValidFrom != null) { + Util.bind(datebox, new Util.Getter() { + @Override + public Date get() { + return dateValidFrom.toDateTimeAtStartOfDay().toDate(); + } + }); + datebox.setDisabled(false); + } else { + datebox.setDisabled(true); + } + + datebox.addEventListener(Events.ON_CHANGE, new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + reloadWorkWeeksList(); + } + }); + + datebox.setConstraint(new Constraint() { + @Override + public void validate(Component comp, Object value) + throws WrongValueException { + if (!baseCalendarModel.checkAndChangeStartDate(version, + LocalDate.fromDateFields(((Date) value)))) { + throw new WrongValueException( + comp, + _("This date can not include the whole previous work week")); + } + } + }); + + Listcell listCell = new Listcell(); + listCell.appendChild(datebox); + listItem.appendChild(listCell); + } + + private void appendExpiringDatebox(final Listitem listItem, + final CalendarData version) { + Datebox datebox = new Datebox(); + + final LocalDate expiringDate = version.getExpiringDate(); + if (expiringDate != null) { + datebox.setDisabled(false); + } else { + datebox.setDisabled(true); + } + + Util.bind(datebox, new Util.Getter() { + @Override + public Date get() { + LocalDate expiringDate = version.getExpiringDate(); + if (expiringDate != null) { + return expiringDate.minusDays(1) + .toDateTimeAtStartOfDay().toDate(); + } + return null; + } + }, new Util.Setter() { + @Override + public void set(Date value) { + LocalDate expiringDate = null; + if (value != null) { + expiringDate = new LocalDate(value).plusDays(1); + } + version.setExpiringDate(expiringDate); + } + }); + + datebox.addEventListener(Events.ON_CHANGE, new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + reloadWorkWeeksList(); + } + }); + + datebox.setConstraint(new Constraint() { + @Override + public void validate(Component comp, Object value) + throws WrongValueException { + if (!baseCalendarModel.checkChangeExpiringDate(version, + LocalDate.fromDateFields(((Date) value)))) { + throw new WrongValueException( + comp, + _("This date can not include the whole next work week")); + } + } + }); + + Listcell listCell = new Listcell(); + listCell.appendChild(datebox); + listItem.appendChild(listCell); + } + + private void appendParentLabel(Listitem listItem, CalendarData version) { + final Label labelParent = new Label(); + if (version.getParent() != null) { + labelParent.setValue(version.getParent().getName()); + } + + Listcell listCell = new Listcell(); + listCell.appendChild(labelParent); + listItem.appendChild(listCell); + } + + private void appendParentCombobox(final Listitem listItem, + final CalendarData version) { + final Combobox comboParents = new Combobox(); + final List listParents = getParentCalendars(); + + for (BaseCalendar parent : listParents) { + Comboitem comboItem = new Comboitem(); + comboItem.setValue(parent); + comboItem.setLabel(parent.getName()); + comboItem.setParent(comboParents); + + if ((version.getParent()) != null + && (parent.getId().equals(version.getParent().getId()))) { + comboParents.setSelectedItem(comboItem); + } + } + + comboParents.addEventListener(Events.ON_SELECT, + new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + if (comboParents.getSelectedItem() != null) { + BaseCalendar parent = (BaseCalendar) comboParents + .getSelectedItem().getValue(); + version.setParent(parent); + } + } + }); + + Util.bind(comboParents, new Util.Getter() { + @Override + public Comboitem get() { + return comboParents.getSelectedItem(); + } + }, new Util.Setter() { + @Override + public void set(Comboitem comboItem) { + if (((comboItem != null)) && (comboItem.getValue() != null) + && (comboItem.getValue() instanceof BaseCalendar)) { + BaseCalendar parent = (BaseCalendar) comboItem + .getValue(); + version.setParent(parent); + } + } + + }); + Listcell listCell = new Listcell(); + listCell.appendChild(comboParents); + listItem.appendChild(listCell); + } + + private void markAsSelected(Listitem item, CalendarData calendarData) { CalendarData selected = baseCalendarModel.getCalendarData(); if ((selected != null) && (calendarData.equals(selected))) { item.setSelected(true); @@ -780,8 +846,7 @@ public abstract class BaseCalendarEditionController extends item.appendChild(listcell); } - private Button createRemoveButton( - final CalendarData calendarData) { + private Button createRemoveButton(final CalendarData calendarData) { Button result = createButton("/common/img/ico_borrar1.png", _("Delete"), "/common/img/ico_borrar.png", "icono", new EventListener() { @@ -796,6 +861,8 @@ public abstract class BaseCalendarEditionController extends || (!baseCalendarModel.getLastCalendarData().equals( calendarData))) { result.setDisabled(true); + } else { + result.setDisabled(false); } return result; } @@ -837,18 +904,16 @@ public abstract class BaseCalendarEditionController extends } - public boolean isLastVersion() { - return baseCalendarModel.isLastVersion(); + public boolean isLastVersion(LocalDate selectedDate) { + return baseCalendarModel.isLastVersion(selectedDate); } - public boolean isFirstVersion() { - return baseCalendarModel.isFirstVersion(); + public boolean isFirstVersion(LocalDate selectedDate) { + return baseCalendarModel.isFirstVersion(selectedDate); } public void goToDate(Date date) { setSelectedDay(toLocalDate(date)); - - reloadCurrentWindow(); } public boolean isCreatingNewVersion() { @@ -857,6 +922,7 @@ public abstract class BaseCalendarEditionController extends public void createNewVersion() { creatingNewVersion = true; + initDatesToCreateNewVersion(); try { Util.reloadBindings(createNewVersionWindow); createNewVersionWindow.doModal(); @@ -865,21 +931,47 @@ public abstract class BaseCalendarEditionController extends } } + private void initDatesToCreateNewVersion() { + this.newWorkWeekStartDate = (new LocalDate()).plusDays(1) + .toDateTimeAtStartOfDay().toDate(); + this.newWorkWeekExpiringDate = (new LocalDate()).plusDays(2) + .toDateTimeAtStartOfDay().toDate(); + } public void acceptCreateNewVersion() { - Component component = createNewVersionWindow - .getFellow("dateValidFromNewVersion"); - LocalDate date = getLocalDateFrom((Datebox) component); - try { - baseCalendarModel.createNewVersion(date); - } catch (IllegalArgumentException e) { - throw new WrongValueException(component, e.getMessage()); + Component compStartDate = createNewVersionWindow + .getFellow("startDateValidFromNewVersion"); + LocalDate startDate = getLocalDateFrom((Datebox) compStartDate); + + Component compExpiringDate = createNewVersionWindow + .getFellow("expiringDateValidFromNewVersion"); + LocalDate expiringDate = getLocalDateFrom((Datebox) compExpiringDate); + + BaseCalendar selected = null; + if (isDerived()) { + Combobox parentCalendars = (Combobox) createNewVersionWindow + .getFellow("parentCalendars"); + selected = (BaseCalendar) parentCalendars.getSelectedItem() + .getValue(); } - Clients.closeErrorBox(component); + try { + baseCalendarModel.createNewVersion(startDate, expiringDate, + selected); + } catch (IllegalArgumentException e) { + throw new WrongValueException(compStartDate, e.getMessage()); + } + + Clients.closeErrorBox(compStartDate); + Clients.closeErrorBox(compExpiringDate); creatingNewVersion = false; Util.reloadBindings(createNewVersionWindow); - setSelectedDay(date); + + setSelectedDay(startDate); + if ((startDate == null) && (expiringDate != null)) { + setSelectedDay(expiringDate.minusDays(1)); + } + reloadCurrentWindow(); } @@ -897,11 +989,19 @@ public abstract class BaseCalendarEditionController extends } public Date getDateValidFromNewVersion() { - return (new LocalDate()).plusDays(1).toDateTimeAtStartOfDay().toDate(); + return newWorkWeekStartDate; } public void setDateValidFromNewVersion(Date date) { - // Just for ZK binding not needed + this.newWorkWeekStartDate = date; + } + + public Date getDateValidToNewVersion() { + return newWorkWeekExpiringDate; + } + + public void setDateValidToNewVersion(Date date) { + this.newWorkWeekExpiringDate = date; } public List getParentCalendars() { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarModel.java index 3bfca59c0..64f36f6e4 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/BaseCalendarModel.java @@ -23,7 +23,6 @@ package org.navalplanner.web.calendars; import static org.navalplanner.web.I18nHelper._; -import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -403,27 +402,6 @@ public class BaseCalendarModel extends IntegrationEntityModel implements return !baseCalendarDAO.findByParent(calendar).isEmpty(); } - @Override - public Date getExpiringDate() { - if ((getBaseCalendar() != null) - && (getBaseCalendar().getExpiringDate(selectedDate) != null)) { - return getBaseCalendar().getExpiringDate(selectedDate).minusDays(1) - .toDateTimeAtStartOfDay() - .toDate(); - } - - return null; - } - - @Override - public void setExpiringDate(LocalDate date) { - if ((getBaseCalendar() != null) - && (getBaseCalendar().getExpiringDate(selectedDate) != null)) { - getBaseCalendar() - .setExpiringDate(date, selectedDate); - } - } - @Override public LocalDate getDateValidFrom() { if (getBaseCalendar() != null) { @@ -451,14 +429,19 @@ public class BaseCalendarModel extends IntegrationEntityModel implements } @Override - public void createNewVersion(LocalDate date) { + public void createNewVersion(LocalDate startDate, LocalDate expiringDate, + BaseCalendar baseCalendar) { if (getBaseCalendar() != null) { - getBaseCalendar().newVersion(date); + if (expiringDate != null) { + expiringDate = expiringDate.plusDays(1); + } + getBaseCalendar().newVersion(startDate, expiringDate, + baseCalendar); } } @Override - public boolean isLastVersion() { + public boolean isLastVersion(LocalDate selectedDate) { if (getBaseCalendar() != null) { return getBaseCalendar().isLastVersion(selectedDate); } @@ -466,13 +449,50 @@ public class BaseCalendarModel extends IntegrationEntityModel implements } @Override - public boolean isFirstVersion() { + public boolean isFirstVersion(LocalDate selectedDate) { if (getBaseCalendar() != null) { return getBaseCalendar().isFirstVersion(selectedDate); } return false; } + @Override + public boolean checkAndChangeStartDate(CalendarData version, + LocalDate newStartDate) { + CalendarData prevVersion = getBaseCalendar().getPrevious(version); + if ((newStartDate != null) && (prevVersion != null)) { + if (getBaseCalendar().getPrevious(prevVersion) == null) { + return true; + } + LocalDate prevStartDate = getBaseCalendar() + .getPrevious(prevVersion).getExpiringDate(); + if ((prevStartDate == null) + || ((newStartDate + .compareTo(prevStartDate) > 0))) { + prevVersion.setExpiringDate(newStartDate); + return true; + } + } + return false; + } + + @Override + public boolean checkChangeExpiringDate(CalendarData version, + LocalDate newExpiringDate) { + Integer index = getBaseCalendar().getCalendarDataVersions().indexOf( + version); + if ((newExpiringDate != null) + && (index < getBaseCalendar().getCalendarDataVersions().size() - 1)) { + LocalDate nextExpiringDate = getBaseCalendar() + .getCalendarDataVersions().get(index + 1).getExpiringDate(); + if ((nextExpiringDate == null) + || (newExpiringDate.compareTo(nextExpiringDate) < 0)) { + return true; + } + } + return false; + } + @Override public String getName() { if (getBaseCalendar() != null) { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/IBaseCalendarModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/IBaseCalendarModel.java index 8e076db08..e1669533f 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/IBaseCalendarModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/calendars/IBaseCalendarModel.java @@ -139,21 +139,18 @@ public interface IBaseCalendarModel extends IIntegrationEntityModel { boolean isParent(BaseCalendar calendar); - Date getExpiringDate(); - - void setExpiringDate(LocalDate date); - LocalDate getDateValidFrom(); void setDateValidFrom(LocalDate date); List getHistoryVersions(); - void createNewVersion(LocalDate date); + void createNewVersion(LocalDate startDate, LocalDate expiringDate, + BaseCalendar baseCalendar); - boolean isLastVersion(); + boolean isLastVersion(LocalDate selectedDate); - boolean isFirstVersion(); + boolean isFirstVersion(LocalDate selectedDate); String getName(); @@ -214,4 +211,9 @@ public interface IBaseCalendarModel extends IIntegrationEntityModel { void checkIsReferencedByOtherEntities(BaseCalendar calendar) throws ValidationException; + boolean checkAndChangeStartDate(CalendarData version, LocalDate newStartDate); + + boolean checkChangeExpiringDate(CalendarData version, + LocalDate newExpiringDate); + } diff --git a/navalplanner-webapp/src/main/webapp/calendars/_createNewVersion.zul b/navalplanner-webapp/src/main/webapp/calendars/_createNewVersion.zul index b481e857e..31217254f 100644 --- a/navalplanner-webapp/src/main/webapp/calendars/_createNewVersion.zul +++ b/navalplanner-webapp/src/main/webapp/calendars/_createNewVersion.zul @@ -20,14 +20,34 @@ --> + id="createNewVersion" title="${i18n:_('Create new version')}" width="350px"> -