ItEr37S20CUAsignacionCalendarioLaboralRecursoItEr35S08: Revamping calendars management interface. Added new exception day types.

This commit is contained in:
Manuel Rego Casasnovas 2009-12-06 06:34:01 +01:00 committed by Javier Moran Rua
parent 67e6b9989c
commit b7c1b5b049
10 changed files with 835 additions and 169 deletions

View file

@ -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;
}
}

View file

@ -128,4 +128,8 @@ public class CalendarData extends BaseEntity {
this.parent = parent;
}
public void removeExpiringDate() {
this.expiringDate = null;
}
}

View file

@ -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() {

View file

@ -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();

View file

@ -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);
}

View file

@ -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));
}
}

View file

@ -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<Comboitem> 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<Comboitem> 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<CalendarException> getCalendarExceptions() {
List<CalendarException> calendarExceptions = new ArrayList<CalendarException>(baseCalendarModel.getCalendarExceptions());
Collections.sort(calendarExceptions,
new Comparator<CalendarException>() {
@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 "";
}
}

View file

@ -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<CalendarData> 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<CalendarExceptionType> getCalendarExceptionTypes() {
return calendarExceptionTypeDAO.list(CalendarExceptionType.class);
}
@Override
public Set<CalendarException> 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));
}
}

View file

@ -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<CalendarExceptionType> 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<CalendarException> 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
*/

View file

