ItEr42S12CUImportacionRecursosProductivosItEr41S15: Support for importing resources with cost assignments.

Support for importing resources with cost assignments has been implemented. Many test cases have been implemented for checking all constraint violations in cost assigments (special care has been taken to check time interval overlappings). toString method has been implemented in constraint violation related DTOs to facilitate debuging in testing.
This commit is contained in:
Fernando Bellas Permuy 2010-01-08 12:56:00 +01:00 committed by Javier Moran Rua
parent 217f702d6f
commit d9f0a0ee51
23 changed files with 813 additions and 166 deletions

View file

@ -23,6 +23,7 @@ package org.navalplanner.business.common;
import org.navalplanner.business.advance.daos.IAdvanceTypeDAO;
import org.navalplanner.business.calendars.daos.IBaseCalendarDAO;
import org.navalplanner.business.common.daos.IConfigurationDAO;
import org.navalplanner.business.costcategories.daos.ICostCategoryDAO;
import org.navalplanner.business.costcategories.daos.ITypeOfWorkHoursDAO;
import org.navalplanner.business.externalcompanies.daos.IExternalCompanyDAO;
import org.navalplanner.business.labels.daos.ILabelDAO;
@ -107,7 +108,7 @@ public class Registry {
@Autowired
private IWorkerDAO workerDAO;
@Autowired
private IWorkReportLineDAO workReportLineDAO;
@ -120,6 +121,9 @@ public class Registry {
@Autowired
private IHoursGroupDAO hoursGroupDAO;
@Autowired
private ICostCategoryDAO costCategoryDAO;
private Registry() {
}
@ -206,4 +210,8 @@ public class Registry {
return getInstance().hoursGroupDAO;
}
public static ICostCategoryDAO getCostCategoryDAO() {
return getInstance().costCategoryDAO;
}
}

View file

@ -28,6 +28,7 @@ import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.joda.time.LocalDate;
import org.navalplanner.business.common.daos.GenericDAOHibernate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.costcategories.entities.CostCategory;
import org.navalplanner.business.costcategories.entities.HourCost;
import org.navalplanner.business.costcategories.entities.ResourcesCostCategoryAssignment;
@ -39,6 +40,7 @@ import org.springframework.transaction.annotation.Transactional;
/**
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
@Repository
@Scope(BeanDefinition.SCOPE_SINGLETON)
@ -56,6 +58,21 @@ public class CostCategoryDAO extends GenericDAOHibernate<CostCategory, Long>
return list;
}
@Override
public CostCategory findUniqueByName(String name)
throws InstanceNotFoundException {
Criteria c = getSession().createCriteria(CostCategory.class).
add(Restrictions.eq("name", name).ignoreCase());
CostCategory costCategory = (CostCategory) c.uniqueResult();
if (costCategory == null) {
throw new InstanceNotFoundException(name,
CostCategory.class.getName());
} else {
return costCategory;
}
}
@Transactional(readOnly = true)
public static BigDecimal getPriceByResourceDateAndHourType(
Resource resource,

View file

@ -23,13 +23,17 @@ package org.navalplanner.business.costcategories.daos;
import java.util.List;
import org.navalplanner.business.common.daos.IGenericDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.costcategories.entities.CostCategory;
/**
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
public interface ICostCategoryDAO extends IGenericDAO<CostCategory, Long> {
List<CostCategory> findActive();
CostCategory findUniqueByName(String name) throws InstanceNotFoundException;
}

View file

@ -20,26 +20,30 @@
package org.navalplanner.business.costcategories.entities;
import static org.navalplanner.business.i18n.I18nHelper._;
import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotNull;
import org.joda.time.LocalDate;
import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.exceptions.CreateUnvalidatedException;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.resources.entities.Resource;
/**
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
public class ResourcesCostCategoryAssignment extends BaseEntity {
@NotNull
private LocalDate initDate;
private LocalDate endDate;
@NotNull
private CostCategory costCategory;
@NotNull
private Resource resource;
// Default constructor, needed by Hibernate
@ -51,6 +55,39 @@ public class ResourcesCostCategoryAssignment extends BaseEntity {
return (ResourcesCostCategoryAssignment) create(new ResourcesCostCategoryAssignment());
}
public static ResourcesCostCategoryAssignment createUnvalidated(
String costCategoryName, Resource resource, LocalDate initDate,
LocalDate endDate) throws CreateUnvalidatedException {
/* Get CostCategory. */
if (StringUtils.isBlank(costCategoryName)) {
throw new CreateUnvalidatedException(
_("cost category name not specified"));
}
CostCategory costCategory = null;
try {
costCategory = Registry.getCostCategoryDAO().findUniqueByName(
StringUtils.trim(costCategoryName));
} catch (InstanceNotFoundException e) {
throw new CreateUnvalidatedException(
_("{0}: cost category does not exist", costCategoryName));
}
/* Create instance of ResourcesCostCategoryAssignment. */
ResourcesCostCategoryAssignment assignment =
create(new ResourcesCostCategoryAssignment());
assignment.initDate = initDate;
assignment.endDate = endDate;
assignment.costCategory = costCategory;
assignment.resource = resource;
return assignment;
}
@NotNull(message="cost assignment's start date not specified")
public LocalDate getInitDate() {
return initDate;
}
@ -67,6 +104,7 @@ public class ResourcesCostCategoryAssignment extends BaseEntity {
this.endDate = endDate;
}
@NotNull(message="cost assignment's category not specified")
public CostCategory getCostCategory() {
return costCategory;
}
@ -75,6 +113,7 @@ public class ResourcesCostCategoryAssignment extends BaseEntity {
this.costCategory = category;
}
@NotNull(message="cost assignment's resource not specified")
public Resource getResource() {
return resource;
}
@ -90,12 +129,25 @@ public class ResourcesCostCategoryAssignment extends BaseEntity {
}
}
@AssertTrue(message="The end date cannot be before the init date")
public boolean checkPositiveTimeInterval() {
@AssertTrue(message="cost assignment with end date less than start date")
public boolean checkConstraintPositiveTimeInterval() {
/* Check if it makes sense to check the constraint .*/
if (!isInitDateSpecified()) {
return true;
}
/* Check the constraint. */
if (endDate == null) {
return true;
}
return (endDate.isAfter(initDate) || initDate.equals(endDate));
}
public boolean isInitDateSpecified() {
return initDate != null;
}
}

