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 a5fab5eed..ce530bdbd 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 @@ -201,15 +201,17 @@ public class BaseCalendar extends BaseEntity implements IWorkHours { exceptions.remove(day); } - public void updateExceptionDay(Date date, Integer hours) + public void updateExceptionDay(Date date, Integer hours, + CalendarExceptionType type) throws IllegalArgumentException { - updateExceptionDay(new LocalDate(date), hours); + updateExceptionDay(new LocalDate(date), hours, type); } - public void updateExceptionDay(LocalDate date, Integer hours) + public void updateExceptionDay(LocalDate date, Integer hours, + CalendarExceptionType type) throws IllegalArgumentException { removeExceptionDay(date); - CalendarException day = CalendarException.create(date, hours); + CalendarException day = CalendarException.create(date, hours, type); addExceptionDay(day); } @@ -449,7 +451,7 @@ public class BaseCalendar extends BaseEntity implements IWorkHours { return Collections.unmodifiableList(calendarDataVersions); } - private CalendarData getCalendarData(LocalDate date) { + public CalendarData getCalendarData(LocalDate date) { for (CalendarData calendarData : calendarDataVersions) { if (calendarData.getExpiringDate() == null) { return calendarData; @@ -463,7 +465,7 @@ public class BaseCalendar extends BaseEntity implements IWorkHours { throw new RuntimeException("Some version should not be expired"); } - private CalendarData getLastCalendarData() { + public CalendarData getLastCalendarData() { if (calendarDataVersions.isEmpty()) { return null; } @@ -643,4 +645,47 @@ public class BaseCalendar extends BaseEntity implements IWorkHours { return result; } + public CalendarExceptionType getExceptionType(Date date) { + return getExceptionType(new LocalDate(date)); + } + + public CalendarExceptionType getExceptionType(LocalDate date) { + CalendarException exceptionDay = getExceptionDay(date); + if (exceptionDay == null) { + return null; + } + + return exceptionDay.getType(); + } + + public void removeCalendarData(CalendarData calendarData) + throws IllegalArgumentException { + CalendarData lastCalendarData = getLastCalendarData(); + if (calendarData.equals(lastCalendarData)) { + LocalDate validFrom = getValidFrom(calendarData); + if (validFrom == null) { + throw new IllegalArgumentException( + "You can not remove the current calendar data"); + } + if (validFrom.compareTo(new LocalDate()) > 0) { + calendarDataVersions.remove(lastCalendarData); + getLastCalendarData().removeExpiringDate(); + } else { + throw new IllegalArgumentException( + "You can not modify the past removing a calendar data"); + } + } else { + throw new IllegalArgumentException( + "You just can remove the last calendar data"); + } + } + + public LocalDate getValidFrom(CalendarData calendarData) { + Integer index = calendarDataVersions.indexOf(calendarData); + if (index > 0) { + return calendarDataVersions.get(index - 1).getExpiringDate(); + } + 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 217c47c72..255e36be8 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 @@ -128,4 +128,8 @@ public class CalendarData extends BaseEntity { this.parent = parent; } + public void removeExpiringDate() { + this.expiringDate = null; + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarException.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarException.java index 4046e9d3e..2800cf4e0 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarException.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarException.java @@ -22,6 +22,7 @@ package org.navalplanner.business.calendars.entities; import java.util.Date; +import org.hibernate.validator.NotNull; import org.joda.time.LocalDate; import org.navalplanner.business.common.BaseEntity; @@ -35,14 +36,18 @@ import org.navalplanner.business.common.BaseEntity; */ public class CalendarException extends BaseEntity { - public static CalendarException create(Date date, Integer hours) { - CalendarException exceptionDay = new CalendarException(new LocalDate(date), hours); + public static CalendarException create(Date date, Integer hours, + CalendarExceptionType type) { + CalendarException exceptionDay = new CalendarException(new LocalDate( + date), hours, type); exceptionDay.setNewObject(true); return exceptionDay; } - public static CalendarException create(LocalDate date, Integer hours) { - CalendarException exceptionDay = new CalendarException(date, hours); + public static CalendarException create(LocalDate date, Integer hours, + CalendarExceptionType type) { + CalendarException exceptionDay = new CalendarException(date, hours, + type); exceptionDay.setNewObject(true); return exceptionDay; } @@ -51,6 +56,7 @@ public class CalendarException extends BaseEntity { private Integer hours; + @NotNull private CalendarExceptionType type; /** @@ -60,9 +66,11 @@ public class CalendarException extends BaseEntity { } - private CalendarException(LocalDate date, Integer hours) { + private CalendarException(LocalDate date, Integer hours, + CalendarExceptionType type) { this.date = date; this.hours = hours; + this.type = type; } public LocalDate getDate() { diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/daos/BaseCalendarDAOTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/daos/BaseCalendarDAOTest.java index 3fda03d9c..f97d687b3 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/daos/BaseCalendarDAOTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/daos/BaseCalendarDAOTest.java @@ -30,13 +30,20 @@ import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING import java.util.List; +import javax.annotation.Resource; + import org.hibernate.SessionFactory; import org.joda.time.LocalDate; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.navalplanner.business.IDataBootstrap; import org.navalplanner.business.calendars.daos.BaseCalendarDAO; import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; +import org.navalplanner.business.calendars.daos.ICalendarExceptionTypeDAO; import org.navalplanner.business.calendars.entities.BaseCalendar; +import org.navalplanner.business.calendars.entities.CalendarException; +import org.navalplanner.business.calendars.entities.CalendarExceptionType; import org.navalplanner.business.calendars.entities.ResourceCalendar; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.ValidationException; @@ -61,9 +68,20 @@ public class BaseCalendarDAOTest { @Autowired private IBaseCalendarDAO baseCalendarDAO; + @Autowired + private ICalendarExceptionTypeDAO calendarExceptionTypeDAO; + @Autowired private SessionFactory session; + @Resource + private IDataBootstrap calendarBootstrap; + + @Before + public void loadRequiredData() { + calendarBootstrap.loadRequiredData(); + } + @Test public void saveBasicCalendar() { BaseCalendar calendar = BaseCalendarTest.createBasicCalendar(); @@ -74,7 +92,7 @@ public class BaseCalendarDAOTest { @Test public void saveBasicCalendarWithExceptionDay() { BaseCalendar calendar = BaseCalendarTest.createBasicCalendar(); - BaseCalendarTest.addChristmasAsExceptionDay(calendar); + addChristmasAsExceptionDay(calendar); baseCalendarDAO.save(calendar); assertTrue(baseCalendarDAO.exists(calendar.getId())); @@ -87,6 +105,14 @@ public class BaseCalendarDAOTest { } } + private void addChristmasAsExceptionDay(BaseCalendar calendar) { + CalendarExceptionType type = calendarExceptionTypeDAO.list( + CalendarExceptionType.class).get(0); + CalendarException christmasDay = CalendarException.create( + BaseCalendarTest.CHRISTMAS_DAY_LOCAL_DATE, 0, type); + calendar.addExceptionDay(christmasDay); + } + @Test public void saveDerivedCalendar() { BaseCalendar calendar = BaseCalendarTest.createBasicCalendar(); diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java index f75618e93..891ddb06f 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/BaseCalendarTest.java @@ -34,6 +34,7 @@ import org.joda.time.LocalDate; import org.junit.Test; import org.navalplanner.business.calendars.entities.BaseCalendar; import org.navalplanner.business.calendars.entities.CalendarException; +import org.navalplanner.business.calendars.entities.CalendarExceptionType; import org.navalplanner.business.calendars.entities.BaseCalendar.DayType; import org.navalplanner.business.calendars.entities.CalendarData.Days; @@ -92,9 +93,15 @@ public class BaseCalendarTest { calendarFixture = BaseCalendar.create(); } + public static CalendarExceptionType createCalendarExceptionType() { + CalendarExceptionType result = CalendarExceptionType.create("TEST", + "black", true); + return result; + } + public static void addChristmasAsExceptionDay(BaseCalendar calendar) { CalendarException christmasDay = CalendarException.create( - CHRISTMAS_DAY_LOCAL_DATE, 0); + CHRISTMAS_DAY_LOCAL_DATE, 0, createCalendarExceptionType()); calendar.addExceptionDay(christmasDay); } @@ -155,7 +162,8 @@ public class BaseCalendarTest { public void testGetWorkableHoursDerivedBasicCalendarWithException() { BaseCalendar calendar = createBasicCalendar().newDerivedCalendar(); - CalendarException day = CalendarException.create(WEDNESDAY_LOCAL_DATE, 4); + CalendarException day = CalendarException.create(WEDNESDAY_LOCAL_DATE, + 4, createCalendarExceptionType()); calendar.addExceptionDay(day); int mondayHours = calendar.getWorkableHours(MONDAY_LOCAL_DATE); @@ -172,7 +180,8 @@ public class BaseCalendarTest { public void testGetWorkableHoursDerivedChristmasCalendarRedefiningExceptionDay() { BaseCalendar calendar = createChristmasCalendar().newDerivedCalendar(); - CalendarException day = CalendarException.create(CHRISTMAS_DAY_LOCAL_DATE, 4); + CalendarException day = CalendarException.create( + CHRISTMAS_DAY_LOCAL_DATE, 4, createCalendarExceptionType()); calendar.addExceptionDay(day); int hours = calendar.getWorkableHours(CHRISTMAS_DAY_LOCAL_DATE); @@ -200,10 +209,12 @@ public class BaseCalendarTest { public void testAddTwoExceptionDaysInTheSameDate() { BaseCalendar calendar = createBasicCalendar(); - CalendarException day = CalendarException.create(MONDAY_LOCAL_DATE, 8); + CalendarException day = CalendarException.create(MONDAY_LOCAL_DATE, 8, + createCalendarExceptionType()); calendar.addExceptionDay(day); - CalendarException day2 = CalendarException.create(MONDAY_LOCAL_DATE, 4); + CalendarException day2 = CalendarException.create(MONDAY_LOCAL_DATE, 4, + createCalendarExceptionType()); calendar.addExceptionDay(day2); } @@ -312,13 +323,15 @@ public class BaseCalendarTest { public void testGettWorkableHoursNewVersionFromChristmasCalendar() { BaseCalendar calendar = createChristmasCalendar(); CalendarException day = CalendarException.create(CHRISTMAS_DAY_LOCAL_DATE - .plusYears(1), 0); + .plusYears(1), 0, + createCalendarExceptionType()); calendar.addExceptionDay(day); calendar.newVersion(CHRISTMAS_DAY_LOCAL_DATE.plusDays(1)); calendar - .updateExceptionDay(CHRISTMAS_DAY_LOCAL_DATE.plusYears(1), 8); + .updateExceptionDay(CHRISTMAS_DAY_LOCAL_DATE.plusYears(1), 8, + createCalendarExceptionType()); assertThat(calendar .getWorkableHours(CHRISTMAS_DAY_LOCAL_DATE.plusYears(1)), equalTo(8)); @@ -384,7 +397,8 @@ public class BaseCalendarTest { calendar.newVersion(CHRISTMAS_DAY_LOCAL_DATE .plusDays(1)); - CalendarException day = CalendarException.create(CHRISTMAS_DAY_LOCAL_DATE, 0); + CalendarException day = CalendarException.create( + CHRISTMAS_DAY_LOCAL_DATE, 0, createCalendarExceptionType()); calendar.addExceptionDay(day); assertThat(calendar.getExceptions().size(), equalTo(1)); @@ -549,8 +563,10 @@ public class BaseCalendarTest { BaseCalendar calendar = createBasicCalendar(); calendar.newVersion(WEDNESDAY_LOCAL_DATE); - calendar.addExceptionDay(CalendarException.create(MONDAY_LOCAL_DATE, 0)); - calendar.addExceptionDay(CalendarException.create(FRIDAY_LOCAL_DATE, 0)); + calendar.addExceptionDay(CalendarException.create(MONDAY_LOCAL_DATE, 0, + createCalendarExceptionType())); + calendar.addExceptionDay(CalendarException.create(FRIDAY_LOCAL_DATE, 0, + createCalendarExceptionType())); assertThat(calendar.getWorkableHours(MONDAY_LOCAL_DATE), equalTo(0)); @@ -566,7 +582,8 @@ public class BaseCalendarTest { BaseCalendar calendar = createBasicCalendar(); LocalDate pastMonth = (new LocalDate()).minusMonths(1); - CalendarException exceptionDay = CalendarException.create(pastMonth, 0); + CalendarException exceptionDay = CalendarException.create(pastMonth, 0, + createCalendarExceptionType()); calendar.addExceptionDay(exceptionDay); } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/CalendarExceptionTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/CalendarExceptionTest.java index 257badd87..4cb2e5235 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/CalendarExceptionTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/CalendarExceptionTest.java @@ -28,6 +28,7 @@ import java.util.Date; import org.joda.time.LocalDate; import org.junit.Test; import org.navalplanner.business.calendars.entities.CalendarException; +import org.navalplanner.business.calendars.entities.CalendarExceptionType; /** * Tests for {@link CalendarException}. @@ -39,11 +40,14 @@ public class CalendarExceptionTest { @Test public void testCreateExceptionDayWithDate() { Date date = new Date(); + CalendarExceptionType type = BaseCalendarTest + .createCalendarExceptionType(); - CalendarException day = CalendarException.create(date, 8); + CalendarException day = CalendarException.create(date, 8, type); assertThat(day.getDate(), equalTo(new LocalDate(date))); assertThat(day.getHours(), equalTo(8)); + assertThat(day.getType(), equalTo(type)); } } 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 794471472..e85219d26 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 @@ -24,6 +24,8 @@ import static org.navalplanner.web.I18nHelper._; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -33,10 +35,10 @@ import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.navalplanner.business.calendars.entities.BaseCalendar; import org.navalplanner.business.calendars.entities.CalendarData; +import org.navalplanner.business.calendars.entities.CalendarException; +import org.navalplanner.business.calendars.entities.CalendarExceptionType; import org.navalplanner.business.calendars.entities.BaseCalendar.DayType; import org.navalplanner.business.calendars.entities.CalendarData.Days; -import org.navalplanner.web.common.IMessagesForUser; -import org.navalplanner.web.common.MessagesForUser; import org.navalplanner.web.common.Util; import org.navalplanner.web.common.components.CalendarHighlightedDays; import org.zkoss.zk.ui.Component; @@ -55,7 +57,6 @@ import org.zkoss.zul.Label; import org.zkoss.zul.Listcell; import org.zkoss.zul.Listitem; import org.zkoss.zul.ListitemRenderer; -import org.zkoss.zul.Tab; import org.zkoss.zul.api.Datebox; import org.zkoss.zul.api.Window; @@ -79,9 +80,7 @@ public abstract class BaseCalendarEditionController extends private HistoryVersionsRenderer historyVersionsRenderer = new HistoryVersionsRenderer(); - private IMessagesForUser messagesForUser; - - private Component messagesContainer; + private CalendarExceptionRenderer calendarExceptionRenderer = new CalendarExceptionRenderer(); private boolean creatingNewVersion = false; @@ -101,10 +100,40 @@ public abstract class BaseCalendarEditionController extends @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); - messagesForUser = new MessagesForUser(messagesContainer); if (baseCalendarModel.isDerived()) { prepareParentCombo(); } + prepareExceptionTypeCombo(); + } + + private void prepareExceptionTypeCombo() { + Combobox exceptionTypes = (Combobox) window + .getFellow("exceptionTypes"); + fillExceptionTypesComboAndMakrSelectedItem(exceptionTypes); + } + + private void fillExceptionTypesComboAndMakrSelectedItem( + Combobox exceptionTypes) { + exceptionTypes.getChildren().clear(); + CalendarExceptionType type = baseCalendarModel + .getCalendarExceptionType(); + + Comboitem defaultItem = new Comboitem("NO_EXCEPTION"); + exceptionTypes.appendChild(defaultItem); + if (type == null) { + exceptionTypes.setSelectedItem(defaultItem); + } + + for (CalendarExceptionType calendarExceptionType : baseCalendarModel + .getCalendarExceptionTypes()) { + Comboitem item = new Comboitem(calendarExceptionType.getName()); + item.setValue(calendarExceptionType); + exceptionTypes.appendChild(item); + if ((type != null) + && (type.getName().equals(calendarExceptionType.getName()))) { + exceptionTypes.setSelectedItem(item); + } + } } private void prepareParentCombo() { @@ -287,9 +316,58 @@ public abstract class BaseCalendarEditionController extends private void reloadDayInformation() { Util.reloadBindings(window.getFellow("dayInformation")); + Util.reloadBindings(window.getFellow("exceptionInformation")); + Util.reloadBindings(window.getFellow("historyInformation")); + reloadTypeDatesAndHours(); + reloadParentCombo(); highlightDaysOnCalendar(); } + private void reloadParentCombo() { + BaseCalendar parent = baseCalendarModel.getParent(); + Combobox parentCalendars = (Combobox) window + .getFellow("parentCalendars"); + 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 reloadTypeDatesAndHours() { + Date selectedDay = baseCalendarModel.getSelectedDay(); + + CalendarExceptionType type = baseCalendarModel + .getCalendarExceptionType(new LocalDate(selectedDay)); + Combobox exceptionTypes = (Combobox) window.getFellow("exceptionTypes"); + List items = exceptionTypes.getItems(); + for (Comboitem item : items) { + CalendarExceptionType value = (CalendarExceptionType) item + .getValue(); + if ((value == null) && (type == null)) { + exceptionTypes.setSelectedItem(item); + break; + } + if ((value != null) && (type != null) + && (value.getName().equals(type.getName()))) { + exceptionTypes.setSelectedItem(item); + break; + } + } + + Datebox dateboxStartDate = (Datebox) window + .getFellow("exceptionStartDate"); + dateboxStartDate.setValue(selectedDay); + Datebox dateboxEndDate = (Datebox) window.getFellow("exceptionEndDate"); + dateboxEndDate.setValue(selectedDay); + + Intbox intboxHours = (Intbox) window.getFellow("exceptionHours"); + intboxHours.setValue(baseCalendarModel.getHoursOfDay()); + } + private void highlightDaysOnCalendar() { ((CalendarHighlightedDays) window.getFellow("calendarWidget")) .highlightDays(); @@ -404,9 +482,51 @@ public abstract class BaseCalendarEditionController extends } public void createException() { - Component exceptionHoursIntbox = window.getFellow("exceptionHours"); + Combobox exceptionTypes = (Combobox) window.getFellow("exceptionTypes"); + CalendarExceptionType type = (CalendarExceptionType) exceptionTypes + .getSelectedItem().getValue(); + if (type == null) { + throw new WrongValueException(exceptionTypes, + _("You should select the type of exception")); + } else { + Clients.closeErrorBox(exceptionTypes); + } - Integer hours = ((Intbox) exceptionHoursIntbox).getValue(); + Datebox dateboxStartDate = (Datebox) window + .getFellow("exceptionStartDate"); + Date startDate = dateboxStartDate.getValue(); + if (startDate == null) { + throw new WrongValueException(dateboxStartDate, + _("You should select a start date for the exception")); + } else { + Clients.closeErrorBox(dateboxStartDate); + } + Datebox dateboxEndDate = (Datebox) window.getFellow("exceptionEndDate"); + Date endDate = dateboxEndDate.getValue(); + if (endDate == null) { + throw new WrongValueException(dateboxEndDate, + _("You should select a end date for the exception")); + } else { + Clients.closeErrorBox(dateboxEndDate); + } + if (startDate.compareTo(new Date()) <= 0) { + throw new WrongValueException( + dateboxStartDate, + _("Exception start date should be greater than current date")); + } else { + Clients.closeErrorBox(dateboxStartDate); + } + if (startDate.compareTo(endDate) > 0) { + throw new WrongValueException( + dateboxEndDate, + _("Exception end date should be greater or equals than start date")); + } else { + Clients.closeErrorBox(dateboxEndDate); + } + + Intbox exceptionHoursIntbox = (Intbox) window + .getFellow("exceptionHours"); + Integer hours = exceptionHoursIntbox.getValue(); if (hours < 0) { throw new WrongValueException( @@ -414,7 +534,7 @@ public abstract class BaseCalendarEditionController extends _("Hours for an exception day should be greater or equal than zero")); } else { Clients.closeErrorBox(exceptionHoursIntbox); - baseCalendarModel.createException(hours); + baseCalendarModel.createException(type, startDate, endDate, hours); reloadDayInformation(); } } @@ -481,6 +601,7 @@ public abstract class BaseCalendarEditionController extends @Override public void render(Listitem item, Object data) throws Exception { CalendarData calendarData = (CalendarData) data; + item.setValue(calendarData); Listcell nameListcell = new Listcell(); nameListcell.appendChild(new Label(baseCalendarModel.getName())); @@ -529,12 +650,70 @@ public abstract class BaseCalendarEditionController extends " - "))); item.appendChild(summaryListcell); - Listcell buttonListcell = new Listcell(); - Button button = new Button(_("Go to this calendar")); - button.addEventListener(Events.ON_CLICK, new EventListener() { + appendOperationsListcell(item, calendarData); + markAsSelected(item, calendarData); + addEventListener(item); + } + private void markAsSelected(Listitem item, + CalendarData calendarData) { + CalendarData selected = baseCalendarModel.getCalendarData(); + if ((selected != null) && (calendarData.equals(selected))) { + item.setSelected(true); + } + } + + private void appendOperationsListcell(Listitem item, + CalendarData calendarData) { + Listcell listcell = new Listcell(); + listcell.appendChild(createRemoveButton(calendarData)); + item.appendChild(listcell); + } + + private Button createRemoveButton( + final CalendarData calendarData) { + Button result = createButton("/common/img/ico_borrar1.png", + _("Delete"), "/common/img/ico_borrar.png", "icono", + new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + baseCalendarModel.removeCalendarData(calendarData); + reloadCurrentWindow(); + } + }); + LocalDate validFrom = baseCalendarModel.getValidFrom(calendarData); + if ((validFrom == null) + || (!baseCalendarModel.getLastCalendarData().equals( + calendarData)) + || (validFrom.compareTo( + new LocalDate()) <= 0)) { + result.setDisabled(true); + } + return result; + } + + private Button createButton(String image, String tooltip, + String hoverImage, String styleClass, + EventListener eventListener) { + Button result = new Button("", image); + result.setHoverImage(hoverImage); + result.setSclass(styleClass); + result.setTooltiptext(tooltip); + result.addEventListener(Events.ON_CLICK, eventListener); + return result; + } + + private void addEventListener(Listitem item) { + item.addEventListener(Events.ON_CLICK, new EventListener() { @Override public void onEvent(Event event) throws Exception { + Listitem item = (Listitem) event.getTarget(); + CalendarData calendarData = (CalendarData) item.getValue(); + + LocalDate dateValidFrom = baseCalendarModel + .getValidFrom(calendarData); + LocalDate expiringDate = calendarData.getExpiringDate(); + if (dateValidFrom != null) { goToDate(dateValidFrom.toDateTimeAtStartOfDay() .toDate()); @@ -546,8 +725,6 @@ public abstract class BaseCalendarEditionController extends } } }); - buttonListcell.appendChild(button); - item.appendChild(buttonListcell); } } @@ -559,7 +736,6 @@ public abstract class BaseCalendarEditionController extends public void goToDate(Date date) { setSelectedDay(date); - ((Tab) window.getFellow("dataTab")).setSelected(true); reloadCurrentWindow(); } @@ -612,4 +788,200 @@ public abstract class BaseCalendarEditionController extends return baseCalendarModel.getPossibleParentCalendars(); } + public List getCalendarExceptions() { + List calendarExceptions = new ArrayList(baseCalendarModel.getCalendarExceptions()); + Collections.sort(calendarExceptions, + new Comparator() { + @Override + public int compare(CalendarException o1, + CalendarException o2) { + return o1.getDate().compareTo(o2.getDate()); + } + }); + return calendarExceptions; + } + + public CalendarExceptionRenderer getCalendarExceptionRenderer() { + return calendarExceptionRenderer; + } + + public class CalendarExceptionRenderer implements ListitemRenderer { + + @Override + public void render(Listitem item, Object data) throws Exception { + CalendarException calendarException = (CalendarException) data; + item.setValue(calendarException); + + appendDayListcell(item, calendarException); + appendExceptionTypeListcell(item, calendarException); + appendHoursListcell(item, calendarException); + appendOperationsListcell(item, calendarException); + + markAsSelected(item, calendarException); + + addEventListener(item); + } + + private void addEventListener(Listitem item) { + item.addEventListener(Events.ON_CLICK, new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + Listitem item = (Listitem) event.getTarget(); + CalendarException calendarException = (CalendarException) item + .getValue(); + setSelectedDay(calendarException + .getDate().toDateTimeAtStartOfDay().toDate()); + reloadDayInformation(); + } + }); + } + + private void markAsSelected(Listitem item, + CalendarException calendarException) { + Date selectedDay = baseCalendarModel.getSelectedDay(); + if (selectedDay != null) { + if (calendarException.getDate().equals( + new LocalDate(selectedDay))) { + item.setSelected(true); + } + } + } + + private void appendDayListcell(Listitem item, + CalendarException calendarException) { + Listcell listcell = new Listcell(); + listcell.appendChild(new Label(calendarException.getDate() + .toString())); + item.appendChild(listcell); + } + + private void appendHoursListcell(Listitem item, + CalendarException calendarException) { + Listcell listcell = new Listcell(); + listcell.appendChild(new Label(calendarException.getHours() + .toString())); + item.appendChild(listcell); + } + + private void appendExceptionTypeListcell(Listitem item, + CalendarException calendarException) { + Listcell listcell = new Listcell(); + String type = ""; + if (calendarException.getType() != null) { + type = calendarException.getType().getName(); + } + listcell.appendChild(new Label(type)); + item.appendChild(listcell); + } + + private void appendOperationsListcell(Listitem item, CalendarException calendarException) { + Listcell listcell = new Listcell(); + listcell.appendChild(createRemoveButton(calendarException)); + item.appendChild(listcell); + } + + private Button createRemoveButton( + final CalendarException calendarException) { + Button result = createButton("/common/img/ico_borrar1.png", + _("Delete"), "/common/img/ico_borrar.png", "icono", + new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + baseCalendarModel + .removeException(calendarException + .getDate()); + reloadDayInformation(); + } + }); + if (isSelectedDateFromPast()) { + result.setDisabled(true); + } + return result; + } + + private Button createButton(String image, String tooltip, + String hoverImage, String styleClass, + EventListener eventListener) { + Button result = new Button("", image); + result.setHoverImage(hoverImage); + result.setSclass(styleClass); + result.setTooltiptext(tooltip); + result.addEventListener(Events.ON_CLICK, eventListener); + return result; + } + + } + + public boolean isOwnExceptionDay() { + DayType typeOfDay = baseCalendarModel.getTypeOfDay(); + if ((typeOfDay != null) && (typeOfDay.equals(DayType.OWN_EXCEPTION))) { + return true; + } + return false; + } + + public boolean isNotOwnExceptionDay() { + return !isOwnExceptionDay(); + } + + public void updateException() { + Combobox exceptionTypes = (Combobox) window.getFellow("exceptionTypes"); + CalendarExceptionType type = (CalendarExceptionType) exceptionTypes + .getSelectedItem().getValue(); + + Datebox dateboxStartDate = (Datebox) window + .getFellow("exceptionStartDate"); + Date startDate = dateboxStartDate.getValue(); + if (startDate == null) { + throw new WrongValueException(dateboxStartDate, + _("You should select a start date for the exception")); + } else { + Clients.closeErrorBox(dateboxStartDate); + } + Datebox dateboxEndDate = (Datebox) window.getFellow("exceptionEndDate"); + Date endDate = dateboxEndDate.getValue(); + if (endDate == null) { + throw new WrongValueException(dateboxEndDate, + _("You should select a end date for the exception")); + } else { + Clients.closeErrorBox(dateboxEndDate); + } + if (startDate.compareTo(new Date()) <= 0) { + throw new WrongValueException( + dateboxStartDate, + _("Exception start date should be greater than current date")); + } else { + Clients.closeErrorBox(dateboxStartDate); + } + if (startDate.compareTo(endDate) > 0) { + throw new WrongValueException( + dateboxEndDate, + _("Exception end date should be greater or equals than start date")); + } else { + Clients.closeErrorBox(dateboxEndDate); + } + + Intbox exceptionHoursIntbox = (Intbox) window + .getFellow("exceptionHours"); + Integer hours = exceptionHoursIntbox.getValue(); + + if (hours < 0) { + throw new WrongValueException( + exceptionHoursIntbox, + _("Hours for an exception day should be greater or equal than zero")); + } else { + Clients.closeErrorBox(exceptionHoursIntbox); + baseCalendarModel.updateException(type, startDate, endDate, hours); + reloadDayInformation(); + } + } + + public String getNameParentCalendar() { + BaseCalendar parent = baseCalendarModel.getParent(); + if (parent != null) { + return parent.getName(); + } + return ""; + } + } 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 a0c12c8af..75ec1a84a 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 @@ -24,14 +24,17 @@ import static org.navalplanner.web.I18nHelper._; import java.util.Date; import java.util.List; +import java.util.Set; import org.apache.commons.lang.Validate; import org.hibernate.validator.InvalidValue; import org.joda.time.LocalDate; import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; +import org.navalplanner.business.calendars.daos.ICalendarExceptionTypeDAO; import org.navalplanner.business.calendars.entities.BaseCalendar; import org.navalplanner.business.calendars.entities.CalendarData; import org.navalplanner.business.calendars.entities.CalendarException; +import org.navalplanner.business.calendars.entities.CalendarExceptionType; import org.navalplanner.business.calendars.entities.BaseCalendar.DayType; import org.navalplanner.business.calendars.entities.CalendarData.Days; import org.navalplanner.business.common.daos.IConfigurationDAO; @@ -71,6 +74,9 @@ public class BaseCalendarModel implements IBaseCalendarModel { @Autowired private IConfigurationDAO configurationDAO; + @Autowired + private ICalendarExceptionTypeDAO calendarExceptionTypeDAO; + /* * Non conversational steps @@ -139,6 +145,13 @@ public class BaseCalendarModel implements IBaseCalendarModel { } } baseCalendar.getExceptions().size(); + forceLoadExceptionTypes(); + } + + private void forceLoadExceptionTypes() { + for (CalendarExceptionType calendarExceptionType : getCalendarExceptionTypes()) { + calendarExceptionType.getName(); + } } @Transactional(readOnly = true) @@ -224,12 +237,18 @@ public class BaseCalendarModel implements IBaseCalendarModel { } @Override - public void createException(Integer hours) { - if (getTypeOfDay().equals(DayType.OWN_EXCEPTION)) { - getBaseCalendar().updateExceptionDay(selectedDate, hours); - } else { - CalendarException day = CalendarException.create(selectedDate, hours); - getBaseCalendar().addExceptionDay(day); + public void createException(CalendarExceptionType type, Date startDate, + Date endDate, Integer hours) { + for (LocalDate date = new LocalDate(startDate); date + .compareTo(new LocalDate(endDate)) <= 0; date = date + .plusDays(1)) { + if (getTypeOfDay(date).equals(DayType.OWN_EXCEPTION)) { + getBaseCalendar().updateExceptionDay(date, hours, type); + } else { + CalendarException day = CalendarException.create(date, hours, + type); + getBaseCalendar().addExceptionDay(day); + } } } @@ -406,12 +425,7 @@ public class BaseCalendarModel implements IBaseCalendarModel { @Override public LocalDate getValidFrom(CalendarData calendarData) { if (getBaseCalendar() != null) { - List calendarDataVersions = getBaseCalendar() - .getCalendarDataVersions(); - Integer index = calendarDataVersions.indexOf(calendarData); - if (index > 0) { - return calendarDataVersions.get(index - 1).getExpiringDate(); - } + return getBaseCalendar().getValidFrom(calendarData); } return null; @@ -478,4 +492,92 @@ public class BaseCalendarModel implements IBaseCalendarModel { .getId()); } + @Override + @Transactional(readOnly = true) + public List getCalendarExceptionTypes() { + return calendarExceptionTypeDAO.list(CalendarExceptionType.class); + } + + @Override + public Set getCalendarExceptions() { + if (getBaseCalendar() == null) { + return null; + } + return getBaseCalendar().getExceptions(); + } + + @Override + public void removeException(LocalDate date) { + if (getBaseCalendar() != null) { + getBaseCalendar().removeExceptionDay(date); + } + } + + @Override + public CalendarExceptionType getCalendarExceptionType() { + if (getBaseCalendar() == null) { + return null; + } + + return getBaseCalendar().getExceptionType(selectedDate); + } + + @Override + public CalendarExceptionType getCalendarExceptionType(LocalDate date) { + if (getBaseCalendar() == null) { + return null; + } + + return getBaseCalendar().getExceptionType(date); + } + + @Override + public void updateException(CalendarExceptionType type, Date startDate, + Date endDate, Integer hours) { + for (LocalDate date = new LocalDate(startDate); date + .compareTo(new LocalDate(endDate)) <= 0; date = date + .plusDays(1)) { + if (getTypeOfDay(date).equals(DayType.OWN_EXCEPTION)) { + if (type == null) { + getBaseCalendar().removeExceptionDay(date); + } else { + getBaseCalendar().updateExceptionDay(date, hours, type); + } + } else { + if (type != null) { + CalendarException day = CalendarException.create(date, + hours, type); + getBaseCalendar().addExceptionDay(day); + } + } + } + } + + @Override + public void removeCalendarData(CalendarData calendarData) { + if (getBaseCalendar() != null) { + getBaseCalendar().removeCalendarData(calendarData); + } + } + + @Override + public CalendarData getLastCalendarData() { + if (getBaseCalendar() == null) { + return null; + } + return getBaseCalendar().getLastCalendarData(); + } + + @Override + public CalendarData getCalendarData() { + if (getBaseCalendar() == null) { + return null; + } + Date selectedDay = getSelectedDay(); + if (selectedDay == null) { + return null; + } + return getBaseCalendar().getCalendarData(new LocalDate(selectedDay)); + } + } 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 881d78f7e..5d73ddf7c 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 @@ -22,10 +22,13 @@ package org.navalplanner.web.calendars; import java.util.Date; import java.util.List; +import java.util.Set; import org.joda.time.LocalDate; import org.navalplanner.business.calendars.entities.BaseCalendar; import org.navalplanner.business.calendars.entities.CalendarData; +import org.navalplanner.business.calendars.entities.CalendarException; +import org.navalplanner.business.calendars.entities.CalendarExceptionType; import org.navalplanner.business.calendars.entities.BaseCalendar.DayType; import org.navalplanner.business.calendars.entities.CalendarData.Days; import org.navalplanner.business.common.exceptions.ValidationException; @@ -71,6 +74,8 @@ public interface IBaseCalendarModel { boolean isDefaultCalendar(BaseCalendar baseCalendar); + List getCalendarExceptionTypes(); + /* * Initial conversation steps */ @@ -103,7 +108,8 @@ public interface IBaseCalendarModel { Integer getHoursOfDay(); - void createException(Integer hours); + void createException(CalendarExceptionType type, Date startDate, + Date endDate, Integer hours); Integer getHours(Days day); @@ -147,6 +153,23 @@ public interface IBaseCalendarModel { LocalDate getValidFrom(CalendarData calendarData); + Set getCalendarExceptions(); + + void removeException(LocalDate date); + + CalendarExceptionType getCalendarExceptionType(); + + CalendarExceptionType getCalendarExceptionType(LocalDate date); + + void updateException(CalendarExceptionType type, Date startDate, + Date endDate, Integer hours); + + void removeCalendarData(CalendarData calendarData); + + CalendarData getLastCalendarData(); + + CalendarData getCalendarData(); + /* * Final conversation steps */ diff --git a/navalplanner-webapp/src/main/webapp/calendars/_edition.zul b/navalplanner-webapp/src/main/webapp/calendars/_edition.zul index a51db97bf..13fee8f01 100644 --- a/navalplanner-webapp/src/main/webapp/calendars/_edition.zul +++ b/navalplanner-webapp/src/main/webapp/calendars/_edition.zul @@ -20,124 +20,192 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -