From e1f863e2829917f3fd94548829934873c5464666 Mon Sep 17 00:00:00 2001 From: Manuel Rego Casasnovas Date: Wed, 19 Aug 2009 09:12:44 +0200 Subject: [PATCH] ItEr22S08CUAltaCalendarioLaboralItEr21S10: Support for creation of basic calendars. --- .../calendars/entities/BaseCalendar.java | 28 +--- .../calendars/entities/Calendars.hbm.xml | 6 +- .../calendars/daos/BaseCalendarDAOTest.java | 31 ++++ .../calendars/entities/BaseCalendarTest.java | 12 +- .../calendars/BaseCalendarCRUDController.java | 143 +++++++++++++++++- .../web/calendars/BaseCalendarModel.java | 104 +++++++++++++ .../web/calendars/IBaseCalendarModel.java | 24 +++ .../src/main/webapp/calendars/_edition.zul | 98 +++++++++--- .../src/main/webapp/calendars/calendars.zul | 4 +- .../web/calendars/BaseCalendarModelTest.java | 105 +++++++++++++ 10 files changed, 489 insertions(+), 66 deletions(-) create mode 100644 navalplanner-webapp/src/test/java/org/navalplanner/web/calendars/BaseCalendarModelTest.java 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 f303cbb5d..474910016 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 @@ -7,7 +7,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.joda.time.DateTime; import org.joda.time.DateTimeConstants; import org.joda.time.LocalDate; import org.navalplanner.business.common.BaseEntity; @@ -78,6 +77,10 @@ public class BaseCalendar extends BaseEntity implements IValidable { return name; } + public Map getHoursPerDay() { + return hoursPerDay; + } + public Integer getHours(Days day) { if ((getHoursForDay(day) == null) && (parent != null)) { return parent.getHours(day); @@ -338,11 +341,7 @@ public class BaseCalendar extends BaseEntity implements IValidable { * calendar restrictions. */ public Integer getWorkableHoursPerWeek(Date date) { - DateTime week = new DateTime(date); - DateTime init = week.dayOfWeek().withMinimumValue(); - DateTime end = week.dayOfWeek().withMaximumValue(); - - return getWorkableHours(init.toDate(), end.toDate()); + return getWorkableHoursPerWeek(new LocalDate(date)); } /** @@ -358,14 +357,6 @@ public class BaseCalendar extends BaseEntity implements IValidable { @Override public void checkValid() throws ValidationException { - if (parent == null) { - if (isNullSomeDay()) { - throw new ValidationException( - "Daily hours could not have the default value " - + "if the calendar is not derivated"); - } - } - if ((nextCalendar == null) && (expiringDate != null)) { throw new ValidationException("A next calendar should exist " + "if current calendar has a expiring date fixed"); @@ -376,15 +367,6 @@ public class BaseCalendar extends BaseEntity implements IValidable { } } - private boolean isNullSomeDay() { - for (Integer hours : hoursPerDay.values()) { - if (hours == null) { - return true; - } - } - return false; - } - /** * Creates a new {@link BaseCalendar} derived from the current calendar. The * new calendar will be the child of the current calendar. diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/calendars/entities/Calendars.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/calendars/entities/Calendars.hbm.xml index 4f948b0a1..5aa3074f5 100644 --- a/navalplanner-business/src/main/resources/org/navalplanner/business/calendars/entities/Calendars.hbm.xml +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/calendars/entities/Calendars.hbm.xml @@ -20,11 +20,11 @@ - + - + - + 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 d556d89bf..3d37b69ca 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 @@ -1,6 +1,8 @@ package org.navalplanner.business.test.calendars.daos; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -80,4 +82,33 @@ public class BaseCalendarDAOTest { } + @Test + public void saveNextCalendar() { + BaseCalendar calendar = BaseCalendarTest.createBasicCalendar(); + baseCalendarDAO.save(calendar); + + BaseCalendar nextCalendar = calendar.newVersion(); + baseCalendarDAO.save(nextCalendar); + + try { + + BaseCalendar savedCalendar = baseCalendarDAO.find(calendar.getId()); + assertThat(savedCalendar.getPreviousCalendar(), nullValue()); + assertThat(savedCalendar.getNextCalendar(), notNullValue()); + assertThat(savedCalendar.getNextCalendar(), equalTo(nextCalendar)); + + BaseCalendar savedNextCalendar = baseCalendarDAO + .find(nextCalendar + .getId()); + assertThat(savedNextCalendar.getPreviousCalendar(), notNullValue()); + assertThat(savedNextCalendar.getNextCalendar(), nullValue()); + assertThat(savedNextCalendar.getPreviousCalendar(), + equalTo(calendar)); + + } catch (InstanceNotFoundException e) { + fail("It should not throw an exception"); + } + + } + } 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 c0877ddc6..3baf6afc2 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 @@ -87,12 +87,6 @@ public class BaseCalendarTest { } } - @Test(expected = ValidationException.class) - public void testInvalidCalendar() throws ValidationException { - BaseCalendar calendar = new BaseCalendar(); - calendar.checkValid(); - } - @Test public void testGetWorkableHoursBasic() { BaseCalendar calendar = createBasicCalendar(); @@ -435,16 +429,14 @@ public class BaseCalendarTest { assertTrue(calendarFixture.isDefault(Days.SUNDAY)); } - @Test(expected = ValidationException.class) - public void testDefaultValues() throws ValidationException { + @Test + public void testDefaultValues() { BaseCalendar calendar = createBasicCalendar(); assertFalse(calendar.isDefault(Days.MONDAY)); calendar.setDefault(Days.MONDAY); assertTrue(calendar.isDefault(Days.MONDAY)); - - calendar.checkValid(); } @Test 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 57bf18e8e..5b835a160 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 @@ -1,8 +1,12 @@ package org.navalplanner.web.calendars; +import java.util.Arrays; +import java.util.Date; import java.util.List; import org.navalplanner.business.calendars.entities.BaseCalendar; +import org.navalplanner.business.calendars.entities.BaseCalendar.DayType; +import org.navalplanner.business.calendars.entities.BaseCalendar.Days; import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.web.common.IMessagesForUser; import org.navalplanner.web.common.Level; @@ -10,7 +14,16 @@ import org.navalplanner.web.common.MessagesForUser; import org.navalplanner.web.common.OnlyOneVisible; import org.navalplanner.web.common.Util; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Checkbox; +import org.zkoss.zul.Intbox; +import org.zkoss.zul.Label; +import org.zkoss.zul.Listcell; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.ListitemRenderer; import org.zkoss.zul.api.Window; /** @@ -38,6 +51,8 @@ public class BaseCalendarCRUDController extends GenericForwardComposer { private Component messagesContainer; + private HoursPerDayRenderer hoursPerDayRenderer = new HoursPerDayRenderer(); + public List getBaseCalendars() { return baseCalendarModel.getBaseCalendars(); } @@ -66,6 +81,7 @@ public class BaseCalendarCRUDController extends GenericForwardComposer { public void goToEditForm(BaseCalendar baseCalendar) { baseCalendarModel.initEdit(baseCalendar); + selectDay(new Date()); getVisibility().showOnly(editWindow); Util.reloadBindings(editWindow); } @@ -119,13 +135,9 @@ public class BaseCalendarCRUDController extends GenericForwardComposer { messagesForUser.showMessage(Level.INFO, "removed " + name); } - public void goToEditForm() { - getVisibility().showOnly(editWindow); - Util.reloadBindings(editWindow); - } - public void goToCreateForm() { baseCalendarModel.initCreate(); + selectDay(new Date()); getVisibility().showOnly(createWindow); Util.reloadBindings(createWindow); } @@ -138,4 +150,125 @@ public class BaseCalendarCRUDController extends GenericForwardComposer { return visibility; } + public void selectDay(Date date) { + baseCalendarModel.selectDay(date); + + reloadCurrentWindow(); + } + + public String getTypeOfDay() { + DayType typeOfDay = baseCalendarModel.getTypeOfDay(); + if (typeOfDay == null) { + return ""; + } + + switch (typeOfDay) { + case ANCESTOR_EXCEPTION: + return "Derived excpetion"; + case OWN_EXCEPTION: + return "Exception"; + case ZERO_HOURS: + return "Not working day"; + case NORMAL: + default: + return "Normal"; + } + } + + public Integer getHoursOfDay() { + return baseCalendarModel.getHoursOfDay(); + } + + public void createException(Integer hours) { + // TODO check hours parameter is >= 0 + baseCalendarModel.createException(hours); + + reloadCurrentWindow(); + } + + public List getHoursPerDay() { + return Arrays.asList(Days.values()); + } + + public boolean isNotExceptional() { + return !baseCalendarModel.isExceptional(); + } + + public void removeException() { + baseCalendarModel.removeException(); + + reloadCurrentWindow(); + } + + public HoursPerDayRenderer getHoursPerDayRenderer() { + return hoursPerDayRenderer; + } + + public class HoursPerDayRenderer implements ListitemRenderer { + + @Override + public void render(Listitem item, Object data) throws Exception { + final Days day = (Days) data; + + Listcell labelListcell = new Listcell(); + labelListcell.appendChild(new Label(day.toString())); + item.appendChild(labelListcell); + + Listcell hoursListcell = new Listcell(); + Intbox hoursIntbox = Util.bind(new Intbox(), + new Util.Getter() { + + @Override + public Integer get() { + return baseCalendarModel.getHours(day); + } + }, new Util.Setter() { + + @Override + public void set(Integer value) { + baseCalendarModel.setHours(day, + value); + } + }); + hoursIntbox.addEventListener(Events.ON_CHANGE, new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + reloadCurrentWindow(); + } + + }); + hoursListcell.appendChild(hoursIntbox); + item.appendChild(hoursListcell); + + if (baseCalendarModel.isDerived()) { + Listcell defaultListcell = new Listcell(); + defaultListcell.appendChild(Util.bind(new Checkbox(), + new Util.Getter() { + + @Override + public Boolean get() { + return baseCalendarModel.isDefault(day); + } + }, new Util.Setter() { + + @Override + public void set(Boolean value) { + baseCalendarModel.setDefault(day); + } + })); + item.appendChild(defaultListcell); + } + } + + } + + private void reloadCurrentWindow() { + if (baseCalendarModel.isEditing()) { + Util.reloadBindings(editWindow); + } else { + Util.reloadBindings(createWindow); + } + } + } 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 8f313c880..7698aa5bf 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 @@ -1,5 +1,6 @@ package org.navalplanner.web.calendars; +import java.util.Date; import java.util.List; import org.apache.commons.lang.Validate; @@ -7,6 +8,9 @@ import org.hibernate.validator.ClassValidator; import org.hibernate.validator.InvalidValue; import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; import org.navalplanner.business.calendars.entities.BaseCalendar; +import org.navalplanner.business.calendars.entities.ExceptionDay; +import org.navalplanner.business.calendars.entities.BaseCalendar.DayType; +import org.navalplanner.business.calendars.entities.BaseCalendar.Days; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.ValidationException; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +34,8 @@ public class BaseCalendarModel implements IBaseCalendarModel { */ private BaseCalendar baseCalendar; + private Date selectedDate; + private boolean editing = false; private ClassValidator baseCalendarValidator = new ClassValidator( @@ -67,6 +73,12 @@ public class BaseCalendarModel implements IBaseCalendarModel { Validate.notNull(baseCalendar); this.baseCalendar = getFromDB(baseCalendar); + forceLoadExceptionDays(); + } + + private void forceLoadExceptionDays() { + baseCalendar.getHoursPerDay().size(); + baseCalendar.getExceptions().size(); } private BaseCalendar getFromDB(BaseCalendar baseCalendar) { @@ -102,6 +114,97 @@ public class BaseCalendarModel implements IBaseCalendarModel { return this.editing; } + @Override + public void selectDay(Date date) { + this.selectedDate = date; + } + + @Override + @Transactional(readOnly = true) + public Integer getHoursOfDay() { + if (baseCalendar == null) { + return null; + } + + return baseCalendar.getWorkableHours(selectedDate); + } + + @Override + @Transactional(readOnly = true) + public DayType getTypeOfDay() { + if (baseCalendar == null) { + return null; + } + + return baseCalendar.getType(selectedDate); + } + + @Override + @Transactional(readOnly = true) + public void createException(Integer hours) { + if (getTypeOfDay().equals(DayType.OWN_EXCEPTION)) { + baseCalendar.updateExceptionDay(selectedDate, hours); + } else { + ExceptionDay day = ExceptionDay.create(selectedDate, hours); + baseCalendar.addExceptionDay(day); + } + } + + @Override + public Integer getHours(Days day) { + if (baseCalendar == null) { + return null; + } + + return baseCalendar.getHours(day); + } + + @Override + public Boolean isDefault(Days day) { + if (baseCalendar == null) { + return false; + } + + return baseCalendar.isDefault(day); + } + + @Override + public void setDefault(Days day) { + if (baseCalendar != null) { + baseCalendar.setDefault(day); + } + } + + @Override + public void setHours(Days day, Integer hours) { + if (baseCalendar != null) { + baseCalendar.setHours(day, hours); + } + } + + @Override + public boolean isExceptional() { + if (baseCalendar == null) { + return false; + } + + ExceptionDay day = baseCalendar.getOwnExceptionDay(selectedDate); + return (day != null); + } + + @Override + public void removeException() { + baseCalendar.removeExceptionDay(selectedDate); + } + + @Override + public boolean isDerived() { + if (baseCalendar == null) { + return false; + } + + return baseCalendar.isDerived(); + } /* * Final conversation steps @@ -116,6 +219,7 @@ public class BaseCalendarModel implements IBaseCalendarModel { throw new ValidationException(invalidValues); } + baseCalendar.checkValid(); baseCalendarDAO.save(baseCalendar); } 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 607e2d796..5c85896dc 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 @@ -1,8 +1,11 @@ package org.navalplanner.web.calendars; +import java.util.Date; import java.util.List; import org.navalplanner.business.calendars.entities.BaseCalendar; +import org.navalplanner.business.calendars.entities.BaseCalendar.DayType; +import org.navalplanner.business.calendars.entities.BaseCalendar.Days; import org.navalplanner.business.common.exceptions.ValidationException; /** @@ -61,6 +64,27 @@ public interface IBaseCalendarModel { boolean isEditing(); + void selectDay(Date date); + + DayType getTypeOfDay(); + + Integer getHoursOfDay(); + + void createException(Integer hours); + + Integer getHours(Days day); + + void setHours(Days day, Integer hours); + + Boolean isDefault(Days day); + + void setDefault(Days day); + + boolean isExceptional(); + + void removeException(); + + boolean isDerived(); /* * Final conversation steps diff --git a/navalplanner-webapp/src/main/webapp/calendars/_edition.zul b/navalplanner-webapp/src/main/webapp/calendars/_edition.zul index 18839f89c..cadb7c638 100644 --- a/navalplanner-webapp/src/main/webapp/calendars/_edition.zul +++ b/navalplanner-webapp/src/main/webapp/calendars/_edition.zul @@ -1,24 +1,76 @@ - - - - - - - - - - - - - - - - + -