View file

@ -67,7 +67,7 @@ public class CriterionTypeDAO extends GenericDAOHibernate<CriterionType, Long>
Criteria c = getSession().createCriteria(CriterionType.class);
c.add(Restrictions.eq("name", name));
c.add(Restrictions.eq("name", name).ignoreCase());
CriterionType criterionType = (CriterionType) c.uniqueResult();

View file

@ -116,8 +116,8 @@ public class CriterionSatisfaction extends BaseEntity {
/* Create instance of CriterionSatisfaction. */
CriterionSatisfaction criterionSatisfaction =
new CriterionSatisfaction();
criterionSatisfaction.setNewObject(true);
create(new CriterionSatisfaction());
criterionSatisfaction.criterion = criterion;
criterionSatisfaction.resource = resource;
criterionSatisfaction.startDate = startDate;

View file

@ -23,6 +23,7 @@ package org.navalplanner.business.resources.entities;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
@ -318,6 +319,12 @@ public class CriterionType extends BaseEntity implements
@AssertTrue(message="criterion type name is already being used")
public boolean checkConstraintUniqueCriterionTypeName() {
/* Check if it makes sense to check the constraint .*/
if (!isNameSpecified()) {
return true;
}
/* Check the constraint. */
ICriterionTypeDAO criterionTypeDAO = Registry.getCriterionTypeDAO();
if (isNewObject()) {
@ -365,4 +372,8 @@ public class CriterionType extends BaseEntity implements
}
private boolean isNameSpecified() {
return !StringUtils.isBlank(name);
}
}

View file

@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.Valid;
@ -43,14 +44,14 @@ public class Machine extends Resource {
configurationUnits.remove(unit);
}
public static Machine createUnvalidated(String code, String name, String description) {
public static Machine createUnvalidated(String code, String name,
String description) {
Machine machine = new Machine();
Machine machine = create(new Machine());
machine.code = code;
machine.name = name;
machine.description = description;
machine.setNewObject(true);
return machine;
@ -108,6 +109,13 @@ public class Machine extends Resource {
@AssertTrue(message="machine code has to be unique. It is already used")
public boolean checkConstraintUniqueCode() {
/* Check if it makes sense to check the constraint .*/
if (!isCodeSpecified()) {
return true;
}
/* Check the constraint. */
boolean result;
if (isNewObject()) {
result = !existsMachineWithTheCode();
@ -115,6 +123,11 @@ public class Machine extends Resource {
result = isIfExistsTheExistentMachineThisOne();
}
return result;
}
private boolean isCodeSpecified() {
return !StringUtils.isBlank(code);
}
private boolean existsMachineWithTheCode() {

View file

@ -51,14 +51,6 @@ import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.costcategories.entities.ResourcesCostCategoryAssignment;
import org.navalplanner.business.planner.entities.DayAssignment;
// FIXME: Alternatively, Resource can be modeled with the style:
// Resource.getParent() & Resource.getChilds(). This way, Resource does not
// depend on ResourceGroup. However, such an option allows combinations not
// semantically correct (e.g. a simple resource, such as Worker, could be the
// child another simple resource, general methods like getChilds() do not make
// sense for simple entities, etc.). In consequence, I prefer the modeling
// option shown below.
/**
* This class acts as the base class for all resources.
* @author Fernando Bellas Permuy <fbellas@udc.es>
@ -822,8 +814,26 @@ public abstract class Resource extends BaseEntity{
assignment.setResource(null);
}
@AssertFalse(message="Two assignments overlap in time")
public boolean checkAssignmentsOverlap() {
@AssertFalse(message="Some cost category assignments overlap in time")
public boolean checkConstraintAssignmentsOverlap() {
/*
* Check if time intervals in cost assignments are correct in isolation.
* If not, it does not make sense to check assignment overlapping.
*/
for (ResourcesCostCategoryAssignment i :
getResourcesCostCategoryAssignments()) {
if (!(i.isInitDateSpecified() &&
i.checkConstraintPositiveTimeInterval())) {
return false;
}
}
/*
* Check assignment overlapping.
*/
List<ResourcesCostCategoryAssignment> assignmentsList =
new ArrayList<ResourcesCostCategoryAssignment>();
assignmentsList.addAll(getResourcesCostCategoryAssignments());
@ -832,11 +842,6 @@ public abstract class Resource extends BaseEntity{
LocalDate endDate = assignmentsList.get(i).getEndDate();
for(int j=i+1; j<assignmentsList.size(); j++) {
ResourcesCostCategoryAssignment listElement = assignmentsList.get(j);
if (initDate == null || listElement.getInitDate() == null) {
//this is not exactly an overlapping but a
//problem with missing compulsory fields
return true;
}
if (endDate == null && listElement.getEndDate() == null) {
return true;
}
@ -845,22 +850,25 @@ public abstract class Resource extends BaseEntity{
return true;
}
else if((endDate != null && listElement.getEndDate() != null) &&
((listElement.getEndDate().compareTo(initDate)>=0 &&
listElement.getEndDate().compareTo(endDate)<=0) ||
(listElement.getInitDate().compareTo(initDate)>=0 &&
listElement.getInitDate().compareTo(endDate)<=0))) {
((listElement.getEndDate().compareTo(initDate)>=0 && // (1) listElement.getEndDate() inside [initDate, endDate]
listElement.getEndDate().compareTo(endDate)<=0) ||
(listElement.getInitDate().compareTo(initDate)>=0 && // (2) listElement.getInitDate() inside [initDate, endDate]
listElement.getInitDate().compareTo(endDate)<=0) ||
(listElement.getInitDate().compareTo(initDate)<=0 && // (3) [listElement.getInitDate(), listElement.getEndDate()]
listElement.getEndDate().compareTo(endDate)>=0))) { // contains [initDate, endDate]
return true;
}
}
}
return false;
}
public boolean isVirtual() {
return false;
}
@AssertTrue(message="there are criterion satisfactions referring to " +
@AssertTrue(message="there exist criterion satisfactions referring to " +
"criterion types not applicable to this resource")
public boolean checkConstraintCriterionSatisfactionsWithCorrectType() {

View file

@ -50,12 +50,11 @@ public class Worker extends Resource {
public static Worker createUnvalidated(String firstName, String surname,
String nif) {
Worker worker = new Worker();
Worker worker = create(new Worker());
worker.firstName = firstName;
worker.surname = surname;
worker.nif = nif;
worker.setNewObject(true);
return worker;
@ -131,14 +130,16 @@ public class Worker extends Resource {
@AssertTrue(message = "Worker with the same first name, surname and nif previously existed")
public boolean checkConstraintUniqueFirstName() {
if (!firstLevelValidationsPassed()) {
return true;
}
/* Check if it makes sense to check the constraint .*/
if (this instanceof VirtualWorker) {
return true;
}
if (!areFirstNameSurnameNifSpecified()) {
return true;
}
/* Check the constraint. */
List<Worker> list = Registry.getWorkerDAO()
.findByFirstNameSecondNameAndNifAnotherTransaction(firstName,
surname, nif);
@ -155,7 +156,7 @@ public class Worker extends Resource {
}
private boolean firstLevelValidationsPassed() {
private boolean areFirstNameSurnameNifSpecified() {
return !StringUtils.isBlank(firstName) &&
!StringUtils.isBlank(surname) &&

View file

@ -49,7 +49,7 @@
</set>
<!-- Inverse navigation from OrderElement to OrderLineGroup -->
<many-to-one name="parent" access="field" cascade="all"/>
<many-to-one name="parent" access="field" cascade="all" class="org.navalplanner.business.orders.entities.OrderLineGroup"/>
<one-to-one name="taskSource" class="TaskSource" access="field" property-ref="orderElement"/>
@ -113,7 +113,8 @@
</set>
<many-to-one name="parentOrderLine" column="PARENT_ORDER_LINE"
not-null="true" />
not-null="true"
class="org.navalplanner.business.orders.entities.OrderLine"/>
</class>

View file

@ -20,6 +20,9 @@
package org.navalplanner.ws.common.api;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.xml.bind.annotation.XmlAttribute;
/**
@ -29,10 +32,13 @@ import javax.xml.bind.annotation.XmlAttribute;
*/
public class ConstraintViolationDTO {
@XmlAttribute(name="field-name")
public final static String FIELD_NAME_ATTRIBUTE_NAME = "field-name";
public final static String MESSAGE_ATTRIBUTE_NAME = "message";
@XmlAttribute(name=FIELD_NAME_ATTRIBUTE_NAME)
public String fieldName;
@XmlAttribute
@XmlAttribute(name=MESSAGE_ATTRIBUTE_NAME)
public String message;
public ConstraintViolationDTO() {}
@ -42,4 +48,21 @@ public class ConstraintViolationDTO {
this.message = message;
}
@Override
public String toString() {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
if (fieldName != null) {
printWriter.print(FIELD_NAME_ATTRIBUTE_NAME + " = " + fieldName +
" - ");
}
printWriter.println(MESSAGE_ATTRIBUTE_NAME + " = " + message);
printWriter.close();
return stringWriter.toString();
}
}

View file

@ -20,6 +20,8 @@
package org.navalplanner.ws.common.api;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
@ -33,7 +35,9 @@ import javax.xml.bind.annotation.XmlElement;
*/
public class InstanceConstraintViolationsDTO {
@XmlAttribute(name="instance-id")
public final static String INSTANCE_ID_ATTRIBUTE_NAME = "instance-id";
@XmlAttribute(name=INSTANCE_ID_ATTRIBUTE_NAME)
public String instanceId;
@XmlElement(name="constraint-violation")
@ -62,4 +66,23 @@ public class InstanceConstraintViolationsDTO {
}
@Override
public String toString() {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
printWriter.println("** " + INSTANCE_ID_ATTRIBUTE_NAME + " = " +
instanceId + " **");
for (ConstraintViolationDTO i : constraintViolations) {
printWriter.println(i);
}
printWriter.close();
return stringWriter.toString();
}
}

View file

@ -20,6 +20,8 @@
package org.navalplanner.ws.common.api;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
@ -48,4 +50,25 @@ public class InstanceConstraintViolationsListDTO {
}
@Override
public String toString() {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
printWriter.println("*** " + this.getClass().getName() + " ***");
for (InstanceConstraintViolationsDTO i :
instanceConstraintViolationsList) {
printWriter.println(i);
}
printWriter.close();
return stringWriter.toString();
}
}

View file

@ -20,14 +20,12 @@
package org.navalplanner.ws.common.impl;
import java.util.Calendar;
import java.util.Date;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.joda.time.LocalDate;
/**
* A converter from <code>java.util.Date</code> to/from
* <code>javax.xml.datatype.XMLGregorianCalendar</code>.
@ -38,53 +36,6 @@ public class DateConverter {
private DateConverter() {}
/**
* It converts a <code>Date</code> to a <code>XMLGregorianCalendar</code>
* representing a <code>xsd:date</code> XML type. <br/><br/>
*
* If the date passed as a parameter is <code>null</code>, it also returns
* <code>null</code>.
*/
public final static XMLGregorianCalendar toXMLGregrorianCalendar(
Date date) {
if (date == null) {
return null;
}
Calendar dateAsCalendar = Calendar.getInstance();
dateAsCalendar.setTime(date);
XMLGregorianCalendar dateAsXMLGregorianCalendar = null;
try {
dateAsXMLGregorianCalendar =
DatatypeFactory.newInstance().newXMLGregorianCalendarDate(
dateAsCalendar.get(Calendar.YEAR),
convertMonthFieldFromCalendarToXMLGregorianCalendar(
dateAsCalendar.get(Calendar.MONTH)),
dateAsCalendar.get(Calendar.DAY_OF_MONTH),
DatatypeConstants.FIELD_UNDEFINED);
} catch (DatatypeConfigurationException e) {
throw new RuntimeException(e);
}
return dateAsXMLGregorianCalendar;
}
/**
* Converts from @{link Calendar} month field format to
* @{link XMLGregorianCalendar} format.
*
* It is needed the conversion because
* @{link XMLGregorianCalendar} months go from 1 to 12 while
* @{link Calendar} months go from 0 to 11
*
*/
private final static int convertMonthFieldFromCalendarToXMLGregorianCalendar(int month) {
return month+1;
}
/**
* It converts a <code>XMLGregorianCalendar</code> representing a
* <code>xsd:date</code> XML type to a <code>Date</code>.<br/><br/>
@ -102,4 +53,23 @@ public class DateConverter {
}
/**
* It converts a <code>XMLGregorianCalendar</code> representing a
* <code>xsd:date</code> XML type to a Joda's <code>LocalDate</code>.
* <br/><br/>
*
* If the date passed as a parameter is <code>null</code>, it also returns
* <code>null</code>.
*/
public final static LocalDate toLocalDate(XMLGregorianCalendar date) {
if (date == null) {
return null;
} else {
return new LocalDate(date.getYear(), date.getMonth(),
date.getDay());
}
}
}

View file

@ -20,14 +20,10 @@
package org.navalplanner.ws.resources.api;
import java.util.Date;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.datatype.XMLGregorianCalendar;
import org.navalplanner.ws.common.impl.DateConverter;
/**
* DTO for <code>CriterionSatisfaction</code> entity.
*
@ -45,19 +41,20 @@ public class CriterionSatisfactionDTO {
@XmlSchemaType(name="date")
public XMLGregorianCalendar startDate;
@XmlAttribute(name="finish-date")
@XmlAttribute(name="end-date")
@XmlSchemaType(name="date")
public XMLGregorianCalendar finishDate;
public XMLGregorianCalendar endDate;
public CriterionSatisfactionDTO() {}
public CriterionSatisfactionDTO(String criterionTypeName,
String criterionName, Date startDate, Date finishDate) {
public CriterionSatisfactionDTO(
String criterionTypeName, String criterionName,
XMLGregorianCalendar startDate, XMLGregorianCalendar endDate) {
this.criterionTypeName = criterionTypeName;
this.criterionName = criterionName;
this.startDate = DateConverter.toXMLGregrorianCalendar(startDate);
this.finishDate = DateConverter.toXMLGregrorianCalendar(finishDate);
this.startDate = startDate;
this.endDate = endDate;
}

View file

@ -42,4 +42,10 @@ public abstract class ResourceDTO {
public List<CriterionSatisfactionDTO> criterionSatisfactions =
new ArrayList<CriterionSatisfactionDTO>();
@XmlElementWrapper(name="resources-cost-category-assignment-list")
@XmlElement(name="resources-cost-category-assignment")
public List<ResourcesCostCategoryAssignmentDTO>
resourcesCostCategoryAssignments =
new ArrayList<ResourcesCostCategoryAssignmentDTO>();
}

View file

@ -0,0 +1,55 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.ws.resources.api;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* DTO for <code>ResourcesCostCategoryAssignment</code> entity.
*
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
public class ResourcesCostCategoryAssignmentDTO {
@XmlAttribute(name="cost-category-name")
public String costCategoryName;
@XmlAttribute(name="start-date")
@XmlSchemaType(name="date")
public XMLGregorianCalendar startDate;
@XmlAttribute(name="end-date")
@XmlSchemaType(name="date")
public XMLGregorianCalendar endDate;
public ResourcesCostCategoryAssignmentDTO() {}
public ResourcesCostCategoryAssignmentDTO(String costCategoryName,
XMLGregorianCalendar startDate, XMLGregorianCalendar endDate) {
this.costCategoryName = costCategoryName;
this.startDate = startDate;
this.endDate = endDate;
}
}

View file

@ -28,6 +28,7 @@ import org.apache.commons.lang.StringUtils;
import org.navalplanner.business.common.exceptions.CreateUnvalidatedException;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.MultipleInstancesException;
import org.navalplanner.business.costcategories.entities.ResourcesCostCategoryAssignment;
import org.navalplanner.business.resources.entities.CriterionSatisfaction;
import org.navalplanner.business.resources.entities.Machine;
import org.navalplanner.business.resources.entities.Resource;
@ -36,6 +37,7 @@ import org.navalplanner.ws.common.impl.DateConverter;
import org.navalplanner.ws.resources.api.CriterionSatisfactionDTO;
import org.navalplanner.ws.resources.api.MachineDTO;
import org.navalplanner.ws.resources.api.ResourceDTO;
import org.navalplanner.ws.resources.api.ResourcesCostCategoryAssignmentDTO;
import org.navalplanner.ws.resources.api.WorkerDTO;
/**
@ -65,6 +67,8 @@ public class ResourceConverter {
addCriterionSatisfactions(resource,
resourceDTO.criterionSatisfactions);
setResourceCalendar(resource, resourceDTO.calendarName);
addResourcesCostCategoryAssignments(resource,
resourceDTO.resourcesCostCategoryAssignments);
return resource;
@ -109,7 +113,7 @@ public class ResourceConverter {
StringUtils.trim(criterionSatisfactionDTO.criterionName),
resource,
DateConverter.toDate(criterionSatisfactionDTO.startDate),
DateConverter.toDate(criterionSatisfactionDTO.finishDate));
DateConverter.toDate(criterionSatisfactionDTO.endDate));
}
@ -129,4 +133,31 @@ public class ResourceConverter {
}
private static void addResourcesCostCategoryAssignments(
Resource resource, List<ResourcesCostCategoryAssignmentDTO>
resourcesCostCategoryAssignments)
throws CreateUnvalidatedException {
for (ResourcesCostCategoryAssignmentDTO assignmentDTO :
resourcesCostCategoryAssignments) {
ResourcesCostCategoryAssignment assignment = toEntity(assignmentDTO,
resource);
resource.addResourcesCostCategoryAssignment(assignment);
}
}
private static ResourcesCostCategoryAssignment toEntity(
ResourcesCostCategoryAssignmentDTO assignmentDTO, Resource resource)
throws CreateUnvalidatedException {
return ResourcesCostCategoryAssignment.createUnvalidated(
assignmentDTO.costCategoryName, resource,
DateConverter.toLocalDate(assignmentDTO.startDate),
DateConverter.toLocalDate(assignmentDTO.endDate));
}
}

View file

@ -29,10 +29,14 @@ import static org.navalplanner.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE;
import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -43,6 +47,8 @@ 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.business.costcategories.daos.ICostCategoryDAO;
import org.navalplanner.business.costcategories.entities.CostCategory;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.daos.IMachineDAO;
import org.navalplanner.business.resources.daos.IResourceDAO;
@ -61,6 +67,7 @@ import org.navalplanner.ws.resources.api.IResourceService;
import org.navalplanner.ws.resources.api.MachineDTO;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.NotTransactional;
@ -100,6 +107,9 @@ public class ResourceServiceTest {
@Autowired
private IBaseCalendarDAO baseCalendarDAO;
@Autowired
private ICostCategoryDAO costCategoryDAO;
@Autowired
private IConfigurationBootstrap configurationBootstrap;
@ -135,10 +145,18 @@ public class ResourceServiceTest {
resourceService.addResources(createResourceListDTO(m1, m2, w1, w2)).
instanceConstraintViolationsList;
assertTrue(instanceConstraintViolationsList.size() == 2);
assertTrue(instanceConstraintViolationsList.get(0).
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).
assertTrue(
instanceConstraintViolationsList.get(1).
constraintViolations.toString(),
instanceConstraintViolationsList.get(1).
constraintViolations.size() == 3); // w2 constraint violations.
machineDAO.findUniqueByCode(m1Code.trim());
assertTrue(
@ -208,10 +226,18 @@ public class ResourceServiceTest {
resourceService.addResources(createResourceListDTO(m1, m2, w1, w2)).
instanceConstraintViolationsList;
assertTrue(instanceConstraintViolationsList.size() == 2);
assertTrue(instanceConstraintViolationsList.get(0).
assertTrue(
instanceConstraintViolationsList.toString(),
instanceConstraintViolationsList.size() == 2);
assertTrue(
instanceConstraintViolationsList.get(0).
constraintViolations.toString(),
instanceConstraintViolationsList.get(0).
constraintViolations.size() == 1);
assertTrue(instanceConstraintViolationsList.get(1).
assertTrue(
instanceConstraintViolationsList.get(1).
constraintViolations.toString(),
instanceConstraintViolationsList.get(1).
constraintViolations.size() == 1);
machineDAO.findUniqueByCode(m1.code);
assertTrue(
@ -232,19 +258,22 @@ public class ResourceServiceTest {
MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc");
machineDTO.criterionSatisfactions.add(
new CriterionSatisfactionDTO(
' ' + ct.getName() + ' ', " c1 ", // Blank spaces intentionally
// added (OK).
Calendar.getInstance().getTime(), null));
' ' + ct.getName().toUpperCase() + // Upper case and blank
' ', " C1 ", // spaces intentionally
// added (OK).
getDate(2001, 1, 1), null));
machineDTO.criterionSatisfactions.add(
new CriterionSatisfactionDTO(ct.getName(), "c2",
Calendar.getInstance().getTime(), null));
getDate(2001, 1, 1), null));
/* Test. */
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
resourceService.addResources(createResourceListDTO(machineDTO)).
instanceConstraintViolationsList;
assertTrue(instanceConstraintViolationsList.isEmpty());
assertTrue(
instanceConstraintViolationsList.toString(),
instanceConstraintViolationsList.isEmpty());
Machine machine = findUniqueMachineByCodeInitialized(machineDTO.code);
assertTrue(machine.getCriterionSatisfactions().size() == 2);
@ -269,7 +298,7 @@ public class ResourceServiceTest {
MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc");
machineDTO.criterionSatisfactions.add(
new CriterionSatisfactionDTO(ct.getName() , "c1",
null, Calendar.getInstance().getTime())); // Missing start date.
null, getDate(2001, 1, 1))); // Missing start date.
/* Test. */
assertOneConstraintViolation(
@ -281,7 +310,7 @@ public class ResourceServiceTest {
@Test
@NotTransactional
public void testAddResourceWithCriterionSatisfactionsWithIncorrectType() {
public void testAddResourcesWithCriterionSatisfactionsWithIncorrectType() {
/* Create two criterion types. */
CriterionType machineCt = createCriterionType(ResourceEnum.MACHINE);
@ -291,11 +320,11 @@ public class ResourceServiceTest {
MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc");
machineDTO.criterionSatisfactions.add(
new CriterionSatisfactionDTO(workerCt.getName() , "c1",
Calendar.getInstance().getTime(), null)); // Incorrect type.
getDate(2001, 1, 1), null)); // Incorrect type.
WorkerDTO workerDTO = new WorkerDTO(getUniqueName(), "surname", "nif");
workerDTO.criterionSatisfactions.add(
new CriterionSatisfactionDTO(machineCt.getName() , "c1",
Calendar.getInstance().getTime(), null)); // Incorrect type.
getDate(2001, 1, 1), null)); // Incorrect type.
/* Test. */
assertOneConstraintViolation(
@ -311,53 +340,45 @@ public class ResourceServiceTest {
@Test
@NotTransactional
public void testAddResourceWithCriterionSatisfactionsWithIncorrectNames() {
public void testAddResourcesWithCriterionSatisfactionsWithIncorrectNames() {
/* Create a criterion type. */
CriterionType ct = createCriterionType();
/* Create machines DTOs. */
MachineDTO m1 = new MachineDTO(getUniqueName(), "name", "desc");
MachineDTO m1 = new MachineDTO(getUniqueName(), "m1", "desc");
m1.criterionSatisfactions.add(
new CriterionSatisfactionDTO("", "X", // Missing criterion type.
Calendar.getInstance().getTime(), null));
MachineDTO m2 = new MachineDTO(getUniqueName(), "name", "desc");
getDate(2001, 1, 1), null));
MachineDTO m2 = new MachineDTO(getUniqueName(), "m2", "desc");
m2.criterionSatisfactions.add(
new CriterionSatisfactionDTO(ct.getName(), // Missing criterion.
null, Calendar.getInstance().getTime(), null));
MachineDTO m3 = new MachineDTO(getUniqueName(), "name", "desc");
null, getDate(2001, 1, 1), null));
MachineDTO m3 = new MachineDTO(getUniqueName(), "m3", "desc");
m3.criterionSatisfactions.add(
new CriterionSatisfactionDTO(
ct.getName() + 'X', // Non-existent criterion type.
"c1", Calendar.getInstance().getTime(), null));
MachineDTO m4 = new MachineDTO(getUniqueName(), "name", "desc");
"c1", getDate(2001, 1, 1), null));
MachineDTO m4 = new MachineDTO(getUniqueName(), "m4", "desc");
m4.criterionSatisfactions.add(
new CriterionSatisfactionDTO(
ct.getName(),
"c1" + 'X', // Criterion name is not of ct's type.
Calendar.getInstance().getTime(), null));
getDate(2001, 1, 1), null));
/* Test. */
List<MachineDTO> machines = new ArrayList<MachineDTO>();
machines.add(m1);
machines.add(m2);
machines.add(m3);
machines.add(m4);
ResourceListDTO resourceDTOs = createResourceListDTO(m1, m2, m3, m4);
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
resourceService.addResources(new ResourceListDTO(machines)).
instanceConstraintViolationsList;
assertOneConstraintViolationPerInstance(
resourceService.addResources(resourceDTOs),
resourceDTOs.resources.size());
assertTrue(instanceConstraintViolationsList.size() == machines.size());
for (InstanceConstraintViolationsDTO i :
instanceConstraintViolationsList) {
assertTrue(i.constraintViolations.size() == 1);
}
for (MachineDTO m : machines) {
for (ResourceDTO r : resourceDTOs.resources) {
MachineDTO m = (MachineDTO) r;
assertFalse(
machineDAO.existsMachineWithCodeInAnotherTransaction(m.code));
"Machine " + m.name + " not expected",
machineDAO.existsMachineWithCodeInAnotherTransaction(
((MachineDTO) r).code));
}
}
@ -418,6 +439,183 @@ public class ResourceServiceTest {
}
@Test
@NotTransactional
public void testAddResourceWithCostAssignments() {
/* Create a CostCategory. */
CostCategory costCategory = createCostCategory();
/* Create resource DTOs. */
MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc");
machineDTO.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
' ' + costCategory.getName().toUpperCase() + ' ',
getDate(2001, 1, 1), null));
machineDTO.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
costCategory.getName(),
getDate(2000, 1, 1), getDate(2000, 4, 1)));
/* Test. */
assertNoConstraintViolations(
resourceService.addResources(createResourceListDTO(machineDTO)));
assertTrue(machineDAO.existsMachineWithCodeInAnotherTransaction(
machineDTO.code));
}
@Test
@NotTransactional
public void testAddResourcesWithCostAssignmentWithIncorrectCategoryNames() {
/* Create a resource DTOs. */
MachineDTO m1 = new MachineDTO(getUniqueName(), "m1", "desc");
m1.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
null, // Cost category not specified.
getDate(2000, 1, 1), null));
MachineDTO m2 = new MachineDTO(getUniqueName(), "m2", "desc");
m2.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
getUniqueName(), // Non-existent cost category.
getDate(2000, 1, 1), null));
/* Test. */
ResourceListDTO resourceDTOs = createResourceListDTO(m1, m2);
assertOneConstraintViolationPerInstance(
resourceService.addResources(resourceDTOs),
resourceDTOs.resources.size());
for (ResourceDTO r : resourceDTOs.resources) {
MachineDTO m = (MachineDTO) r;
assertFalse(
"Machine " + m.name + " not expected",
machineDAO.existsMachineWithCodeInAnotherTransaction(m.code));
};
}
@Test
@NotTransactional
public void testAddResourceWithCostAssignmentWithoutStartDate() {
/* Create a CostCategory. */
CostCategory costCategory = createCostCategory();
/* Create a resource DTO. */
MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc");
machineDTO.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
costCategory.getName(), null, // Start date not specified.
getDate(2000, 1, 1)));
/* Test. */
assertOneConstraintViolation(
resourceService.addResources(createResourceListDTO(machineDTO)));
assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction(
machineDTO.code));
}
@Test
@NotTransactional
public void testAddResourceWithCostAssignmentWithNegativeInterval() {
/* Create a CostCategory. */
CostCategory costCategory = createCostCategory();
/* Create a resource DTO. */
MachineDTO machineDTO = new MachineDTO(getUniqueName(), "name", "desc");
machineDTO.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
costCategory.getName(),
getDate(2000, 2, 1), getDate(2000, 1, 1)));
/* Test. */
assertOneConstraintViolation(
resourceService.addResources(createResourceListDTO(machineDTO)));
assertFalse(machineDAO.existsMachineWithCodeInAnotherTransaction(
machineDTO.code));
}
@Test
@NotTransactional
public void testAddResourcesWithOverlappingInCostAssignments() {
/* Create a CostCategory. */
CostCategory costCategory = createCostCategory();
/*
* 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 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 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 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 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));
/* Test. */
ResourceListDTO resourceDTOs = createResourceListDTO(
m1, m2, m3, m4, m5, m6, m7, m8, m9);
assertOneConstraintViolationPerInstance(
resourceService.addResources(resourceDTOs),
resourceDTOs.resources.size());
for (ResourceDTO r : resourceDTOs.resources) {
MachineDTO m = (MachineDTO) r;
assertFalse(
"Machine " + m.name + " not expected",
machineDAO.existsMachineWithCodeInAnotherTransaction(
((MachineDTO) r).code));
}
}
private CriterionType createCriterionType() {
return createCriterionType(ResourceEnum.RESOURCE);
}
@ -501,7 +699,7 @@ public class ResourceServiceTest {
}
public BaseCalendar getDefaultCalendar() {
private BaseCalendar getDefaultCalendar() {
IOnTransaction<BaseCalendar> find = new IOnTransaction<BaseCalendar>() {
@ -546,11 +744,51 @@ public class ResourceServiceTest {
}
private CostCategory createCostCategory() {
IOnTransaction<CostCategory> create =
new IOnTransaction<CostCategory>() {
@Override
public CostCategory execute() {
CostCategory costCategory =
CostCategory.create(getUniqueName());
costCategoryDAO.save(costCategory);
return costCategory;
}
};
return transactionService.runOnTransaction(create);
}
private MachineDTO createMachineDTOWithTwoCostsAssignments(
String machineName, String costCategoryName,
XMLGregorianCalendar startDate1, XMLGregorianCalendar endDate1,
XMLGregorianCalendar startDate2, XMLGregorianCalendar endDate2) {
MachineDTO machineDTO = new MachineDTO(getUniqueName(), machineName,
"desc");
machineDTO.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
costCategoryName, startDate1, endDate1));
machineDTO.resourcesCostCategoryAssignments.add(
new ResourcesCostCategoryAssignmentDTO(
costCategoryName, startDate2, endDate2));
return machineDTO;
}
private void assertNoConstraintViolations(
InstanceConstraintViolationsListDTO
instanceConstraintViolationsListDTO) {
assertTrue(instanceConstraintViolationsListDTO.
assertTrue(
instanceConstraintViolationsListDTO.
instanceConstraintViolationsList.toString(),
instanceConstraintViolationsListDTO.
instanceConstraintViolationsList.size() == 0);
}
@ -563,9 +801,46 @@ public class ResourceServiceTest {
instanceConstraintViolationsListDTO.
instanceConstraintViolationsList;
assertTrue(instanceConstraintViolationsList.size() == 1);
assertTrue(instanceConstraintViolationsList.get(0).
constraintViolations.size() == 1);
assertTrue(
instanceConstraintViolationsList.toString(),
instanceConstraintViolationsList.size() == 1);
assertTrue(
instanceConstraintViolationsList.get(0).
constraintViolations.toString(),
instanceConstraintViolationsList.get(0).
constraintViolations.size() == 1);
}
private void assertOneConstraintViolationPerInstance(
InstanceConstraintViolationsListDTO
instanceConstraintViolationsListDTO, int numberOfInstances) {
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
instanceConstraintViolationsListDTO.
instanceConstraintViolationsList;
assertTrue(
instanceConstraintViolationsList.toString(),
instanceConstraintViolationsList.size() == numberOfInstances);
for (InstanceConstraintViolationsDTO i :
instanceConstraintViolationsList) {
assertTrue(
i.constraintViolations.toString(),
i.constraintViolations.size() == 1);
}
}
private XMLGregorianCalendar getDate(int year, int month, int day) {
try {
return DatatypeFactory.newInstance().newXMLGregorianCalendarDate(
year, month, day, DatatypeConstants.FIELD_UNDEFINED);
} catch (DatatypeConfigurationException e) {
throw new RuntimeException(e);
}
}

View file

@ -22,7 +22,7 @@
* Import resources:
- import-resources.sh resources-sample.xml
- import-resources.sh resources-sample-mini.xml (or resources-sample.xml)
(authenticate with wswriter/wswriter)
- Check the returned errors are consistent with the comments in

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<resource-list xmlns="http://rest.ws.navalplanner.org">
<!-- [It assumes existence of "TestLocationGroupCriterion" and
"TestCostCategory"] OK. -->
<machine code="machineA" name="name" description="desc">
<criterion-satisfaction-list>
<criterion-satisfaction
criterion-type-name="LOCATION_GROUP"
criterion-name="TestLocationGroupCriterion"
start-date="2009-01-01"
end-date=""/>
</criterion-satisfaction-list>
<resources-cost-category-assignment-list>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2001-01-01"/>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2000-01-01"
end-date="2000-04-01"/>
</resources-cost-category-assignment-list>
</machine>
<!-- [It assumes existence of "TestCalendar" and "TestCostCategory"] OK -->
<worker first-name="workerA" surname="surname" nif="nif"
calendar-name="TestCalendar">
<criterion-satisfaction-list>
<criterion-satisfaction
criterion-type-name="WORK_RELATIONSHIP"
criterion-name="hiredResourceWorkingRelationship"
start-date="2009-01-01"
end-date=""/>
<criterion-satisfaction
criterion-type-name="LEAVE"
criterion-name="paternityLeave"
start-date="2009-12-24"
end-date="2009-12-25"/>
</criterion-satisfaction-list>
<resources-cost-category-assignment-list>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2001-01-01"/>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2000-01-01"
end-date="2000-04-01"/>
</resources-cost-category-assignment-list>
</worker>
</resource-list>

View file

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
See org.navalplanner.web.test.ws.resources.api.ResourceServiceTest for a
complete list of test cases.
-->
<resource-list xmlns="http://rest.ws.navalplanner.org">
<!-- *** Machines *** -->
@ -17,16 +22,62 @@
criterion-type-name="WORK_RELATIONSHIP"
criterion-name="hiredResourceWorkingRelationship"
start-date="2009-01-01"
finish-date=""/>
end-date=""/>
</criterion-satisfaction-list>
</machine>
<!-- Another machine is being imported with the same code. -->
<machine code="m1" name="m3-name" description="m3-desc"/>
<!-- OK or not OK depending on the existence of "CalendarTest". -->
<!-- OK or not OK depending on the existence of "TestCalendar". -->
<machine code="m4" name="m4-name" description="m4-desc"
calendar-name="CalendarTest"/>
calendar-name="TestCalendar"/>
<!-- [It assumes existence of "TestCostCategory"] OK. -->
<machine code="m5" name="m5-name" description="m5-desc">
<resources-cost-category-assignment-list>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2001-01-01"/>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2000-01-01"
end-date="2000-04-01"/>
</resources-cost-category-assignment-list>
</machine>
<!-- [It assumes existence of "TestCostCategory"] Missing start date. -->
<machine code="m6" name="m6-name" description="m6-desc">
<resources-cost-category-assignment-list>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
end-date="2000-01-01"/>
</resources-cost-category-assignment-list>
</machine>
<!-- [It assumes existence of "TestCostCategory"] Negative interval. -->
<machine code="m7" name="m7-name" description="m7-desc">
<resources-cost-category-assignment-list>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2000-02-01"
end-date="2000-01-01"/>
</resources-cost-category-assignment-list>
</machine>
<!-- [It assumes existence of "TestCostCategory"] Overlapping intervals. -->
<machine code="m8" name="m8-name" description="m8-desc">
<resources-cost-category-assignment-list>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2000-02-01"
end-date="2000-05-01"/>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2000-01-01"
end-date="2000-03-01"/>
</resources-cost-category-assignment-list>
</machine>
<!-- *** Workers *** -->
@ -37,12 +88,12 @@
criterion-type-name="WORK_RELATIONSHIP"
criterion-name="hiredResourceWorkingRelationship"
start-date="2009-01-01"
finish-date=""/>
end-date=""/>
<criterion-satisfaction
criterion-type-name="LEAVE"
criterion-name="paternityLeave"
start-date="2009-12-24"
finish-date="2009-12-25"/>
end-date="2009-12-25"/>
</criterion-satisfaction-list>
</worker>
@ -55,7 +106,7 @@
<criterion-satisfaction
criterion-type-name="LEAVE"
criterion-name="paternityLeave"
finish-date="2009-12-25"/>
end-date="2009-12-25"/>
</criterion-satisfaction-list>
</worker>
@ -66,7 +117,7 @@
criterion-type-name="WORK_RELATIONSHIP_XXX"
criterion-name="hiredResourceWorkingRelationship"
start-date="2009-01-01"
finish-date=""/>
end-date=""/>
</criterion-satisfaction-list>
</worker>
@ -77,7 +128,7 @@
criterion-type-name="WORK_RELATIONSHIP"
criterion-name="hiredResourceWorkingRelationshipXXX"
start-date="2009-01-01"
finish-date=""/>
end-date=""/>
</criterion-satisfaction-list>
</worker>
@ -87,7 +138,7 @@
<criterion-satisfaction
criterion-type-name="WORK_RELATIONSHIP"
start-date="2009-01-01"
finish-date=""/>
end-date=""/>
</criterion-satisfaction-list>
</worker>
@ -97,7 +148,7 @@
<criterion-satisfaction
criterion-name="hiredResourceWorkingRelationship"
start-date="2009-01-01"
finish-date=""/>
end-date=""/>
</criterion-satisfaction-list>
</worker>
@ -105,8 +156,34 @@
and nif. -->
<worker first-name="w1-firstName" surname="w1-surname" nif="w1-nif"/>
<!-- OK or not OK depending on the existence of "CalendarTest". -->
<!-- OK or not OK depending on the existence of "TestCalendar". -->
<worker first-name="w8-firstName" surname="w8-surname" nif="w8-nif"
calendar-name="CalendarTest" />
calendar-name="TestCalendar" />
<!-- [It assumes existence of "TestCalendar" and "TestCostCategory"] OK -->
<worker first-name="w9-firstName" surname="w9-surname" nif="w9-nif"
calendar-name="TestCalendar">
<criterion-satisfaction-list>
<criterion-satisfaction
criterion-type-name="WORK_RELATIONSHIP"
criterion-name="hiredResourceWorkingRelationship"
start-date="2009-01-01"
end-date=""/>
<criterion-satisfaction
criterion-type-name="LEAVE"
criterion-name="paternityLeave"
start-date="2009-12-24"
end-date="2009-12-25"/>
</criterion-satisfaction-list>
<resources-cost-category-assignment-list>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2001-01-01"/>
<resources-cost-category-assignment
cost-category-name="TestCostCategory"
start-date="2000-01-01"
end-date="2000-04-01"/>
</resources-cost-category-assignment-list>
</worker>
</resource-list>