@ -20,124 +20,192 @@
<window id="${arg.top_id}" title="${arg.title}">
<tabbox>
<tabs>
<tab label="${i18n:_('Data')}" id="dataTab" />
<tab label="${i18n:_('History')}"
visible="@{calendarController.editionController.isEditing}" id="historyTab" />
</tabs>
<tabpanels>
<tabpanel>
<vbox>
<hbox>
<vbox>
<!-- Calendar data -->
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<label value="${i18n:_('Name')}" />
<textbox value="@{calendarController.editionController.baseCalendar.name}" width="300px"
constraint="no empty:${i18n:_('cannot be null or empty')}" />
</row>
<row>
<label value="${i18n:_('Type')}" />
<vbox>
<label value="@{calendarController.editionController.calendarType}" />
<combobox id="parentCalendars"
visible="@{calendarController.editionController.isDerived}"
disabled="@{calendarController.editionController.isDateValidFromPast}">
<comboitem self="@{each='baseCalnedar'}" value="@{baseCalnedar}"
label="@{baseCalnedar.name}" />
</combobox>
</vbox>
</row>
</rows>
</grid>
<!-- Edit calendar -->
<listbox id="hoursPerDay"
model="@{calendarController.editionController.getHoursPerDay}"
itemRenderer="@{calendarController.editionController.hoursPerDayRenderer}">
<listhead>
<listheader label="${i18n:_('Day of week')}" />
<listheader label="${i18n:_('Hours')}" />
<listheader label="${i18n:_('By default')}" />
</listhead>
</listbox>
</vbox>
<vbox id="dayInformation">
<calendarhighlighteddays id="calendarWidget"
value="@{calendarController.editionController.selectedDay,access='both'}"
ancestorExceptionDays="@{calendarController.editionController.ancestorExceptionDays,access='both'}"
ownExceptionDays="@{calendarController.editionController.ownExceptionDays,access='both'}"
zeroHoursDays="@{calendarController.editionController.zeroHoursDays,access='both'}" />
<hbox>
<label value="${i18n:_('Type of day')}" />
<label value="@{calendarController.editionController.typeOfDay}" />
</hbox>
<hbox>
<label value="${i18n:_('Hours of day')}" />
<label value="@{calendarController.editionController.hoursOfDay}" />
</hbox>
<hbox visible="@{calendarController.editionController.isNotSelectedDateFromPast}">
<vbox>
<button label="${i18n:_('Create exception')}"
onClick="calendarController.editionController.createException();" />
<button disabled="@{calendarController.editionController.isNotExceptional}"
label="${i18n:_('Remove exception')}"
onClick="calendarController.editionController.removeException();" />
</vbox>
<intbox id="exceptionHours" value="0" />
</hbox>
<vbox>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<label value="${i18n:_('Name')}" />
<textbox value="@{calendarController.editionController.baseCalendar.name}" width="300px"
constraint="no empty:${i18n:_('cannot be null or empty')}" />
</row>
<row>
<label value="${i18n:_('Type')}" />
<vbox>
<label value="@{calendarController.editionController.calendarType}" />
<label value="@{calendarController.editionController.nameParentCalendar}" visible="@{calendarController.editionController.isDerived}" />
</vbox>
</row>
</rows>
</grid>
</vbox>
<hbox>
<vbox id="dayInformation">
<calendarhighlighteddays id="calendarWidget"
value="@{calendarController.editionController.selectedDay,access='both'}"
ancestorExceptionDays="@{calendarController.editionController.ancestorExceptionDays,access='both'}"
ownExceptionDays="@{calendarController.editionController.ownExceptionDays,access='both'}"
zeroHoursDays="@{calendarController.editionController.zeroHoursDays,access='both'}" />
<hbox>
<label value="${i18n:_('Type of day')}" />
<label value="@{calendarController.editionController.typeOfDay}" />
</hbox>
<hbox>
<label value="${i18n:_('Hours of day')}" />
<label value="@{calendarController.editionController.hoursOfDay}" />
</hbox>
</vbox>
<tabbox>
<tabs>
<tab label="${i18n:_('Exceptions')}" id="exceptionsTab" />
<tab label="${i18n:_('Work week')}" id="workWeekTab" />
</tabs>
<tabpanels>
<tabpanel>
<vbox id="exceptionInformation">
<hbox>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<label value="${i18n:_('Exception Type')}" />
<combobox id="exceptionTypes"
disabled="@{calendarController.editionController.isSelectedDateFromPast}">
<comboitem self="@{each='calendarExceptionType'}"
value="@{calendarExceptionType}"
label="@{calendarExceptionType.name}" />
</combobox>
</row>
<row>
<label value="${i18n:_('Start Date')}" />
<datebox id="exceptionStartDate"
disabled="@{calendarController.editionController.isSelectedDateFromPast}"
value="@{calendarController.editionController.selectedDay}" />
</row>
<row>
<label value="${i18n:_('End Date')}" />
<datebox id="exceptionEndDate"
disabled="@{calendarController.editionController.isSelectedDateFromPast}"/>
</row>
<row>
<label value="${i18n:_('Hours')}" />
<intbox id="exceptionHours"
disabled="@{calendarController.editionController.isSelectedDateFromPast}" />
</row>
</rows>
</grid>
<listbox id="exceptionsList"
model="@{calendarController.editionController.calendarExceptions}"
itemRenderer="@{calendarController.editionController.calendarExceptionRenderer}"
rows="4">
<listhead>
<listheader label="${i18n:_('Day')}" />
<listheader label="${i18n:_('Exception Type')}" />
<listheader label="${i18n:_('Hours')}" />
<listheader label="${i18n:_('Operations')}" />
</listhead>
</listbox>
</hbox>
<hbox>
<button label="${i18n:_('Create exception')}"
disabled="@{calendarController.editionController.isSelectedDateFromPast}"
onClick="calendarController.editionController.createException();"
visible="@{calendarController.editionController.isNotOwnExceptionDay}" />
<button label="${i18n:_('Update exception')}"
disabled="@{calendarController.editionController.isSelectedDateFromPast}"
onClick="calendarController.editionController.updateException();"
visible="@{calendarController.editionController.isOwnExceptionDay}" />
</hbox>
</vbox>
</tabpanel>
<tabpanel>
<vbox>
<hbox>
<listbox id="hoursPerDay"
model="@{calendarController.editionController.getHoursPerDay}"
itemRenderer="@{calendarController.editionController.hoursPerDayRenderer}">
<listhead>
<listheader label="${i18n:_('Day of week')}" />
<listheader label="${i18n:_('Hours')}" />
<listheader label="${i18n:_('By default')}" />
</listhead>
</listbox>
<listbox id="historyInformation"
model="@{calendarController.editionController.historyVersions}"
itemRenderer="@{calendarController.editionController.historyVersionsRenderer}">
<listhead>
<listheader label="${i18n:_('Name')}" />
<listheader label="${i18n:_('Parent')}" />
<listheader label="${i18n:_('Valid from')}" />
<listheader label="${i18n:_('Expiring Date')}" />
<listheader label="${i18n:_('Summary')}" />
<listheader label="${i18n:_('Operations')}" />
</listhead>
</listbox>
</hbox>
<hbox>
<label value="${i18n:_('Type')}" />
<vbox>
<label value="@{calendarController.editionController.calendarType}" />
<combobox id="parentCalendars"
visible="@{calendarController.editionController.isDerived}"
disabled="@{calendarController.editionController.isDateValidFromPast}">
<comboitem self="@{each='baseCalnedar'}" value="@{baseCalnedar}"
label="@{baseCalnedar.name}" />
</combobox>
</vbox>
</hbox>
<hbox visible="@{calendarController.editionController.isEditing}">
<label value="${i18n:_('Valid from')}" />
<datebox id="dateValidFrom" value="@{calendarController.editionController.dateValidFrom}"
disabled="@{calendarController.editionController.isDateValidFromPast}" />
<label value="${i18n:_('to')}" />
<datebox id="expiringDate" value="@{calendarController.editionController.expiringDate}"
disabled="@{calendarController.editionController.isLastVersion}" />
</hbox>
<button onClick="calendarController.editionController.createNewVersion();"
label="${i18n:_('Create new work week')}"
visible="@{calendarController.editionController.isEditing}"
sclass="create-button global-action" />
</vbox>
</tabpanel>
</tabpanels>
</tabbox>
</hbox>
<hbox visible="@{calendarController.editionController.isEditing}">
<label value="${i18n:_('Valid from')}" />
<datebox id="dateValidFrom" value="@{calendarController.editionController.dateValidFrom}"
disabled="@{calendarController.editionController.isDateValidFromPast}" />
<label value="${i18n:_('to')}" />
<datebox id="expiringDate" value="@{calendarController.editionController.expiringDate}"
disabled="@{calendarController.editionController.isLastVersion}" />
</hbox>
</vbox>
</tabpanel>
<tabpanel>
<listbox model="@{calendarController.editionController.historyVersions}"
itemRenderer="@{calendarController.editionController.historyVersionsRenderer}">
<listhead>
<listheader label="${i18n:_('Name')}" />
<listheader label="${i18n:_('Parent')}" />
<listheader label="${i18n:_('Valid from')}" />
<listheader label="${i18n:_('Expiring Date')}" />
<listheader label="${i18n:_('Summary')}" />
<listheader label="${i18n:_('Operations')}" />
</listhead>
</listbox>
</tabpanel>
</tabpanels>
</tabbox>
<hbox>
<button onClick="calendarController.editionController.save();"
label="${arg.save_button_label}"
@ -146,11 +214,8 @@
<button onClick="calendarController.editionController.cancel();"
label="${arg.cancel_button_label}"
sclass="cancel-button global-action" />
<button onClick="calendarController.editionController.createNewVersion();"
label="${i18n:_('Create new version')}"
visible="@{calendarController.editionController.isEditing}"
sclass="create-button global-action" />
</hbox>
</vbox>
</window>