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 60aa7346a..f7a85deea 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 @@ -694,18 +694,56 @@ public class BaseCalendar extends BaseEntity implements IWorkHours { return Collections.unmodifiableList(calendarAvailabilities); } - public void addCalendarAvailability( - CalendarAvailability calendarAvailability) { + public void addNewCalendarAvailability( + CalendarAvailability calendarAvailability) + throws IllegalArgumentException { if (this instanceof ResourceCalendar) { + if (!calendarAvailabilities.isEmpty()) { + CalendarAvailability lastCalendarAvailability = calendarAvailabilities + .get(calendarAvailabilities.size() - 1); + if (lastCalendarAvailability.getEndDate() == null) { + if (lastCalendarAvailability.getStartDate().compareTo( + calendarAvailability.getStartDate()) >= 0) { + throw new IllegalArgumentException( + "New calendar availability should start after the last calendar availability"); + } + } else { + if (lastCalendarAvailability.getEndDate().compareTo( + calendarAvailability.getStartDate()) >= 0) { + throw new IllegalArgumentException( + "New calendar availability should start after the last calendar availability"); + } + } + lastCalendarAvailability.setEndDate(calendarAvailability + .getStartDate().minusDays(1)); + } calendarAvailabilities.add(calendarAvailability); } } public void removeCalendarAvailability( - CalendarAvailability calendarAvailability) { + CalendarAvailability calendarAvailability) + throws IllegalArgumentException { if (this instanceof ResourceCalendar) { + if (calendarAvailability.getStartDate().compareTo(new LocalDate()) <= 0) { + throw new IllegalArgumentException( + "Calendar availabilty already in use"); + } calendarAvailabilities.remove(calendarAvailability); } } -} + public boolean isActive(Date date) { + return isActive(new LocalDate(date)); + } + + public boolean isActive(LocalDate date) { + for (CalendarAvailability calendarAvailability : calendarAvailabilities) { + if (calendarAvailability.isActive(date)) { + return true; + } + } + return false; + } + +} \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarAvailability.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarAvailability.java index 924072d38..4f3f3dd15 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarAvailability.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/CalendarAvailability.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; @@ -33,17 +34,23 @@ import org.navalplanner.business.common.BaseEntity; */ public class CalendarAvailability extends BaseEntity { + public static CalendarAvailability craete() { + return create(new CalendarAvailability(new LocalDate(), null)); + } + public static CalendarAvailability craete(Date startDate, Date endDate) { return create(new CalendarAvailability(new LocalDate(startDate), new LocalDate(endDate))); } - public static CalendarAvailability craete(LocalDate startDate, + public static CalendarAvailability create(LocalDate startDate, LocalDate endDate) { return create(new CalendarAvailability(startDate, endDate)); } + @NotNull private LocalDate startDate; + private LocalDate endDate; /** @@ -52,16 +59,27 @@ public class CalendarAvailability extends BaseEntity { public CalendarAvailability() { } - private CalendarAvailability(LocalDate startDate, LocalDate endDate) { - this.startDate = startDate; - this.endDate = endDate; + private CalendarAvailability(LocalDate startDate, LocalDate endDate) + throws IllegalArgumentException { + setStartDate(startDate); + setEndDate(endDate); } public LocalDate getStartDate() { return startDate; } - public void setStartDate(LocalDate startDate) { + public void setStartDate(LocalDate startDate) + throws IllegalArgumentException { + if (startDate == null) { + throw new IllegalArgumentException("Start date must not be null"); + } + if (endDate != null) { + if (startDate.compareTo(endDate) > 0) { + throw new IllegalArgumentException( + "End date must be greater or equal than start date"); + } + } this.startDate = startDate; } @@ -69,8 +87,26 @@ public class CalendarAvailability extends BaseEntity { return endDate; } - public void setEndDate(LocalDate endDate) { + public void setEndDate(LocalDate endDate) throws IllegalArgumentException { + if (endDate != null) { + if (startDate.compareTo(endDate) > 0) { + throw new IllegalArgumentException( + "End date must be greater or equal than start date"); + } + } this.endDate = endDate; } + public boolean isActive(LocalDate date) { + if (startDate.compareTo(date) > 0) { + return false; + } + + if ((endDate != null) && (endDate.compareTo(date) < 0)) { + return false; + } + + return true; + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ResourceCalendar.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ResourceCalendar.java index 824858825..ef7f6e7dc 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ResourceCalendar.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/ResourceCalendar.java @@ -20,6 +20,7 @@ package org.navalplanner.business.calendars.entities; +import org.joda.time.LocalDate; import org.navalplanner.business.resources.entities.Resource; /** @@ -30,10 +31,7 @@ import org.navalplanner.business.resources.entities.Resource; public class ResourceCalendar extends BaseCalendar { public static ResourceCalendar create() { - ResourceCalendar resourceCalendar = new ResourceCalendar(CalendarData - .create()); - resourceCalendar.setNewObject(true); - return resourceCalendar; + return create(new ResourceCalendar(CalendarData.create())); } /** @@ -44,6 +42,17 @@ public class ResourceCalendar extends BaseCalendar { private ResourceCalendar(CalendarData calendarData) { super(calendarData); + CalendarAvailability calendarAvailability = CalendarAvailability + .create(new LocalDate(), null); + addNewCalendarAvailability(calendarAvailability); + } + + @Override + public Integer getWorkableHours(LocalDate date) { + if (!isActive(date)) { + return 0; + } + return super.getWorkableHours(date); } } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/ResourceCalendarTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/ResourceCalendarTest.java new file mode 100644 index 000000000..3c355da1c --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/ResourceCalendarTest.java @@ -0,0 +1,105 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.business.test.calendars.entities; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.joda.time.LocalDate; +import org.junit.Test; +import org.navalplanner.business.calendars.entities.CalendarAvailability; +import org.navalplanner.business.calendars.entities.ResourceCalendar; +import org.navalplanner.business.calendars.entities.CalendarData.Days; + +/** + * Tests for {@link ResourceCalendar}. + * + * @author Manuel Rego Casasnovas + */ +public class ResourceCalendarTest { + + public static ResourceCalendar createBasicResourceCalendar() { + ResourceCalendar calendar = ResourceCalendar.create(); + + calendar.setName("Test"); + + calendar.setHours(Days.MONDAY, 8); + calendar.setHours(Days.TUESDAY, 8); + calendar.setHours(Days.WEDNESDAY, 8); + calendar.setHours(Days.THURSDAY, 8); + calendar.setHours(Days.FRIDAY, 8); + calendar.setHours(Days.SATURDAY, 8); + calendar.setHours(Days.SUNDAY, 8); + + return calendar; + } + + private static final LocalDate PAST = (new LocalDate()).minusMonths(1); + private static final LocalDate FUTURE = (new LocalDate()).plusMonths(1); + + @Test + public void testIsActive() { + ResourceCalendar calendar = createBasicResourceCalendar(); + + assertFalse(calendar.isActive(PAST)); + assertTrue(calendar.isActive(FUTURE)); + } + + @Test + public void testGetWorkableHours() { + ResourceCalendar calendar = createBasicResourceCalendar(); + + assertThat(calendar.getWorkableHours(PAST), equalTo(0)); + assertThat(calendar.getWorkableHours(FUTURE), equalTo(8)); + } + + @Test(expected = IllegalArgumentException.class) + public void notAllowCreateCalendarAvailabilityInThePast() { + ResourceCalendar calendar = createBasicResourceCalendar(); + + CalendarAvailability calendarAvailability = CalendarAvailability + .create(PAST, null); + calendar.addNewCalendarAvailability(calendarAvailability); + } + + @Test + public void allowCreateCalendarAvailabilityInTheFuture() { + ResourceCalendar calendar = createBasicResourceCalendar(); + + CalendarAvailability calendarAvailability = CalendarAvailability + .create(FUTURE, null); + calendar.addNewCalendarAvailability(calendarAvailability); + + List calendarAvailabilities = calendar.getCalendarAvailabilities(); + assertThat(calendarAvailabilities.size(), equalTo(2)); + assertThat(calendarAvailabilities.get(0).getEndDate(), equalTo(FUTURE + .minusDays(1))); + assertThat(calendarAvailabilities.get(1).getStartDate(), + equalTo(FUTURE)); + assertNull(calendarAvailabilities.get(1).getEndDate()); + } + +} \ No newline at end of file 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 75ec1a84a..1e64e8c44 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 @@ -145,6 +145,7 @@ public class BaseCalendarModel implements IBaseCalendarModel { } } baseCalendar.getExceptions().size(); + baseCalendar.getCalendarAvailabilities().size(); forceLoadExceptionTypes(); }