From fee8406e5e541367e373a546d587b0bfce490285 Mon Sep 17 00:00:00 2001 From: Susana Montes Pedreira Date: Mon, 12 Apr 2010 16:35:58 +0200 Subject: [PATCH] ItEr53S10AdaptacionServiciosRESTItEr52S10 : adds the import of calendars to the calendar service. --- .../daos/CalendarAvailabilityDAO.java | 40 ++ .../daos/ICalendarAvailabilityDAO.java | 34 ++ .../calendars/entities/BaseCalendar.java | 139 +++++++ .../entities/CalendarAvailability.java | 11 +- .../calendars/entities/CalendarData.java | 29 ++ .../calendars/entities/CalendarException.java | 22 +- .../business/common/Registry.java | 7 + .../business/resources/entities/Resource.java | 22 +- .../ws/calendars/api/BaseCalendarDTO.java | 10 +- .../ws/calendars/api/CalendarDataDTO.java | 10 +- .../calendars/api/CalendarExceptionDTO.java | 22 +- .../ws/calendars/api/ICalendarService.java | 3 + .../ws/calendars/impl/CalendarConverter.java | 316 +++++++++++++++- .../calendars/impl/CalendarServiceREST.java | 15 +- .../api/CalendarAvailabilityDTO.java | 62 ++++ .../ws/resources/api/ResourceCalendarDTO.java | 77 ++++ .../ws/resources/api/ResourceDTO.java | 5 +- .../ws/resources/impl/ResourceConverter.java | 101 ++++- .../BaseCalendarServiceTest.java | 348 ++++++++++++++++++ .../ws/materials/MaterialServiceTest.java | 27 +- .../ws/resources/api/ResourceServiceTest.java | 299 ++++++++------- .../ReportAdvancesServiceTest.java | 19 +- scripts/rest-clients/calendars-sample.xml | 69 ++++ scripts/rest-clients/import-calendars.sh | 33 ++ .../resource-withCalendars-sample.xml | 62 ++++ 25 files changed, 1547 insertions(+), 235 deletions(-) create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/CalendarAvailabilityDAO.java create mode 100644 navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/ICalendarAvailabilityDAO.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/CalendarAvailabilityDTO.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceCalendarDTO.java create mode 100644 navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/basecalendars/BaseCalendarServiceTest.java create mode 100644 scripts/rest-clients/calendars-sample.xml create mode 100755 scripts/rest-clients/import-calendars.sh create mode 100644 scripts/rest-clients/resource-withCalendars-sample.xml diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/CalendarAvailabilityDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/CalendarAvailabilityDAO.java new file mode 100644 index 000000000..324027662 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/CalendarAvailabilityDAO.java @@ -0,0 +1,40 @@ +/* + * This file is part of NavalPlan + * + * 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.calendars.daos; + +import org.navalplanner.business.calendars.entities.CalendarAvailability; +import org.navalplanner.business.common.daos.IntegrationEntityDAO; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Repository; + +/** + * DAO for {@link CalendarAvailability} + * + * @author Susana Montes Pedreira + */ +@Repository +@Scope(BeanDefinition.SCOPE_SINGLETON) +public class CalendarAvailabilityDAO extends + IntegrationEntityDAO + implements ICalendarAvailabilityDAO { + +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/ICalendarAvailabilityDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/ICalendarAvailabilityDAO.java new file mode 100644 index 000000000..0ffcdeb41 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/daos/ICalendarAvailabilityDAO.java @@ -0,0 +1,34 @@ +/* + * This file is part of NavalPlan + * + * 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.calendars.daos; + +import org.navalplanner.business.calendars.entities.CalendarAvailability; +import org.navalplanner.business.common.daos.IIntegrationEntityDAO; + +/** + * Contract for {@link CalendarAvailabilityDAO} + * + * @author Susana Montes Pedreira + */ +public interface ICalendarAvailabilityDAO extends + IIntegrationEntityDAO { + +} 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 4ed46d1f9..d7d41479c 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 @@ -27,12 +27,15 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.apache.commons.lang.StringUtils; +import org.hibernate.validator.AssertTrue; import org.hibernate.validator.NotEmpty; import org.joda.time.DateTimeConstants; import org.joda.time.LocalDate; import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; import org.navalplanner.business.calendars.entities.CalendarData.Days; import org.navalplanner.business.common.IntegrationEntity; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.planner.entities.ResourcesPerDay; /** @@ -50,6 +53,45 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours { return create(new BaseCalendar(CalendarData.create())); } + public static BaseCalendar createUnvalidated(String code, String name, + BaseCalendar parent, Set exceptions, + List calendarDataVersions) + throws IllegalArgumentException { + + BaseCalendar baseCalendar = create(new BaseCalendar(CalendarData + .create()), code); + baseCalendar.name = name; + + if ((exceptions != null) && (!exceptions.isEmpty())) { + for (CalendarException exception : exceptions) { + baseCalendar.addExceptionDay(exception); + } + } + + if ((calendarDataVersions != null) && (!calendarDataVersions.isEmpty())) { + baseCalendar.calendarDataVersions = calendarDataVersions; + } + + if (parent != null) { + baseCalendar.setParent(parent); + } + + return baseCalendar; + + } + + public void updateUnvalidated(String name, BaseCalendar parent) { + + if (!StringUtils.isBlank(name)) { + this.name = name; + } + + if (parent != null) { + setParent(parent); + } + + } + @NotEmpty private String name; @@ -418,6 +460,43 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours { calendarDataVersions.add(newCalendarData); } + public void addNewVersion(CalendarData version){ + if (version.getExpiringDate() == null) { + if (getLastCalendarData().getExpiringDate() == null) { + throw new IllegalArgumentException( + "the date is null and overlaps with the last version."); + } + else{ + calendarDataVersions.add(version); + return; + } + } + + if (version.getExpiringDate().toDateTimeAtStartOfDay().toDate() + .compareTo(new Date()) <= 0) { + throw new IllegalArgumentException( + "You can not add a version with previous date than current date"); + } + for (int i = 0; i < calendarDataVersions.size(); i++) { + if ((calendarDataVersions.get(i).getExpiringDate() == null) + || (calendarDataVersions.get(i).getExpiringDate() + .compareTo(version.getExpiringDate()) > 0)) { + if ((i - 1 >= 0) + && (calendarDataVersions.get(i - 1).getExpiringDate() != null) + && (calendarDataVersions.get(i - 1).getExpiringDate() + .compareTo(version.getExpiringDate()) >= 0)) { + throw new IllegalArgumentException( + "the date is null and overlap with the other version."); + } + calendarDataVersions.add(i, version); + return; + } + } + + calendarDataVersions.add(version); + + } + public BaseCalendar newCopy() { BaseCalendar copy = create(); copyFields(copy); @@ -942,4 +1021,64 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours { return org.navalplanner.business.common.Registry.getBaseCalendarDAO(); } + @SuppressWarnings("unused") + @AssertTrue(message = "the versions: the dates should be sorted and could not overlap ") + public boolean checkConstraintDateCouldNotOverlap() { + + if (calendarDataVersions == null || calendarDataVersions.isEmpty()) { + return true; + } + + if (this.getLastCalendarData().getExpiringDate() != null) { + return false; + } + + for (int i = 0; i < calendarDataVersions.size() - 2; i++) { + LocalDate date1 = calendarDataVersions.get(i).getExpiringDate(); + LocalDate date2 = calendarDataVersions.get(i + 1).getExpiringDate(); + if ((date1 == null) || (date2 == null) + || (date1.compareTo(date2) >= 0)) { + return false; + } + } + + return true; + } + + public CalendarException getCalendarExceptionByCode(String code) + throws InstanceNotFoundException { + + if (StringUtils.isBlank(code)) { + throw new InstanceNotFoundException(code, CalendarException.class + .getName()); + } + + for (CalendarException e : this.exceptions) { + if (e.getCode().equalsIgnoreCase(StringUtils.trim(code))) { + return e; + } + } + + throw new InstanceNotFoundException(code, CalendarException.class + .getName()); + + } + + public CalendarData getCalendarDataByCode(String code) + throws InstanceNotFoundException { + + if (StringUtils.isBlank(code)) { + throw new InstanceNotFoundException(code, CalendarData.class + .getName()); + } + + for (CalendarData e : this.calendarDataVersions) { + if (e.getCode().equalsIgnoreCase(StringUtils.trim(code))) { + return e; + } + } + + throw new InstanceNotFoundException(code, CalendarData.class.getName()); + + } } 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 4d5615b99..74a43c982 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 @@ -25,7 +25,9 @@ import java.util.Date; import org.hibernate.validator.NotNull; import org.joda.time.LocalDate; -import org.navalplanner.business.common.BaseEntity; +import org.navalplanner.business.calendars.daos.ICalendarAvailabilityDAO; +import org.navalplanner.business.common.IntegrationEntity; +import org.navalplanner.business.common.Registry; /** * Stores information about activating periods, that define the availability of @@ -33,7 +35,7 @@ import org.navalplanner.business.common.BaseEntity; * * @author Manuel Rego Casasnovas */ -public class CalendarAvailability extends BaseEntity { +public class CalendarAvailability extends IntegrationEntity { public static CalendarAvailability craete() { return create(new CalendarAvailability(new LocalDate(), null)); @@ -118,4 +120,9 @@ public class CalendarAvailability extends BaseEntity { return true; } + @Override + protected ICalendarAvailabilityDAO getIntegrationEntityDAO() { + return Registry.getCalendarAvailabilityDAO(); + } + } 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 27a089c53..ff248fd89 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 @@ -40,6 +40,35 @@ public class CalendarData extends IntegrationEntity { return create(new CalendarData()); } + public static CalendarData createUnvalidated(String code, + LocalDate expiringDate, BaseCalendar parent) { + CalendarData calendarData = create(new CalendarData(), code); + calendarData.expiringDate = expiringDate; + calendarData.parent = parent; + return calendarData; + } + + public void updateUnvalidated(LocalDate expiringDate, BaseCalendar parent) { + if (expiringDate != null) { + this.expiringDate = expiringDate; + } + if (parent != null) { + this.parent = parent; + } + } + + public void updateHourPerDay(Map hoursPerDay) + throws IllegalArgumentException { + if ((hoursPerDay != null)) { + for (Days day : Days.values()) { + Integer hours = hoursPerDay.get(day.ordinal()); + if (hours != null) { + setHours(day, hours); + } + } + } + } + private Map hoursPerDay; private LocalDate expiringDate; 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 37c09c721..9639f3aa0 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 @@ -48,11 +48,30 @@ public class CalendarException extends IntegrationEntity { return create(new CalendarException(date, hours, type)); } + public static CalendarException create(String code, LocalDate date, + Integer hours, CalendarExceptionType type) { + return create(new CalendarException(date, hours, type), code); + } + + public void updateUnvalidated(LocalDate date, Integer hours, + CalendarExceptionType type) { + if (date != null) { + this.date = date; + } + + if (hours != null) { + this.hours = hours; + } + + if (type != null) { + this.type = type; + } + } + private LocalDate date; private Integer hours; - @NotNull private CalendarExceptionType type; /** @@ -77,6 +96,7 @@ public class CalendarException extends IntegrationEntity { return hours != null ? hours : 0; } + @NotNull public CalendarExceptionType getType() { return type; } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java index b21fb4afd..c4df0214d 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java @@ -22,6 +22,7 @@ package org.navalplanner.business.common; import org.navalplanner.business.advance.daos.IAdvanceTypeDAO; import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; +import org.navalplanner.business.calendars.daos.ICalendarAvailabilityDAO; import org.navalplanner.business.calendars.daos.ICalendarDataDAO; import org.navalplanner.business.calendars.daos.ICalendarExceptionDAO; import org.navalplanner.business.calendars.daos.ICalendarExceptionTypeDAO; @@ -169,6 +170,9 @@ public class Registry { @Autowired private IUnitTypeDAO unitTypeDAO; + @Autowired + private ICalendarAvailabilityDAO calendarAvailabilityDAO; + private Registry() { } @@ -306,4 +310,7 @@ public class Registry { return getInstance().calendarDataDAO; } + public static ICalendarAvailabilityDAO getCalendarAvailabilityDAO() { + return getInstance().calendarAvailabilityDAO; + } } \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java index 614e7394c..2bf4fe84c 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Resource.java @@ -712,31 +712,19 @@ public abstract class Resource extends IntegrationEntity { return calendar; } - public void setResourceCalendar(String calendarName) + public void setResourceCalendar(String calendarCode) throws InstanceNotFoundException, MultipleInstancesException { ResourceCalendar calendar; - if (StringUtils.isBlank(calendarName)) { - + if (StringUtils.isBlank(calendarCode)) { calendar = Registry.getConfigurationDAO().getConfiguration(). getDefaultCalendar().newDerivedResourceCalendar(); } else { - - List baseCalendars = Registry.getBaseCalendarDAO(). - findByName(calendarName); - - if (baseCalendars.isEmpty()) { - throw new InstanceNotFoundException(calendarName, - BaseCalendar.class.getName()); - } if (baseCalendars.size() > 1) { - throw new MultipleInstancesException(calendarName, - BaseCalendar.class.getName()); - } else { - calendar = baseCalendars.get(0).newDerivedResourceCalendar(); - } - + BaseCalendar baseCalendar = Registry.getBaseCalendarDAO() + .findByCode(calendarCode); + calendar = baseCalendar.newDerivedResourceCalendar(); } setCalendar(calendar); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/BaseCalendarDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/BaseCalendarDTO.java index 6099c737b..119ac56d9 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/BaseCalendarDTO.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/BaseCalendarDTO.java @@ -42,6 +42,9 @@ public class BaseCalendarDTO extends IntegrationEntityDTO { @XmlAttribute public String name; + @XmlAttribute + public String parent; + @XmlElementWrapper(name = "calendar-exception-list") @XmlElement(name = "calendar-exception") public List calendarExceptions = new ArrayList(); @@ -53,19 +56,20 @@ public class BaseCalendarDTO extends IntegrationEntityDTO { public BaseCalendarDTO() { } - public BaseCalendarDTO(String code, String name, + public BaseCalendarDTO(String code, String name, String parent, List calendarExceptions, List calendarDatas) { super(code); this.name = name; + this.parent = parent; this.calendarExceptions = calendarExceptions; this.calendarDatas = calendarDatas; } - public BaseCalendarDTO(String name, + public BaseCalendarDTO(String name, String parent, List calendarExceptions, List calendarDatas) { - this(generateCode(), name, calendarExceptions, calendarDatas); + this(generateCode(), name, parent, calendarExceptions, calendarDatas); } @Override diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarDataDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarDataDTO.java index b086f1290..e9105eb5c 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarDataDTO.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarDataDTO.java @@ -21,12 +21,12 @@ package org.navalplanner.ws.calendars.api; import java.util.ArrayList; -import java.util.Date; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.datatype.XMLGregorianCalendar; import org.navalplanner.business.calendars.entities.CalendarData; import org.navalplanner.ws.common.api.IntegrationEntityDTO; @@ -41,11 +41,11 @@ public class CalendarDataDTO extends IntegrationEntityDTO { public final static String ENTITY_TYPE = "calendar-data"; @XmlElementWrapper(name = "hors-per-day-list") - @XmlElement(name = "hors-per-day") + @XmlElement(name = "hours-per-day") public List hoursPerDays = new ArrayList(); @XmlAttribute(name = "expiring-date") - public Date expiringDate; + public XMLGregorianCalendar expiringDate; @XmlAttribute(name = "parent-calendar") public String parentCalendar; @@ -54,7 +54,7 @@ public class CalendarDataDTO extends IntegrationEntityDTO { } public CalendarDataDTO(String code, List hoursPerDays, - Date expiringDate, String parentCalendar) { + XMLGregorianCalendar expiringDate, String parentCalendar) { super(code); this.hoursPerDays = hoursPerDays; this.expiringDate = expiringDate; @@ -62,7 +62,7 @@ public class CalendarDataDTO extends IntegrationEntityDTO { } public CalendarDataDTO(List hoursPerDays, - Date expiringDate, String parentCalendar) { + XMLGregorianCalendar expiringDate, String parentCalendar) { this(generateCode(), hoursPerDays, expiringDate, parentCalendar); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarExceptionDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarExceptionDTO.java index 085674689..c6eaecc0e 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarExceptionDTO.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/CalendarExceptionDTO.java @@ -20,9 +20,8 @@ package org.navalplanner.ws.calendars.api; -import java.util.Date; - import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.datatype.XMLGregorianCalendar; import org.navalplanner.business.calendars.entities.CalendarException; import org.navalplanner.ws.common.api.IntegrationEntityDTO; @@ -37,28 +36,29 @@ public class CalendarExceptionDTO extends IntegrationEntityDTO { public final static String ENTITY_TYPE = "calendar-exception"; @XmlAttribute - public Date date; + public XMLGregorianCalendar date; @XmlAttribute public Integer hours; - @XmlAttribute(name = "calendar-exception-type-name") - public String calendarExceptionTypeName; + @XmlAttribute(name = "calendar-exception-type-code") + public String calendarExceptionTypeCode; public CalendarExceptionDTO() { } - public CalendarExceptionDTO(String code, Date date, Integer hours, - String calendarExceptionTypeName) { + public CalendarExceptionDTO(String code, XMLGregorianCalendar date, + Integer hours, + String calendarExceptionTypeCode) { super(code); this.date = date; this.hours = hours; - this.calendarExceptionTypeName = calendarExceptionTypeName; + this.calendarExceptionTypeCode = calendarExceptionTypeCode; } - public CalendarExceptionDTO(Date date, Integer hours, - String calendarExceptionTypeName) { - this(generateCode(), date, hours, calendarExceptionTypeName); + public CalendarExceptionDTO(XMLGregorianCalendar date, Integer hours, + String calendarExceptionTypeCode) { + this(generateCode(), date, hours, calendarExceptionTypeCode); } @Override diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/ICalendarService.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/ICalendarService.java index 94f9ca754..e8497d999 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/ICalendarService.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/api/ICalendarService.java @@ -21,6 +21,7 @@ package org.navalplanner.ws.calendars.api; import org.navalplanner.business.calendars.entities.BaseCalendar; +import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO; /** * Service for managing {@link BaseCalendar} entities. @@ -31,4 +32,6 @@ public interface ICalendarService { BaseCalendarListDTO getBaseCalendars(); + public InstanceConstraintViolationsListDTO addBaseCalendars( + BaseCalendarListDTO BaseCalendraListDTO); } \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarConverter.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarConverter.java index 06e0ae25f..78de1db83 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarConverter.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarConverter.java @@ -20,14 +20,33 @@ package org.navalplanner.ws.calendars.impl; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import static org.navalplanner.web.I18nHelper._; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeConstants; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +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.CalendarData.Days; +import org.navalplanner.business.common.Registry; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.ws.calendars.api.BaseCalendarDTO; import org.navalplanner.ws.calendars.api.CalendarDataDTO; import org.navalplanner.ws.calendars.api.CalendarExceptionDTO; @@ -35,8 +54,8 @@ import org.navalplanner.ws.calendars.api.HoursPerDayDTO; /** * Converter from/to {@link BaseCalendar} related entities to/from DTOs. - * * @author Manuel Rego Casasnovas + * @author Susana Montes Pedreira */ public final class CalendarConverter { @@ -54,16 +73,28 @@ public final class CalendarConverter { calendarDataDTOs.add(toDTO(calendarData)); } + String parent = null; + if (baseCalendar.getParent() != null) { + parent = baseCalendar.getParent().getCode(); + } + return new BaseCalendarDTO(baseCalendar.getCode(), baseCalendar - .getName(), calendarExceptionDTOs, calendarDataDTOs); + .getName(), parent, calendarExceptionDTOs, calendarDataDTOs); } private final static CalendarExceptionDTO toDTO( CalendarException calendarException) { - return new CalendarExceptionDTO(calendarException.getCode(), - calendarException.getDate().toDateTimeAtStartOfDay().toDate(), + + XMLGregorianCalendar date = null; + try { + date = toXMLGregorianCalendar(calendarException.getDate()); + } catch (DatatypeConfigurationException e) { + throw new ValidationException(e.getMessage()); + } + + return new CalendarExceptionDTO(calendarException.getCode(), date, calendarException.getHours(), calendarException.getType() - .getName()); + .getCode()); } private final static CalendarDataDTO toDTO(CalendarData calendarData) { @@ -75,15 +106,276 @@ public final class CalendarConverter { hoursPerDayDTOs.add(new HoursPerDayDTO(dayName, hours)); } - Date expiringDate = (calendarData.getExpiringDate() != null) ? calendarData - .getExpiringDate().toDateTimeAtStartOfDay().toDate() + XMLGregorianCalendar expiringDate = null; + try { + expiringDate = (calendarData.getExpiringDate() != null) ? toXMLGregorianCalendar(calendarData + .getExpiringDate()) : null; + } catch (DatatypeConfigurationException e) { + throw new ValidationException(e.getMessage()); + } + String parentCalendar = (calendarData.getParent() != null) ? calendarData .getParent().getCode() : null; - return new CalendarDataDTO(hoursPerDayDTOs, expiringDate, - parentCalendar); + return new CalendarDataDTO(calendarData.getCode(), hoursPerDayDTOs, + expiringDate, parentCalendar); + } + + public final static BaseCalendar toEntity(BaseCalendarDTO baseCalendarDTO) { + + Set exceptions = new HashSet(); + if (baseCalendarDTO.calendarExceptions != null) { + for (CalendarExceptionDTO exceptionDTO : baseCalendarDTO.calendarExceptions) { + exceptions.add(toEntity(exceptionDTO)); + } + } + + List calendarDataVersions = new ArrayList(); + if (baseCalendarDTO.calendarDatas != null) { + for (CalendarDataDTO calendarDataDTO : baseCalendarDTO.calendarDatas) { + calendarDataVersions.add(toEntity(calendarDataDTO)); + } + calendarDataVersions = getVersionsOrderedByExpiringDate(calendarDataVersions); + } + + BaseCalendar parent = findBaseCalendarParent(baseCalendarDTO.parent); + + try { + return BaseCalendar.createUnvalidated(baseCalendarDTO.code, + baseCalendarDTO.name, parent, exceptions, calendarDataVersions); + } catch (IllegalArgumentException e) { + throw new ValidationException(_(e.getMessage())); + } + } + + public final static CalendarException toEntity( + CalendarExceptionDTO calendarExceptionDTO) { + + LocalDate date = null; + if (calendarExceptionDTO.date != null) { + date = toLocalDate(calendarExceptionDTO.date); + } + + CalendarExceptionType type = findCalendarExceptionType(calendarExceptionDTO.calendarExceptionTypeCode); + + return CalendarException.create(calendarExceptionDTO.code, date, + calendarExceptionDTO.hours, type); + } + + public final static CalendarData toEntity(CalendarDataDTO calendarDataDTO) { + LocalDate expiringDate = null; + if (calendarDataDTO.expiringDate != null) { + expiringDate = toLocalDate(calendarDataDTO.expiringDate); + } + + BaseCalendar parent = findBaseCalendarParent(calendarDataDTO.parentCalendar); + + CalendarData calendarData = CalendarData.createUnvalidated( + calendarDataDTO.code, expiringDate, parent); + + Map hoursPerDays = getHoursPerDays(calendarDataDTO.hoursPerDays); + try { + calendarData.updateHourPerDay(hoursPerDays); + } catch (IllegalArgumentException e) { + throw new ValidationException(_(e.getMessage())); + } + + return calendarData; + } + + public final static void update(BaseCalendar baseCalendar, + BaseCalendarDTO baseCalendarDTO) { + + if (baseCalendarDTO.calendarExceptions != null) { + for (CalendarExceptionDTO exceptionDTO : baseCalendarDTO.calendarExceptions) { + + if (StringUtils.isBlank(exceptionDTO.code)) { + throw new ValidationException( + _("missing code in a calendar exception")); + } + + if (exceptionDTO.date == null) { + throw new ValidationException( + _("missing date in a calendar exception")); + } + // find by code + try { + CalendarException exception = baseCalendar + .getCalendarExceptionByCode(exceptionDTO.code); + update(exception, exceptionDTO); + } catch (InstanceNotFoundException e) { + // find by date + CalendarException exception = baseCalendar + .getOwnExceptionDay(toLocalDate(exceptionDTO.date)); + if (exception != null) { + throw new ValidationException( + _("exception date already exists")); + } else { + try { + baseCalendar + .addExceptionDay(toEntity(exceptionDTO)); + } catch (IllegalArgumentException o) { + throw new ValidationException(_(o.getMessage())); + } + } + } + } + } + + if (baseCalendarDTO.calendarDatas != null) { + + for (CalendarDataDTO calendarDataDTO : baseCalendarDTO.calendarDatas) { + + if (StringUtils.isBlank(calendarDataDTO.code)) { + throw new ValidationException( + _("missing code in a calendar data version")); + } + + // find by code + try { + CalendarData version = baseCalendar + .getCalendarDataByCode(calendarDataDTO.code); + update(version, calendarDataDTO); + } catch (InstanceNotFoundException e) { + try { + baseCalendar.addNewVersion(toEntity(calendarDataDTO)); + } catch (IllegalArgumentException o) { + throw new ValidationException(_(o.getMessage())); + } + } + } + + } + + BaseCalendar parent = null; + if (!StringUtils.isBlank(baseCalendarDTO.parent)) { + try { + parent = Registry.getBaseCalendarDAO().findByCode( + baseCalendarDTO.parent); + } catch (InstanceNotFoundException e) { + throw new ValidationException( + _("The base calendar parent not found")); + } + } + + baseCalendar.updateUnvalidated(baseCalendarDTO.name, parent); + + } + + public final static void update(CalendarException exception, + CalendarExceptionDTO calendarExceptionDTO) { + + LocalDate date = null; + if (calendarExceptionDTO.date != null) { + date = toLocalDate(calendarExceptionDTO.date); + } + + CalendarExceptionType type = findCalendarExceptionType(calendarExceptionDTO.calendarExceptionTypeCode); + + exception.updateUnvalidated(date, calendarExceptionDTO.hours, type); + } + + public final static void update(CalendarData calendarData, + CalendarDataDTO calendarDataDTO) { + + LocalDate expiringDate = null; + if (calendarDataDTO.expiringDate != null) { + expiringDate = toLocalDate(calendarDataDTO.expiringDate); + } + + BaseCalendar parent = findBaseCalendarParent(calendarDataDTO.parentCalendar); + + Map hoursPerDays = getHoursPerDays(calendarDataDTO.hoursPerDays); + try { + calendarData.updateHourPerDay(hoursPerDays); + } catch (IllegalArgumentException e) { + throw new ValidationException(_(e.getMessage())); + } + + calendarData.updateUnvalidated(expiringDate, parent); + + } + + private static Map getHoursPerDays( + List hoursPerDayDTOs) { + Map hoursPerDays = new HashMap(); + if (hoursPerDayDTOs != null) { + for (HoursPerDayDTO hoursPerDayDTO : hoursPerDayDTOs) { + Integer day = CalendarData.Days.valueOf(hoursPerDayDTO.day) + .ordinal(); + if (day != null) { + hoursPerDays.put(day, hoursPerDayDTO.hours); + } else { + throw new ValidationException(_("a day is not valid")); + } + } + } + return hoursPerDays; + } + + private static BaseCalendar findBaseCalendarParent(String parentCode) { + if (StringUtils.isBlank(parentCode)) { + return null; + } + + try { + return Registry.getBaseCalendarDAO().findByCode(parentCode); + } catch (InstanceNotFoundException e) { + throw new ValidationException( + _("The base calendar parent not found")); + } + } + + private static CalendarExceptionType findCalendarExceptionType( + String typeCode) { + if (StringUtils.isBlank(typeCode)) { + return null; + } + + try { + return Registry.getCalendarExceptionTypeDAO().findByCode(typeCode); + } catch (InstanceNotFoundException e) { + throw new ValidationException( + _("The calendar exception type not found")); + } + } + + private static final List getVersionsOrderedByExpiringDate( + List versions) { + + Collections.sort(versions, new Comparator() { + + @Override + public int compare(CalendarData o1, CalendarData o2) { + if (o1.getExpiringDate() == null) { + return 1; + } + if (o2.getExpiringDate() == null) { + return -1; + } + return o1.getExpiringDate().compareTo(o2.getExpiringDate()); + } + }); + return versions; + } + + public static XMLGregorianCalendar toXMLGregorianCalendar( + LocalDate localDate) throws DatatypeConfigurationException { + DatatypeFactory factory = DatatypeFactory.newInstance(); + return factory.newXMLGregorianCalendarDate(localDate.getYear(), + localDate.getMonthOfYear(), localDate.getDayOfMonth(), + DatatypeConstants.FIELD_UNDEFINED); + } + + public static XMLGregorianCalendar toXMLGregorianCalendar(Date date) + throws DatatypeConfigurationException { + return toXMLGregorianCalendar(LocalDate.fromDateFields(date)); + } + public static LocalDate toLocalDate(XMLGregorianCalendar calendar) { + return new LocalDate(calendar.getYear(), calendar.getMonth(), calendar + .getDay()); } } \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarServiceREST.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarServiceREST.java index 7a9b02029..c90032836 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarServiceREST.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/calendars/impl/CalendarServiceREST.java @@ -22,7 +22,9 @@ package org.navalplanner.ws.calendars.impl; import java.util.List; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -32,6 +34,7 @@ import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.ws.calendars.api.BaseCalendarDTO; import org.navalplanner.ws.calendars.api.BaseCalendarListDTO; import org.navalplanner.ws.calendars.api.ICalendarService; +import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO; import org.navalplanner.ws.common.impl.GenericRESTService; import org.navalplanner.ws.common.impl.RecoverableErrorException; import org.navalplanner.ws.labels.api.ILabelService; @@ -67,14 +70,13 @@ public class CalendarServiceREST extends @Override protected BaseCalendar toEntity(BaseCalendarDTO entityDTO) throws ValidationException, RecoverableErrorException { - // TODO Auto-generated method stub - return null; + return CalendarConverter.toEntity(entityDTO); } @Override protected void updateEntity(BaseCalendar entity, BaseCalendarDTO entityDTO) throws ValidationException, RecoverableErrorException { - // TODO Auto-generated method stub + CalendarConverter.update(entity, entityDTO); } @@ -88,4 +90,11 @@ public class CalendarServiceREST extends return new BaseCalendarListDTO(toDTO(justBaseCalendars)); } + @Override + @POST + @Consumes("application/xml") + public InstanceConstraintViolationsListDTO addBaseCalendars( + BaseCalendarListDTO baseCalendraListDTO) { + return save(baseCalendraListDTO.baseCalendars); + } } \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/CalendarAvailabilityDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/CalendarAvailabilityDTO.java new file mode 100644 index 000000000..6c3b88457 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/CalendarAvailabilityDTO.java @@ -0,0 +1,62 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.resources.api; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlAttribute; + +import org.navalplanner.business.calendars.entities.CalendarAvailability; +import org.navalplanner.ws.common.api.IntegrationEntityDTO; + +/** + * DTO for {@link CalendarAvailability} entity. + * @author Susana Montes Pedreira + */ +public class CalendarAvailabilityDTO extends IntegrationEntityDTO { + + public final static String ENTITY_TYPE = "calendar-availability"; + + @XmlAttribute + public Date startDate; + + @XmlAttribute + public Date endDate; + + public CalendarAvailabilityDTO() { + } + + public CalendarAvailabilityDTO(String code, Date startDate, Date endDate) { + super(code); + this.startDate = startDate; + this.endDate = endDate; + } + + public CalendarAvailabilityDTO(Date startDate, Date endDate) { + this(generateCode(), startDate, endDate); + } + + @Override + public String getEntityType() { + return ENTITY_TYPE; + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceCalendarDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceCalendarDTO.java new file mode 100644 index 000000000..238f15b69 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceCalendarDTO.java @@ -0,0 +1,77 @@ +/* + * This file is part of NavalPlan + * + * 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.ws.resources.api; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + +import org.navalplanner.business.calendars.entities.ResourceCalendar; +import org.navalplanner.ws.calendars.api.BaseCalendarDTO; +import org.navalplanner.ws.calendars.api.CalendarDataDTO; +import org.navalplanner.ws.calendars.api.CalendarExceptionDTO; + +/** + * DTO for {@link ResourceCalendar} entity. + * @author Susana Montes Pedreira + */ +public class ResourceCalendarDTO extends BaseCalendarDTO { + + public final static String ENTITY_TYPE = "resource-calendar"; + + @XmlAttribute + public Integer capacity; + + @XmlElementWrapper(name = "calendar-availability-list") + @XmlElement(name = "calendar-availability") + public List calendarAvailabilityDTOs = new ArrayList(); + + public ResourceCalendarDTO() { + } + + public ResourceCalendarDTO(String code, String name, String parent, + Integer capacity, + List calendarExceptions, + List calendarDatas, + List calendarAvailabilityDTOs) { + super(code, name, parent, calendarExceptions, calendarDatas); + this.capacity = capacity; + this.calendarAvailabilityDTOs = calendarAvailabilityDTOs; + } + + public ResourceCalendarDTO(String name, String parent, Integer capacity, + List calendarExceptions, + List calendarDatas, + List calendarAvailabilityDTOs) { + this(generateCode(), name, parent, capacity, calendarExceptions, + calendarDatas, + calendarAvailabilityDTOs); + } + + @Override + public String getEntityType() { + return ENTITY_TYPE; + } + +} \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceDTO.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceDTO.java index a7ba4656d..c87a412ac 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceDTO.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/api/ResourceDTO.java @@ -23,7 +23,6 @@ package org.navalplanner.ws.resources.api; import java.util.ArrayList; import java.util.List; -import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; @@ -36,8 +35,8 @@ import org.navalplanner.ws.common.api.IntegrationEntityDTO; */ public abstract class ResourceDTO extends IntegrationEntityDTO { - @XmlAttribute(name="calendar-name") - public String calendarName; + @XmlElement(name = "calendar") + public ResourceCalendarDTO calendar; @XmlElementWrapper(name="criterion-satisfaction-list") @XmlElement(name="criterion-satisfaction") diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java index 685a8bce5..451a8b520 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/ws/resources/impl/ResourceConverter.java @@ -28,6 +28,8 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.navalplanner.business.calendars.entities.CalendarAvailability; +import org.navalplanner.business.calendars.entities.ResourceCalendar; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.MultipleInstancesException; import org.navalplanner.business.common.exceptions.ValidationException; @@ -37,10 +39,14 @@ import org.navalplanner.business.resources.entities.CriterionType; import org.navalplanner.business.resources.entities.Machine; import org.navalplanner.business.resources.entities.Resource; import org.navalplanner.business.resources.entities.Worker; +import org.navalplanner.ws.calendars.api.BaseCalendarDTO; +import org.navalplanner.ws.calendars.impl.CalendarConverter; import org.navalplanner.ws.common.impl.InstanceNotFoundRecoverableErrorException; import org.navalplanner.ws.common.impl.RecoverableErrorException; +import org.navalplanner.ws.resources.api.CalendarAvailabilityDTO; import org.navalplanner.ws.resources.api.CriterionSatisfactionDTO; import org.navalplanner.ws.resources.api.MachineDTO; +import org.navalplanner.ws.resources.api.ResourceCalendarDTO; import org.navalplanner.ws.resources.api.ResourceDTO; import org.navalplanner.ws.resources.api.ResourcesCostCategoryAssignmentDTO; import org.navalplanner.ws.resources.api.WorkerDTO; @@ -49,8 +55,8 @@ import org.navalplanner.ws.resources.criterion.api.CriterionTypeDTO; /** * Converter from/to resource-related entities to/from DTOs. - * * @author Fernando Bellas Permuy + * @author Susana Montes Pedreira */ public class ResourceConverter { @@ -79,7 +85,7 @@ public class ResourceConverter { addCriterionSatisfactions(resource, resourceDTO.criterionSatisfactions); - setResourceCalendar(resource, resourceDTO.calendarName); + setResourceCalendar(resource, resourceDTO.calendar); addResourcesCostCategoryAssignments(resource, resourceDTO.resourcesCostCategoryAssignments); @@ -95,7 +101,7 @@ public class ResourceConverter { updateBasicData(resource, resourceDTO); - updateResourceCalendar(resource, resourceDTO.calendarName); + updateResourceCalendar(resource, resourceDTO.calendar); updateCriterionSatisfactions(resource, resourceDTO.criterionSatisfactions); @@ -178,19 +184,49 @@ public class ResourceConverter { } private static void setResourceCalendar(Resource resource, - String calendarName) { - - try { - resource.setResourceCalendar(StringUtils.trim(calendarName)); - } catch (InstanceNotFoundException e) { - throw new InstanceNotFoundRecoverableErrorException( - RESOURCE_CALENDAR_ENTITY_TYPE, e.getKey().toString()); - } catch (MultipleInstancesException e) { - throw new ValidationException( - _("there exist multiple resource calendars with name {0}", - calendarName)); + ResourceCalendarDTO calendar) { + String calendarCode = null; + if (calendar != null) { + calendarCode = calendar.parent; } + try { + resource.setResourceCalendar(StringUtils.trim(calendarCode)); + + // Copy the data of the resource calendar DTO + updateBasicPropertiesResourceCalendar(calendar, resource + .getCalendar()); + + } catch (InstanceNotFoundException e) { + throw new InstanceNotFoundRecoverableErrorException( + RESOURCE_CALENDAR_ENTITY_TYPE, e.getKey().toString()); + } catch (MultipleInstancesException e) { + throw new ValidationException(_( + "there exist multiple resource calendars with name {0}", + calendarCode)); + } + } + + private static void updateBasicPropertiesResourceCalendar( + ResourceCalendarDTO calendarDTO, ResourceCalendar calendar) { + if (calendarDTO != null) { + + if (!StringUtils.isBlank(calendarDTO.name)) { + calendar.setName(calendarDTO.name); + } + + if (!StringUtils.isBlank(calendarDTO.code)) { + calendar.setCode(calendarDTO.code); + } else { + throw new ValidationException( + _("missing code in the resource calendar")); + } + + if (calendarDTO.capacity != null) { + calendar.setCapacity(calendarDTO.capacity); + } + + } } private static void addResourcesCostCategoryAssignments( @@ -266,7 +302,7 @@ public class ResourceConverter { private static void updateResourceCalendar(Resource resource, - String calendarName) { + ResourceCalendarDTO calendarDTO) { // TODO. Decide policy to update calendar (e.g. previous calendar must // be removed?, if new calendar is the same as previous, must be @@ -407,6 +443,9 @@ public class ResourceConverter { } resourceDTO.resourcesCostCategoryAssignments = resourcesCostCategoryAssignmentDTOs; + ResourceCalendarDTO resourceCalendarDTO = toDTO(resource.getCalendar()); + resourceDTO.calendar = resourceCalendarDTO; + return resourceDTO; } @@ -444,4 +483,36 @@ public class ResourceConverter { initDate, endDate); } + public static ResourceCalendarDTO toDTO(ResourceCalendar calendar) { + + BaseCalendarDTO baseCalendarDTO = CalendarConverter.toDTO(calendar); + + List calendarAvailabilityDTOs = new ArrayList(); + for (CalendarAvailability calendarAvailability : calendar + .getCalendarAvailabilities()) { + calendarAvailabilityDTOs.add(toDTO(calendarAvailability)); + } + + return new ResourceCalendarDTO(baseCalendarDTO.code, + baseCalendarDTO.name, baseCalendarDTO.parent, calendar + .getCapacity(), baseCalendarDTO.calendarExceptions, + baseCalendarDTO.calendarDatas, calendarAvailabilityDTOs); + + } + + private static CalendarAvailabilityDTO toDTO( + CalendarAvailability calendarAvailability) { + + Date startDate = calendarAvailability.getStartDate() + .toDateTimeAtStartOfDay().toDate(); + + Date endDate = null; + if (calendarAvailability.getEndDate() != null) { + endDate = calendarAvailability.getEndDate() + .toDateTimeAtStartOfDay().toDate(); + } + + return new CalendarAvailabilityDTO(calendarAvailability.getCode(), + startDate, endDate); + } } \ No newline at end of file diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/basecalendars/BaseCalendarServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/basecalendars/BaseCalendarServiceTest.java new file mode 100644 index 000000000..39a7fcfff --- /dev/null +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/basecalendars/BaseCalendarServiceTest.java @@ -0,0 +1,348 @@ +/* + * This file is part of NavalPlan + * + * 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.web.test.ws.basecalendars; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; +import static org.navalplanner.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE; +import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE; +import static org.navalplanner.web.test.ws.common.Util.getUniqueName; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.hibernate.SessionFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; +import org.navalplanner.business.calendars.daos.ICalendarDataDAO; +import org.navalplanner.business.calendars.daos.ICalendarExceptionDAO; +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.CalendarExceptionType; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.IOnTransaction; +import org.navalplanner.business.common.daos.IConfigurationDAO; +import org.navalplanner.business.common.entities.IConfigurationBootstrap; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.ws.calendarexceptiontypes.api.ICalendarExceptionTypeService; +import org.navalplanner.ws.calendars.api.BaseCalendarDTO; +import org.navalplanner.ws.calendars.api.BaseCalendarListDTO; +import org.navalplanner.ws.calendars.api.CalendarDataDTO; +import org.navalplanner.ws.calendars.api.CalendarExceptionDTO; +import org.navalplanner.ws.calendars.api.HoursPerDayDTO; +import org.navalplanner.ws.calendars.api.ICalendarService; +import org.navalplanner.ws.calendars.impl.CalendarConverter; +import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +/** + * Tests for ICalendarService. + * @author Susana Montes Pedreira + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, + WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE }) +@Transactional + +public class BaseCalendarServiceTest { + + @Autowired + private ICalendarService calendarService; + + @Autowired + private IBaseCalendarDAO baseCalendarDAO; + + @Autowired + private ICalendarExceptionDAO calendarExceptionDAO; + + @Autowired + private ICalendarExceptionTypeService calendarExceptionTypeService; + + @Autowired + private ICalendarExceptionTypeDAO calendarExceptionTypeDAO; + + @Autowired + private IConfigurationDAO configurationDAO; + + @Autowired + private ICalendarDataDAO calendarDataDAO; + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + private IAdHocTransactionService transactionService; + + @Autowired + private IConfigurationBootstrap configurationBootstrap; + + private final String typeCode = "TypeCode_A"; + + @Before + public void loadConfiguration() { + + IOnTransaction load = new IOnTransaction() { + + @Override + public Void execute() { + configurationBootstrap.loadRequiredData(); + return null; + } + }; + + transactionService.runOnAnotherTransaction(load); + + } + + @Test + @Rollback(false) + public void givenCalendarExceptionTypeStored() { + CalendarExceptionType calendarExceptionType = CalendarExceptionType + .create("name", "color", false); + calendarExceptionType.setCode(typeCode); + + calendarExceptionTypeDAO.save(calendarExceptionType); + calendarExceptionTypeDAO.flush(); + sessionFactory.getCurrentSession().evict(calendarExceptionType); + calendarExceptionType.dontPoseAsTransientObjectAnymore(); + + } + + private Date getValidDate(int day) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + + calendar.add(calendar.MONTH, 1); + calendar.add(calendar.DAY_OF_MONTH, day); + + int date = calendar.get(Calendar.DAY_OF_MONTH); + int month = calendar.get(calendar.MONTH); + int year = calendar.get(Calendar.YEAR); + + calendar.set(year, month, date); + return calendar.getTime(); + } + + private Date getInvalidDate() { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + + int date = calendar.get(Calendar.DAY_OF_MONTH); + int month = calendar.get(calendar.MONTH) - 1; + int year = calendar.get(Calendar.YEAR); + + calendar.set(year, month, date); + return calendar.getTime(); + } + + private XMLGregorianCalendar toXml(Date date) { + try { + return CalendarConverter.toXMLGregorianCalendar(date); + } catch (DatatypeConfigurationException e) { + return null; + } + } + + @Test + public void testAddValidBaseCalendar() { + + /* Build valid base calendar "bc1" (5 constraint violations). */ + /* Build a calendar exception */ + CalendarExceptionDTO exceptionDTO_1 = new CalendarExceptionDTO( + getUniqueName(), toXml(getValidDate(0)), new Integer(7), + typeCode); + + CalendarExceptionDTO exceptionDTO_2 = new CalendarExceptionDTO( + getUniqueName(), toXml(getValidDate(1)), new Integer(7), + typeCode); + + List calendarExceptions = new ArrayList(); + calendarExceptions.add(exceptionDTO_1); + calendarExceptions.add(exceptionDTO_2); + + /* Build a calendar data */ + HoursPerDayDTO hoursPerDayDTO_1 = new HoursPerDayDTO(CalendarData.Days.FRIDAY.name(), new Integer(4)); + HoursPerDayDTO hoursPerDayDTO_2 = new HoursPerDayDTO(CalendarData.Days.TUESDAY.name(), new Integer(4)); + List listHoursPerDayDTO = new ArrayList(); + listHoursPerDayDTO.add(hoursPerDayDTO_1); + listHoursPerDayDTO.add(hoursPerDayDTO_2); + + /* missing code,date, hoursPerDays and parent */ + CalendarDataDTO dataDTO_1 = new CalendarDataDTO(null, null, null); + CalendarDataDTO dataDTO_2 = new CalendarDataDTO("codeData", + listHoursPerDayDTO, toXml(getValidDate(4)), + getDefaultCalendar() + .getCode()); + + List calendarDatas = new ArrayList(); + calendarDatas.add(dataDTO_1); + calendarDatas.add(dataDTO_2); + + /* Build Base Calendar list. */ + BaseCalendarDTO bc1 = new BaseCalendarDTO(getUniqueName(), + getUniqueName(), null, calendarExceptions, + new ArrayList()); + + String codeBaseCalendar = getUniqueName(); + BaseCalendarDTO bc2 = new BaseCalendarDTO(codeBaseCalendar, + getUniqueName(), null, null, calendarDatas); + + BaseCalendarListDTO baseCalendars = createBaseCalendarListDTO(bc1, bc2); + + List instanceConstraintViolationsList = calendarService + .addBaseCalendars(baseCalendars).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 0); + + try{ + BaseCalendar baseCalendar = baseCalendarDAO + .findByCode(codeBaseCalendar); + assertTrue(baseCalendar.getExceptions().isEmpty()); + assertTrue(baseCalendar.getCalendarDataVersions().size() == 2); + + CalendarData data = baseCalendar.getCalendarDataByCode("codeData"); + assertTrue(data.getHours(CalendarData.Days.FRIDAY) == 4); + assertTrue(data.getHours(CalendarData.Days.TUESDAY) == 4); + }catch(InstanceNotFoundException e){ + fail(); + } catch (NullPointerException o) { + fail(); + } + } + + @Test + public void testAddInvalidBaseCalendar() throws InstanceNotFoundException { + /* Build valid base calendar "bc1" (5 constraint violations). */ + /* Build two calendar exception with the same date */ + CalendarExceptionDTO exceptionDTO_1 = new CalendarExceptionDTO( + getUniqueName(), toXml(getValidDate(0)), new Integer(7), + typeCode); + + CalendarExceptionDTO exceptionDTO_2 = new CalendarExceptionDTO( + getUniqueName(), toXml(getValidDate(0)), new Integer(7), + typeCode); + + /* Build two calendar exception with the past date */ + CalendarExceptionDTO exceptionDTO_3 = new CalendarExceptionDTO( + getUniqueName(), toXml(getInvalidDate()), new Integer(7), + typeCode); + + /* Build two calendar exception with the invalid type */ + CalendarExceptionDTO exceptionDTO_4 = new CalendarExceptionDTO( + getUniqueName(), toXml(getInvalidDate()), new Integer(7), + "InvalidType"); + + List calendarExceptions = new ArrayList(); + calendarExceptions.add(exceptionDTO_1); + calendarExceptions.add(exceptionDTO_2); + calendarExceptions.add(exceptionDTO_3); + calendarExceptions.add(exceptionDTO_4); + + /* Build Base Calendar list. */ + BaseCalendarDTO bc1 = new BaseCalendarDTO(getUniqueName(), + getUniqueName(), null, calendarExceptions, + new ArrayList()); + + BaseCalendarListDTO baseCalendars = createBaseCalendarListDTO(bc1); + + List instanceConstraintViolationsList = calendarService + .addBaseCalendars(baseCalendars).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + + } + + @Test + public void testAddInvalidCalendarData() { + /* Build a calendar data */ + HoursPerDayDTO hoursPerDayDTO_1 = new HoursPerDayDTO("XXX", + new Integer(4)); + List listHoursPerDayDTO = new ArrayList(); + listHoursPerDayDTO.add(hoursPerDayDTO_1); + + /* missing code,date, hoursPerDays and parent */ + CalendarDataDTO dataDTO_2 = new CalendarDataDTO("codeData_2", + listHoursPerDayDTO, toXml(getInvalidDate()), + getDefaultCalendar() + .getCode()); + + List calendarDatas = new ArrayList(); + calendarDatas.add(dataDTO_2); + + String codeBaseCalendar = getUniqueName(); + BaseCalendarDTO bc2 = new BaseCalendarDTO(codeBaseCalendar, + getUniqueName(), null, null, calendarDatas); + + BaseCalendarListDTO baseCalendars = createBaseCalendarListDTO(bc2); + + List instanceConstraintViolationsList = calendarService + .addBaseCalendars(baseCalendars).instanceConstraintViolationsList; + + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 1); + } + + private BaseCalendarListDTO createBaseCalendarListDTO( + BaseCalendarDTO... calendarDTOs) { + + List baseCalendarList = new ArrayList(); + + for (BaseCalendarDTO c : calendarDTOs) { + baseCalendarList.add(c); + } + + return new BaseCalendarListDTO(baseCalendarList); + + } + + private BaseCalendar getDefaultCalendar() { + + IOnTransaction find = new IOnTransaction() { + + @Override + public BaseCalendar execute() { + BaseCalendar defaultCalendar = configurationDAO + .getConfiguration().getDefaultCalendar(); + defaultCalendar.getCode(); + return defaultCalendar; + } + }; + + return transactionService.runOnAnotherTransaction(find); + + } + +} diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java index fdf10f095..990b2d69e 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/materials/MaterialServiceTest.java @@ -40,6 +40,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.navalplanner.business.IDataBootstrap; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.IOnTransaction; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.materials.bootstrap.UnitTypeBootstrap; import org.navalplanner.business.materials.daos.IMaterialCategoryDAO; @@ -72,6 +74,9 @@ public class MaterialServiceTest { @Autowired private SessionFactory sessionFactory; + @Autowired + private IAdHocTransactionService transactionService; + @Autowired private IMaterialService materialService; @@ -94,6 +99,22 @@ public class MaterialServiceTest { private String unitTypeCodeB = "unitTypeCodeB"; + @Before + public void loadRequiredaData() { + IOnTransaction load = new IOnTransaction() { + + @Override + public Void execute() { + materialCategoryBootstrap.loadRequiredData(); + unitTypeBootstrap.loadRequiredData(); + return null; + } + }; + + transactionService.runOnAnotherTransaction(load); + + } + @Test @Rollback(false) public void CreateUnitType() { @@ -106,12 +127,6 @@ public class MaterialServiceTest { sessionFactory.getCurrentSession().evict(entityB); } - @Before - public void loadRequiredaData() { - materialCategoryBootstrap.loadRequiredData(); - unitTypeBootstrap.loadRequiredData(); - } - @Test public void testAddAndGetMaterialCategories() { /* Build materialCategory (0 constraint violations). */ diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java index 94f8f4b6c..f9cbbadbb 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/resources/api/ResourceServiceTest.java @@ -47,6 +47,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; import org.navalplanner.business.calendars.entities.BaseCalendar; +import org.navalplanner.business.calendars.entities.ResourceCalendar; import org.navalplanner.business.common.IAdHocTransactionService; import org.navalplanner.business.common.IOnTransaction; import org.navalplanner.business.common.daos.IConfigurationDAO; @@ -69,10 +70,12 @@ import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO; import org.navalplanner.ws.resources.api.CriterionSatisfactionDTO; import org.navalplanner.ws.resources.api.IResourceService; import org.navalplanner.ws.resources.api.MachineDTO; +import org.navalplanner.ws.resources.api.ResourceCalendarDTO; import org.navalplanner.ws.resources.api.ResourceDTO; import org.navalplanner.ws.resources.api.ResourceListDTO; import org.navalplanner.ws.resources.api.ResourcesCostCategoryAssignmentDTO; import org.navalplanner.ws.resources.api.WorkerDTO; +import org.navalplanner.ws.resources.impl.ResourceConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -488,33 +491,40 @@ public class ResourceServiceTest { @Test public void testAddResourceWithSpecificCalendar() { - /* Create a base calendar. */ + /* Create a resource calendar DTO. */ BaseCalendar baseCalendar = createBaseCalendar(); + ResourceCalendar resourceCalendar = baseCalendar + .newDerivedResourceCalendar(); + ResourceCalendarDTO resourceCalendarDTO = ResourceConverter + .toDTO(resourceCalendar); /* Create a machine DTO. */ MachineDTO machineDTO = new MachineDTO("name", "desc"); - machineDTO.calendarName = - ' ' + baseCalendar.getName().toUpperCase() + ' '; + machineDTO.calendar = resourceCalendarDTO; /* Test. */ - assertNoConstraintViolations(resourceService. - addResources(createResourceListDTO(machineDTO))); + assertNoConstraintViolations(resourceService + .addResources(createResourceListDTO(machineDTO))); Machine machine = machineDAO.findExistingEntityByCode(machineDTO.code); - assertEquals(baseCalendar.getId(), - machine.getCalendar().getParent().getId()); + assertEquals(baseCalendar.getId(), machine.getCalendar().getParent() + .getId()); } @Test public void testAddResourceWithNonExistentCalendar() { + /* Create invalid calendar */ + ResourceCalendarDTO calendarDTO = new ResourceCalendarDTO("", + "ParentNoExist", null, + null, null, null); /* Create a machine DTO. */ MachineDTO machineDTO = new MachineDTO("name", "desc"); - machineDTO.calendarName = getUniqueName(); + machineDTO.calendar = calendarDTO; /* Test. */ - assertOneRecoverableError(resourceService. - addResources(createResourceListDTO(machineDTO))); + assertOneRecoverableError(resourceService + .addResources(createResourceListDTO(machineDTO))); assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @@ -527,57 +537,54 @@ public class ResourceServiceTest { /* Create resource DTOs. */ MachineDTO m1 = new MachineDTO("name", "desc"); - ResourcesCostCategoryAssignmentDTO a1m1 = - new ResourcesCostCategoryAssignmentDTO( - ' ' + costCategory.getName().toUpperCase() + ' ', - getDate(2001, 1, 1), null); + ResourcesCostCategoryAssignmentDTO a1m1 = new ResourcesCostCategoryAssignmentDTO( + ' ' + costCategory.getName().toUpperCase() + ' ', getDate(2001, + 1, 1), null); m1.resourcesCostCategoryAssignments.add(a1m1); - m1.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - costCategory.getName(), - getDate(2000, 1, 1), getDate(2000, 4, 1))); + m1.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO(costCategory + .getName(), getDate(2000, 1, 1), getDate(2000, 4, 1))); MachineDTO m2 = new MachineDTO("name", "desc"); - m2.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO(a1m1.code, - costCategory.getName().toUpperCase(), - getDate(2001, 1, 1), null)); // Repeated assignment code - // (used by another machine). - m2.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO(null, - costCategory.getName().toUpperCase(), - getDate(2000, 1, 1), getDate(2000, 4, 1))); // Missing - // assignment code. + m2.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO(a1m1.code, + costCategory.getName().toUpperCase(), getDate(2001, 1, + 1), null)); // Repeated assignment code + // (used by another machine). + m2.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO(null, costCategory + .getName().toUpperCase(), getDate(2000, 1, 1), getDate( + 2000, 4, 1))); // Missing + // assignment code. MachineDTO m3 = new MachineDTO("name", "desc"); - ResourcesCostCategoryAssignmentDTO a1m3 = - new ResourcesCostCategoryAssignmentDTO(costCategory.getName(), - getDate(2001, 1, 1), null); + ResourcesCostCategoryAssignmentDTO a1m3 = new ResourcesCostCategoryAssignmentDTO( + costCategory.getName(), getDate(2001, 1, 1), null); m3.resourcesCostCategoryAssignments.add(a1m3); - m3.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - a1m3.code, // Repeated assignment code in this machine. - costCategory.getName(), - getDate(2000, 1, 1), getDate(2000, 4, 1))); + m3.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO(a1m3.code, // Repeated + // assignment + // code + // in + // this + // machine. + costCategory.getName(), getDate(2000, 1, 1), getDate( + 2000, 4, 1))); /* Test. */ - List instanceConstraintViolationsList = - resourceService.addResources(createResourceListDTO(m1, m2, m3)). - instanceConstraintViolationsList; + List instanceConstraintViolationsList = resourceService + .addResources(createResourceListDTO(m1, m2, m3)).instanceConstraintViolationsList; - assertTrue( - instanceConstraintViolationsList.toString(), - instanceConstraintViolationsList.size() == 2); - assertTrue( - instanceConstraintViolationsList.get(0). - constraintViolations.toString(), - instanceConstraintViolationsList.get(0). - constraintViolations.size() == 2); // m2 constraint violations. - assertTrue( - instanceConstraintViolationsList.get(1). - constraintViolations.toString(), - instanceConstraintViolationsList.get(1). - constraintViolations.size() == 1); // m3 constraint violations. + assertTrue(instanceConstraintViolationsList.toString(), + instanceConstraintViolationsList.size() == 2); + assertTrue(instanceConstraintViolationsList.get(0).constraintViolations + .toString(), + instanceConstraintViolationsList.get(0).constraintViolations + .size() == 2); // m2 constraint violations. + assertTrue(instanceConstraintViolationsList.get(1).constraintViolations + .toString(), + instanceConstraintViolationsList.get(1).constraintViolations + .size() == 1); // m3 constraint violations. assertTrue(resourceDAO.existsByCode(m1.code)); assertFalse(resourceDAO.existsByCode(m2.code)); @@ -589,13 +596,13 @@ public class ResourceServiceTest { /* Create a resource DTO. */ MachineDTO machineDTO = new MachineDTO("name", "desc"); - machineDTO.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - "", null, getDate(2000, 1, 1), null)); + machineDTO.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO("", null, getDate( + 2000, 1, 1), null)); /* Test. */ - assertOneConstraintViolation( - resourceService.addResources(createResourceListDTO(machineDTO))); + assertOneConstraintViolation(resourceService + .addResources(createResourceListDTO(machineDTO))); assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @@ -605,13 +612,13 @@ public class ResourceServiceTest { /* Create a resource DTO. */ MachineDTO machineDTO = new MachineDTO("name", "desc"); - machineDTO.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - getUniqueName(), getDate(2000, 1, 1), null)); + machineDTO.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO(getUniqueName(), + getDate(2000, 1, 1), null)); /* Test. */ - assertOneRecoverableError( - resourceService.addResources(createResourceListDTO(machineDTO))); + assertOneRecoverableError(resourceService + .addResources(createResourceListDTO(machineDTO))); assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @@ -624,14 +631,14 @@ public class ResourceServiceTest { /* Create a resource DTO. */ MachineDTO machineDTO = new MachineDTO("name", "desc"); - machineDTO.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - costCategory.getName(), null, // Start date not specified. - getDate(2000, 1, 1))); + machineDTO.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO(costCategory + .getName(), null, // Start date not specified. + getDate(2000, 1, 1))); /* Test. */ - assertOneConstraintViolation( - resourceService.addResources(createResourceListDTO(machineDTO))); + assertOneConstraintViolation(resourceService + .addResources(createResourceListDTO(machineDTO))); assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @@ -644,14 +651,13 @@ public class ResourceServiceTest { /* Create a resource DTO. */ MachineDTO machineDTO = new MachineDTO("name", "desc"); - machineDTO.resourcesCostCategoryAssignments.add( - new ResourcesCostCategoryAssignmentDTO( - costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 1, 1))); + machineDTO.resourcesCostCategoryAssignments + .add(new ResourcesCostCategoryAssignmentDTO(costCategory + .getName(), getDate(2000, 2, 1), getDate(2000, 1, 1))); /* Test. */ - assertOneConstraintViolation( - resourceService.addResources(createResourceListDTO(machineDTO))); + assertOneConstraintViolation(resourceService + .addResources(createResourceListDTO(machineDTO))); assertFalse(resourceDAO.existsByCode(machineDTO.code)); } @@ -666,64 +672,53 @@ public class ResourceServiceTest { * Create a resource DTOs. Each resource contains one cost assignment * overlapping. */ - MachineDTO m1 = createMachineDTOWithTwoCostsAssignments( - "m1", costCategory.getName(), - getDate(2000, 1, 1), null, - getDate(2000, 2, 1), null); + MachineDTO m1 = createMachineDTOWithTwoCostsAssignments("m1", + costCategory.getName(), getDate(2000, 1, 1), null, getDate( + 2000, 2, 1), null); - MachineDTO m2 = createMachineDTOWithTwoCostsAssignments( - "m2", costCategory.getName(), - getDate(2000, 2, 1), null, - getDate(2000, 1, 1), getDate(2000, 3, 1)); + MachineDTO m2 = createMachineDTOWithTwoCostsAssignments("m2", + costCategory.getName(), getDate(2000, 2, 1), null, getDate( + 2000, 1, 1), getDate(2000, 3, 1)); - MachineDTO m3 = createMachineDTOWithTwoCostsAssignments( - "m3", costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 4, 1), - getDate(2000, 3, 1), null); + MachineDTO m3 = createMachineDTOWithTwoCostsAssignments("m3", + costCategory.getName(), getDate(2000, 2, 1), + getDate(2000, 4, 1), getDate(2000, 3, 1), null); - MachineDTO m4 = createMachineDTOWithTwoCostsAssignments( - "m4", costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 5, 1), - getDate(2000, 1, 1), getDate(2000, 3, 1)); + MachineDTO m4 = createMachineDTOWithTwoCostsAssignments("m4", + costCategory.getName(), getDate(2000, 2, 1), + getDate(2000, 5, 1), getDate(2000, 1, 1), getDate(2000, 3, 1)); - MachineDTO m5 = createMachineDTOWithTwoCostsAssignments( - "m5", costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 5, 1), - getDate(2000, 3, 1), getDate(2000, 4, 1)); + MachineDTO m5 = createMachineDTOWithTwoCostsAssignments("m5", + costCategory.getName(), getDate(2000, 2, 1), + getDate(2000, 5, 1), getDate(2000, 3, 1), getDate(2000, 4, 1)); - MachineDTO m6 = createMachineDTOWithTwoCostsAssignments( - "m6", costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 5, 1), - getDate(2000, 4, 1), getDate(2000, 6, 1)); + MachineDTO m6 = createMachineDTOWithTwoCostsAssignments("m6", + costCategory.getName(), getDate(2000, 2, 1), + getDate(2000, 5, 1), getDate(2000, 4, 1), getDate(2000, 6, 1)); - MachineDTO m7 = createMachineDTOWithTwoCostsAssignments( - "m7", costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 5, 1), - getDate(2000, 1, 1), getDate(2000, 2, 1)); + MachineDTO m7 = createMachineDTOWithTwoCostsAssignments("m7", + costCategory.getName(), getDate(2000, 2, 1), + getDate(2000, 5, 1), getDate(2000, 1, 1), getDate(2000, 2, 1)); - MachineDTO m8 = createMachineDTOWithTwoCostsAssignments( - "m8", costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 5, 1), - getDate(2000, 5, 1), getDate(2000, 6, 1)); + MachineDTO m8 = createMachineDTOWithTwoCostsAssignments("m8", + costCategory.getName(), getDate(2000, 2, 1), + getDate(2000, 5, 1), getDate(2000, 5, 1), getDate(2000, 6, 1)); - MachineDTO m9 = createMachineDTOWithTwoCostsAssignments( - "m9", costCategory.getName(), - getDate(2000, 2, 1), getDate(2000, 5, 1), - getDate(2000, 2, 1), getDate(2000, 5, 1)); + MachineDTO m9 = createMachineDTOWithTwoCostsAssignments("m9", + costCategory.getName(), getDate(2000, 2, 1), + getDate(2000, 5, 1), getDate(2000, 2, 1), getDate(2000, 5, 1)); /* Test. */ - ResourceListDTO resourceDTOs = createResourceListDTO( - m1, m2, m3, m4, m5, m6, m7, m8, m9); + ResourceListDTO resourceDTOs = createResourceListDTO(m1, m2, m3, m4, + m5, m6, m7, m8, m9); - assertOneConstraintViolationPerInstance( - resourceService.addResources(resourceDTOs), - resourceDTOs.resources.size()); + assertOneConstraintViolationPerInstance(resourceService + .addResources(resourceDTOs), resourceDTOs.resources.size()); for (ResourceDTO r : resourceDTOs.resources) { MachineDTO m = (MachineDTO) r; - assertFalse( - "Machine " + m.name + " not expected", - resourceDAO.existsByCode(((MachineDTO) r).code)); + assertFalse("Machine " + m.name + " not expected", resourceDAO + .existsByCode(((MachineDTO) r).code)); } } @@ -737,66 +732,61 @@ public class ResourceServiceTest { /* Create a machine DTO. */ MachineDTO m1 = new MachineDTO("name", "desc"); - CriterionSatisfactionDTO m1s1 = new CriterionSatisfactionDTO( - ct.getName(), "c1", getDate(2000, 1, 1), getDate(2000, 2, 1)); + CriterionSatisfactionDTO m1s1 = new CriterionSatisfactionDTO(ct + .getName(), "c1", getDate(2000, 1, 1), getDate(2000, 2, 1)); m1.criterionSatisfactions.add(m1s1); - ResourcesCostCategoryAssignmentDTO m1a1 = - new ResourcesCostCategoryAssignmentDTO(costCategory.getName(), - getDate(2000, 1, 1), getDate(2000, 2, 1)); + ResourcesCostCategoryAssignmentDTO m1a1 = new ResourcesCostCategoryAssignmentDTO( + costCategory.getName(), getDate(2000, 1, 1), + getDate(2000, 2, 1)); m1.resourcesCostCategoryAssignments.add(m1a1); /* Create a worker DTO. */ WorkerDTO w1 = new WorkerDTO(getUniqueName(), "surname", "nif"); - CriterionSatisfactionDTO w1s1 = new CriterionSatisfactionDTO( - ct.getName(), "c1", getDate(2000, 1, 1), getDate(2000, 2, 1)); + CriterionSatisfactionDTO w1s1 = new CriterionSatisfactionDTO(ct + .getName(), "c1", getDate(2000, 1, 1), getDate(2000, 2, 1)); w1.criterionSatisfactions.add(w1s1); - ResourcesCostCategoryAssignmentDTO w1a1 = - new ResourcesCostCategoryAssignmentDTO(costCategory.getName(), - getDate(2000, 1, 1), getDate(2000, 2, 1)); + ResourcesCostCategoryAssignmentDTO w1a1 = new ResourcesCostCategoryAssignmentDTO( + costCategory.getName(), getDate(2000, 1, 1), + getDate(2000, 2, 1)); w1.resourcesCostCategoryAssignments.add(w1a1); /* Add resources. */ - assertNoConstraintViolations( - resourceService.addResources(createResourceListDTO(m1, w1))); + assertNoConstraintViolations(resourceService + .addResources(createResourceListDTO(m1, w1))); /* - * Build DTOs for making the following update: - * - * + m1: update name, m1s1's start date, and add a new cost category - * assignment. - * + w1: update surname, w1a1's start date, and add a new criterion - * satisfaction. + * Build DTOs for making the following update: + m1: update name, m1s1's + * start date, and add a new cost category assignment. + w1: update + * surname, w1a1's start date, and add a new criterion satisfaction. */ - MachineDTO m1Updated = new MachineDTO(m1.code, "name" + "UPDATED", - null); + MachineDTO m1Updated = new MachineDTO(m1.code, "name" + "UPDATED", null); CriterionSatisfactionDTO m1s1Updated = new CriterionSatisfactionDTO( - m1s1.code, null, null, getDate(2000, 1, 2), null); + m1s1.code, null, null, getDate(2000, 1, 2), null); m1Updated.criterionSatisfactions.add(m1s1Updated); - ResourcesCostCategoryAssignmentDTO m1a2 = - new ResourcesCostCategoryAssignmentDTO(costCategory.getName(), - getDate(2000, 3, 1), getDate(2000, 4, 1)); + ResourcesCostCategoryAssignmentDTO m1a2 = new ResourcesCostCategoryAssignmentDTO( + costCategory.getName(), getDate(2000, 3, 1), + getDate(2000, 4, 1)); m1Updated.resourcesCostCategoryAssignments.add(m1a2); - WorkerDTO w1Updated = new WorkerDTO(w1.code, null, - "surname" + "UPDATED", null); - CriterionSatisfactionDTO w1s2 = new CriterionSatisfactionDTO( - ct.getName(), "c1", getDate(2000, 3, 1), getDate(2000, 4, 1)); + WorkerDTO w1Updated = new WorkerDTO(w1.code, null, "surname" + + "UPDATED", null); + CriterionSatisfactionDTO w1s2 = new CriterionSatisfactionDTO(ct + .getName(), "c1", getDate(2000, 3, 1), getDate(2000, 4, 1)); w1Updated.criterionSatisfactions.add(w1s2); - ResourcesCostCategoryAssignmentDTO w1a1Updated = - new ResourcesCostCategoryAssignmentDTO(w1a1.code, null, - getDate(2000, 2, 1), null); + ResourcesCostCategoryAssignmentDTO w1a1Updated = new ResourcesCostCategoryAssignmentDTO( + w1a1.code, null, getDate(2000, 2, 1), null); w1Updated.resourcesCostCategoryAssignments.add(w1a1Updated); /* Update resources and test. */ - assertNoConstraintViolations( - resourceService.addResources(createResourceListDTO(m1Updated, - w1Updated))); + assertNoConstraintViolations(resourceService + .addResources(createResourceListDTO(m1Updated, w1Updated))); /* Test machine update. */ Machine m1Entity = machineDAO.findByCode(m1.code); assertEquals(m1Updated.name, m1Entity.getName()); // Modified. - assertEquals(m1.description, m1Entity.getDescription()); //Not modified. + assertEquals(m1.description, m1Entity.getDescription()); // Not + // modified. assertTrue(m1s1Updated.startDate.equals(m1Entity .getCriterionSatisfactionByCode(m1s1.code).getStartDate())); assertTrue(m1s1.endDate.equals(m1Entity.getCriterionSatisfactionByCode( @@ -888,8 +878,7 @@ public class ResourceServiceTest { private BaseCalendar createBaseCalendar() { - IOnTransaction create = - new IOnTransaction() { + IOnTransaction create = new IOnTransaction() { @Override public BaseCalendar execute() { diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/subcontract/ReportAdvancesServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/subcontract/ReportAdvancesServiceTest.java index 39ef7e417..86286f91e 100644 --- a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/subcontract/ReportAdvancesServiceTest.java +++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/ws/subcontract/ReportAdvancesServiceTest.java @@ -47,6 +47,8 @@ import org.junit.runner.RunWith; import org.navalplanner.business.IDataBootstrap; import org.navalplanner.business.advance.entities.AdvanceMeasurement; import org.navalplanner.business.advance.entities.DirectAdvanceAssignment; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.IOnTransaction; import org.navalplanner.business.common.daos.IConfigurationDAO; import org.navalplanner.business.externalcompanies.daos.IExternalCompanyDAO; import org.navalplanner.business.externalcompanies.entities.ExternalCompany; @@ -76,6 +78,9 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class ReportAdvancesServiceTest { + @Autowired + private IAdHocTransactionService transactionService; + @Resource private IDataBootstrap defaultAdvanceTypesBootstrapListener; @@ -84,8 +89,18 @@ public class ReportAdvancesServiceTest { @Before public void loadRequiredaData() { - defaultAdvanceTypesBootstrapListener.loadRequiredData(); - configurationBootstrap.loadRequiredData(); + + IOnTransaction load = new IOnTransaction() { + + @Override + public Void execute() { + defaultAdvanceTypesBootstrapListener.loadRequiredData(); + configurationBootstrap.loadRequiredData(); + return null; + } + }; + + transactionService.runOnAnotherTransaction(load); } @Autowired diff --git a/scripts/rest-clients/calendars-sample.xml b/scripts/rest-clients/calendars-sample.xml new file mode 100644 index 000000000..c2494a1d0 --- /dev/null +++ b/scripts/rest-clients/calendars-sample.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/rest-clients/import-calendars.sh b/scripts/rest-clients/import-calendars.sh new file mode 100755 index 000000000..c3e707963 --- /dev/null +++ b/scripts/rest-clients/import-calendars.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +. ./rest-common-env.sh + +printf "Login name: " +read loginName +printf "Password: " +read password + +baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL +certificate=$DEVELOPMENT_CERTIFICATE + +for i in "$@" +do + if [ "$i" = "--prod" ]; then + baseServiceURL=$PRODUCTION_BASE_SERVICE_URL + certificate=$PRODUCTION_CERTIFICATE + else + file=$i + fi +done + +if [ "$file" = "" ]; then + printf "Missing file\n" 1>&2 + exit 1 +fi + +authorization=`./base64.sh $loginName:$password` + +curl -sv -X POST $certificate -d @$file \ + --header "Content-type: application/xml" \ + --header "Authorization: Basic $authorization" \ + $baseServiceURL/calendars | tidy -xml -i -q -utf8 diff --git a/scripts/rest-clients/resource-withCalendars-sample.xml b/scripts/rest-clients/resource-withCalendars-sample.xml new file mode 100644 index 000000000..6e1e27a98 --- /dev/null +++ b/scripts/rest-clients/resource-withCalendars-sample.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +