ItEr60S04ValidacionEProbasFuncionaisItEr59S04 : Fixing bug in the work report class.

it shows the error messages when the importation is incorrect.
This commit is contained in:
Susana Montes Pedreira 2010-07-06 15:08:55 +02:00 committed by Javier Moran Rua
parent 61c011e52f
commit 961eca61ea
8 changed files with 594 additions and 123 deletions

View file

@ -275,7 +275,7 @@ public class WorkReport extends IntegrationEntity {
return true;
}
if (this.workReportType.getHeadingFields().size() != this.descriptionValues
if (this.workReportType.getHeadingFields().size() > this.descriptionValues
.size()) {
return false;
}
@ -291,6 +291,27 @@ public class WorkReport extends IntegrationEntity {
return true;
}
@SuppressWarnings("unused")
@AssertTrue(message = "There are repeated description values in the work report ")
public boolean checkConstraintAssignedRepeatedDescriptionValues() {
Set<String> textFields = new HashSet<String>();
for (DescriptionValue v : this.descriptionValues) {
String name = v.getFieldName();
if (!StringUtils.isBlank(name)) {
if (textFields.contains(name.toLowerCase())) {
return false;
} else {
textFields.add(name.toLowerCase());
}
}
}
return true;
}
public DescriptionValue getDescriptionValueByFieldName(String fieldName)
throws InstanceNotFoundException {
@ -402,4 +423,8 @@ public class WorkReport extends IntegrationEntity {
}
@AssertTrue(message = "The work report line codes must be unique.")
public boolean checkConstraintNonRepeatedWorkReportLinesCodes() {
return getFirstRepeatedCode(this.workReportLines) == null;
}
}

View file

@ -272,6 +272,25 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
return true;
}
@SuppressWarnings("unused")
@AssertTrue(message = "The start hour cannot be higher than finish hour")
public boolean checkCannotBeHigher() {
if (!firstLevelValidationsPassed()) {
return true;
}
if (workReport.getWorkReportType().getHoursManagement().equals(
HoursManagementEnum.HOURS_CALCULATED_BY_CLOCK)) {
return checkCannotBeHigher(this.clockStart, this.clockFinish);
}
return true;
}
public boolean checkCannotBeHigher(LocalTime starting, LocalTime ending) {
return !((ending != null) && (starting != null) && (starting
.compareTo(ending) > 0));
}
void updateItsFieldsAndLabels() {
if (workReport != null) {
assignItsLabels(workReport.getWorkReportType());
@ -455,7 +474,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
return true;
}
if (this.workReport.getWorkReportType().getLineFields().size() != this.descriptionValues
if (this.workReport.getWorkReportType().getLineFields().size() > this.descriptionValues
.size()) {
return false;
}
@ -471,6 +490,27 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
return true;
}
@SuppressWarnings("unused")
@AssertTrue(message = "There are repeated description values in the work report line")
public boolean checkConstraintAssignedRepeatedDescriptionValues() {
Set<String> textFields = new HashSet<String>();
for (DescriptionValue v : this.descriptionValues) {
String name = v.getFieldName();
if (!StringUtils.isBlank(name)) {
if (textFields.contains(name.toLowerCase())) {
return false;
} else {
textFields.add(name.toLowerCase());
}
}
}
return true;
}
public DescriptionValue getDescriptionValueByFieldName(String fieldName)
throws InstanceNotFoundException {
@ -505,4 +545,5 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
throw new InstanceNotFoundException(type, LabelType.class.getName());
}
}

View file

@ -28,6 +28,7 @@ import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
/**
* A converter from <code>java.util.Date</code> to/from
@ -58,9 +59,34 @@ 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/>
*
* <code>xsd:localTime</code> XML type to a <code>LocalTime</code>.<br/>
* <br/>
* If the localTime passed as a parameter is <code>null</code>, it also
* returns <code>null</code>.
*/
public final static LocalTime toLocalTime(XMLGregorianCalendar date) {
if (date == null) {
return null;
} else {
if (isDefined(date.getHour()) && isDefined(date.getMinute())
&& isDefined(date.getSecond())){
return new LocalTime(date.getHour(), date.getMinute(), date
.getSecond());
}
return null;
}
}
private static boolean isDefined(int hour){
return hour != DatatypeConstants.FIELD_UNDEFINED;
}
/**
* 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>.
*/
@ -106,4 +132,23 @@ public class DateConverter {
return toXMLGregorianCalendar(LocalDate.fromDateFields(date));
}
public static XMLGregorianCalendar toXMLGregorianCalendar(LocalTime dateTime) {
if (dateTime == null) {
return null;
} else {
DatatypeFactory factory;
try {
factory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) {
throw new RuntimeException(e);
}
LocalDate date = dateTime.toDateTimeToday().toLocalDate();
return factory.newXMLGregorianCalendarTime(dateTime
.getHourOfDay(), dateTime.getMinuteOfHour(), dateTime
.getSecondOfMinute(), dateTime.getMillisOfSecond(),
DatatypeConstants.FIELD_UNDEFINED
);
}
}
}

View file

@ -20,7 +20,6 @@
package org.navalplanner.ws.workreports.api;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@ -28,6 +27,7 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.datatype.XMLGregorianCalendar;
import org.navalplanner.business.workreports.entities.WorkReport;
import org.navalplanner.ws.common.api.IntegrationEntityDTO;
@ -47,7 +47,7 @@ public class WorkReportDTO extends IntegrationEntityDTO {
public String workReportType;
@XmlAttribute
public Date date;
public XMLGregorianCalendar date;
@XmlAttribute
public String resource;
@ -70,7 +70,8 @@ public class WorkReportDTO extends IntegrationEntityDTO {
public WorkReportDTO() {
}
public WorkReportDTO(String code, String workReportType, Date date,
public WorkReportDTO(String code, String workReportType,
XMLGregorianCalendar date,
String resource, String orderElement, Set<LabelReferenceDTO> labels,
Set<DescriptionValueDTO> descriptionValues,
Set<WorkReportLineDTO> workReportLines) {

View file

@ -20,7 +20,6 @@
package org.navalplanner.ws.workreports.api;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@ -28,6 +27,7 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.datatype.XMLGregorianCalendar;
import org.navalplanner.business.workreports.entities.WorkReportLine;
import org.navalplanner.ws.common.api.IntegrationEntityDTO;
@ -44,7 +44,7 @@ public class WorkReportLineDTO extends IntegrationEntityDTO {
public final static String ENTITY_TYPE = "work-report-line";
@XmlAttribute
public Date date;
public XMLGregorianCalendar date;
@XmlAttribute
public String resource;
@ -56,10 +56,10 @@ public class WorkReportLineDTO extends IntegrationEntityDTO {
public String typeOfWorkHours;
@XmlAttribute(name = "start-hour")
public Date clockStart;
public XMLGregorianCalendar clockStart;
@XmlAttribute(name = "finish-hour")
public Date clockFinish;
public XMLGregorianCalendar clockFinish;
@XmlAttribute(name = "hours")
public Integer numHours;
@ -75,9 +75,11 @@ public class WorkReportLineDTO extends IntegrationEntityDTO {
public WorkReportLineDTO() {
}
public WorkReportLineDTO(String code, Date date, String resource,
String orderElement, String typeOfWorkHours, Date clockStart,
Date clockFinish, Integer numHours, Set<LabelReferenceDTO> labels,
public WorkReportLineDTO(String code, XMLGregorianCalendar date,
String resource,
String orderElement, String typeOfWorkHours,
XMLGregorianCalendar clockStart, XMLGregorianCalendar clockFinish,
Integer numHours, Set<LabelReferenceDTO> labels,
Set<DescriptionValueDTO> descriptionValues) {
super(code);
this.date = date;

View file

@ -26,6 +26,8 @@ import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.xml.datatype.XMLGregorianCalendar;
import org.apache.commons.lang.StringUtils;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
@ -41,6 +43,7 @@ import org.navalplanner.business.workreports.entities.WorkReportLine;
import org.navalplanner.business.workreports.entities.WorkReportType;
import org.navalplanner.business.workreports.valueobjects.DescriptionValue;
import org.navalplanner.ws.common.api.LabelReferenceDTO;
import org.navalplanner.ws.common.impl.DateConverter;
import org.navalplanner.ws.common.impl.LabelReferenceConverter;
import org.navalplanner.ws.workreports.api.DescriptionValueDTO;
import org.navalplanner.ws.workreports.api.WorkReportDTO;
@ -78,7 +81,7 @@ public final class WorkReportConverter {
// Optional fields
if (workReportDTO.date != null) {
workReport.setDate(workReportDTO.date);
workReport.setDate(DateConverter.toDate(workReportDTO.date));
}
if (workReportDTO.orderElement != null) {
@ -88,6 +91,8 @@ public final class WorkReportConverter {
workReport.setOrderElement(orderElement);
} catch (InstanceNotFoundException e) {
workReport.setOrderElement(null);
throw new ValidationException(
_("There is no order element with this code"));
}
}
@ -98,15 +103,24 @@ public final class WorkReportConverter {
workReport.setResource(worker);
} catch (InstanceNotFoundException e) {
workReport.setResource(null);
throw new ValidationException(
_("There is no resource with this nif"));
}
}
if (workReportDTO.labels != null) {
if (workReportDTO.labels != null && !workReportDTO.labels.isEmpty()) {
try {
workReport.setLabels(LabelReferenceConverter
.toEntity(workReportDTO.labels));
} catch (InstanceNotFoundException e) {
throw new ValidationException(
_("There is no label with this code "
+ (String) e.getKey()));
}
}
if (workReportDTO.descriptionValues != null) {
if (workReportDTO.descriptionValues != null
&& !workReportDTO.descriptionValues.isEmpty()) {
workReport
.setDescriptionValues(toEntity(workReportDTO.descriptionValues));
}
@ -138,7 +152,8 @@ public final class WorkReportConverter {
// Optional fields
if (workReportLineDTO.date != null) {
workReportLine.setDate(workReportLineDTO.date);
workReportLine
.setDate(DateConverter.toDate(workReportLineDTO.date));
}
if (workReportLineDTO.orderElement != null) {
@ -148,6 +163,8 @@ public final class WorkReportConverter {
workReportLine.setOrderElement(orderElement);
} catch (InstanceNotFoundException e) {
workReportLine.setOrderElement(null);
throw new ValidationException(
_("There is no order element with this code"));
}
}
@ -158,17 +175,22 @@ public final class WorkReportConverter {
workReportLine.setResource(worker);
} catch (InstanceNotFoundException e) {
workReportLine.setResource(null);
throw new ValidationException(
_("There is no resource with this nif"));
}
}
if (workReportLineDTO.clockStart != null) {
workReportLine.setClockStart(workReportLineDTO.clockStart);
workReportLine.setClockStart(DateConverter
.toLocalTime(workReportLineDTO.clockStart));
}
if (workReportLineDTO.clockFinish != null) {
workReportLine.setClockFinish(workReportLineDTO.clockFinish);
workReportLine.setClockFinish(DateConverter
.toLocalTime(workReportLineDTO.clockFinish));
}
if (workReportLineDTO.labels != null) {
if (workReportLineDTO.labels != null
&& !workReportLineDTO.labels.isEmpty()) {
workReportLine.setLabels(LabelReferenceConverter
.toEntity(workReportLineDTO.labels));
}
@ -211,9 +233,9 @@ public final class WorkReportConverter {
}
// Optional fields
Date date = null;
XMLGregorianCalendar date = null;
if (workReport.getDate() != null) {
date = workReport.getDate();
date = DateConverter.toXMLGregorianCalendar(workReport.getDate());
}
String orderElementCode = null;
@ -262,7 +284,8 @@ public final class WorkReportConverter {
public final static WorkReportLineDTO toDTO(WorkReportLine line){
String code = line.getCode();
Date date = line.getDate();
XMLGregorianCalendar date = DateConverter.toXMLGregorianCalendar(line
.getDate());
String resource = null;
if((line.getResource() != null) && (line.getResource() instanceof Worker)){
@ -279,14 +302,15 @@ public final class WorkReportConverter {
typeOfWorkHours = line.getTypeOfWorkHours().getCode();
}
Date clockStart = null;
XMLGregorianCalendar clockStart = null;
if(line.getClockStart() != null){
clockStart = line.getClockStart().toDateTimeToday().toDate();
clockStart = DateConverter.toXMLGregorianCalendar(line.getClockStart());
}
Date clockFinish = null;
XMLGregorianCalendar clockFinish = null;
if(line.getClockFinish() != null){
clockFinish = line.getClockFinish().toDateTimeToday().toDate();
clockFinish = DateConverter.toXMLGregorianCalendar(line
.getClockFinish());
}
Integer numHours = null;
@ -331,6 +355,10 @@ public final class WorkReportConverter {
public final static void updateWorkReport(WorkReport workReport,
WorkReportDTO workReportDTO) throws ValidationException {
if (StringUtils.isBlank(workReportDTO.code)) {
throw new ValidationException(_("missing code in a work report."));
}
WorkReportType type = workReport.getWorkReportType();
/*
* 1: Update the existing work report line or add new
@ -361,12 +389,12 @@ public final class WorkReportConverter {
/*
* 2: Update the existing labels
*/
if (workReportDTO.labels != null) {
for (LabelReferenceDTO labelDTO : workReportDTO.labels) {
/* Step 2.1: requires each label reference DTO to have a code. */
if (StringUtils.isBlank(labelDTO.code)) {
throw new ValidationException(
_("missing code in a label"));
throw new ValidationException(_("missing code in a label"));
}
try {
@ -377,10 +405,12 @@ public final class WorkReportConverter {
_("work report has not this label type assigned"));
}
}
}
/*
* 3: Update the existing description values
*/
if (workReportDTO.descriptionValues != null) {
for (DescriptionValueDTO valueDTO : workReportDTO.descriptionValues) {
/* Step 3.1: requires each description value DTO to have a code. */
@ -398,13 +428,14 @@ public final class WorkReportConverter {
_("work report has not any description value with this field name"));
}
}
}
/*
* 4: Update basic properties in existing work report
*/
/* Step 4.1: Update the date. */
Date date = workReportDTO.date;
Date date = DateConverter.toDate(workReportDTO.date);
workReport.setDate(date);
/* Step 4.2: Update the resource. */
@ -441,9 +472,11 @@ public final class WorkReportConverter {
/*
* 1: Update the existing labels
*/
if (workReportLineDTO.labels != null) {
for (LabelReferenceDTO labelDTO : workReportLineDTO.labels) {
/* Step 2.1: requires each label reference DTO to have a code. */
// * Step 2.1: requires each label reference DTO to have a code.
// */
if (StringUtils.isBlank(labelDTO.code)) {
throw new ValidationException(_("missing code in a label"));
}
@ -456,7 +489,7 @@ public final class WorkReportConverter {
_("a work report line has not this label type assigned"));
}
}
}
/*
* 2: Update the existing description values
*/
@ -468,7 +501,7 @@ public final class WorkReportConverter {
*/
/* Step 3.1: Update the date. */
Date date = workReportLineDTO.date;
Date date = DateConverter.toDate(workReportLineDTO.date);
workReportLine.setDate(date);
/* Step 3.2: Update the resource. */
@ -509,10 +542,12 @@ public final class WorkReportConverter {
* hours.
*/
if (workReportLineDTO.clockStart != null) {
workReportLine.setClockStart(workReportLineDTO.clockStart);
workReportLine.setClockStart(DateConverter
.toLocalTime(workReportLineDTO.clockStart));
}
if (workReportLineDTO.clockFinish != null) {
workReportLine.setClockFinish(workReportLineDTO.clockFinish);
workReportLine.setClockFinish(DateConverter
.toLocalTime(workReportLineDTO.clockFinish));
}
if (workReportLineDTO.numHours != null) {
@ -524,6 +559,7 @@ public final class WorkReportConverter {
private static void updateDescriptionValues(
Set<DescriptionValueDTO> descriptionValues,
WorkReportLine workReportLine) {
if (descriptionValues != null) {
for (DescriptionValueDTO valueDTO : descriptionValues) {
/* Step 3.1: requires each description value DTO to have a code. */
@ -542,6 +578,7 @@ public final class WorkReportConverter {
}
}
}
}
@Transactional
private static void updateLabel(LabelReferenceDTO labelDTO,

View file

@ -36,6 +36,7 @@ import java.util.Set;
import java.util.UUID;
import org.hibernate.SessionFactory;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -62,6 +63,7 @@ import org.navalplanner.business.workreports.valueobjects.DescriptionField;
import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO;
import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO;
import org.navalplanner.ws.common.api.LabelReferenceDTO;
import org.navalplanner.ws.common.impl.DateConverter;
import org.navalplanner.ws.workreports.api.DescriptionValueDTO;
import org.navalplanner.ws.workreports.api.IWorkReportService;
import org.navalplanner.ws.workreports.api.WorkReportDTO;
@ -303,7 +305,8 @@ public class WorkReportServiceTest {
workReportLineDTO.code = "work-report-line-code-" + UUID.randomUUID();
workReportLineDTO.resource = resourceCode;
workReportLineDTO.orderElement = orderElementCode;
workReportLineDTO.date = new Date();
workReportLineDTO.date = DateConverter
.toXMLGregorianCalendar(new Date());
workReportLineDTO.typeOfWorkHours = typeOfWorkHoursCode;
workReportLineDTO.numHours = 8;
@ -473,8 +476,8 @@ public class WorkReportServiceTest {
int previous = workReportDAO.getAll().size();
WorkReportDTO workReportDTO = createWorkReportDTO(workReportTypeCode2);
Date date = new Date();
workReportDTO.date = date;
Date date = new LocalDate().toDateTimeAtStartOfDay().toDate();
workReportDTO.date = DateConverter.toXMLGregorianCalendar(date);
WorkReportListDTO workReportListDTO = new WorkReportListDTO(Arrays
.asList(workReportDTO));
@ -519,8 +522,10 @@ public class WorkReportServiceTest {
int hours = 12;
LocalTime start = new LocalTime(8, 0);
LocalTime end = start.plusHours(hours);
workReportLineDTO.clockStart = start.toDateTimeToday().toDate();
workReportLineDTO.clockFinish = end.toDateTimeToday().toDate();
workReportLineDTO.clockStart = DateConverter
.toXMLGregorianCalendar(start);
workReportLineDTO.clockFinish = DateConverter
.toXMLGregorianCalendar(end);
WorkReportListDTO workReportListDTO = new WorkReportListDTO(Arrays
.asList(workReportDTO));

View file

@ -1,59 +1,374 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<work-report-list xmlns="http://rest.ws.navalplanner.org">
<work-report work-order="proxecto-00006-00009"
resource="30303030D" date="2010-03-09T00:00:00+01:00"
work-report-type="codeXX"
code="c3573671-1245-4b49-91b2-2f0914a5cf8b">
<!-- the type wr1 has got the following structure
Date: heading
Resource: heading
Order Element: heading
Hours Management: Number of assigned hours.-->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-03-09"
work-report-type="wrt1"
code="wr1">
<label-list>
<label code="b2b9cdee-2785-4c03-8e01-cec0a93b61aa" />
<label code="001-001" />
</label-list>
<work-report-line-list>
<work-report-line hours="4"
finish-hour="2010-03-08T05:00:00+01:00"
start-hour="2010-03-08T01:00:00+01:00" hour-type="Normal"
work-order="proxecto-00006-00009" resource="30303030D"
date="2010-03-09T00:00:00+01:00"
code="77011765-2d77-4350-b315-84435d065a60">
<label-list>
<label code="774e42b9-c35c-4de2-a20b-487ff1c413ef" />
</label-list>
finish-hour="2010-03-08"
start-hour="2010-03-08" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="2010-03-09"
code="wrl1">
</work-report-line>
<work-report-line hours="6"
finish-hour="2010-03-08T07:00:00+01:00"
start-hour="2010-03-08T01:00:00+01:00" hour-type="Normal"
work-order="proxecto-00006-00009" resource="30303030D"
date="2010-03-09T00:00:00+01:00"
code="77011765-2d77-4350-b315-84435d065555">
finish-hour="2010-03-08"
start-hour="2010-03-08" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="2010-03-09"
code="wrl2">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- repeated labels [OK , because it only saves one reference to the label ]-->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-03-09"
work-report-type="wrt1"
code="wr19">
<label-list>
<label code="a6256552-5ac7-46a7-95d6-8b8c8b415c65" />
<label code="001-001" />
<label code="001-001" />
</label-list>
</work-report-line>
</work-report-line-list>
</work-report>
<work-report work-order="proxecto-00001-00002"
</work-report>
<!-- work report type not found -->
<work-report work-order="PREFIX-00001"
resource="66666666F" date="2010-03-18T00:00:00+01:00"
work-report-type="codeXY"
code="e230a3b4-3848-4ea9-9e7b-2c21e246200e">
<text-field-list>
<text-field value="oooh!" name="campoH" />
</text-field-list>
work-report-type="code not found"
code="wr2">
</work-report>
<!-- with a incorrect date -->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-13-09"
work-report-type="wrt1"
code="wr3">
</work-report>
<!-- with a incorrect order element code -->
<work-report work-order="incorrect code"
resource="30303030D" date="2010-13-09"
work-report-type="wrt1"
code="wr4">
</work-report>
<!-- with a incorrect resource -->
<work-report work-order="PREFIX-00001"
resource="resource not found" date="2010-13-09"
work-report-type="wrt1"
code="wr5">
</work-report>
<!-- code not specified -->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-11-09"
work-report-type="wrt1">
</work-report>
<!--label not assigned -->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-03-09"
work-report-type="wrt1"
code="wr6">
<label-list>
<label code="002-001" />
</label-list>
</work-report>
<!-- label code not found -->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-03-09"
work-report-type="wrt1"
code="wr7">
<label-list>
<label code="002-001" />
</label-list>
</work-report>
<!-- label code not found -->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-03-09"
work-report-type="wrt1"
code="wr8">
<label-list>
<label code="002-001" />
</label-list>
</work-report>
<!-- missing finish-hour (wrl1) OK -->
<!-- incorrect date (wrl2) OK -->
<work-report work-order="PREFIX-00001"
resource="30303030D" date="2010-03-09"
work-report-type="wrt1"
code="wr9">
<work-report-line-list>
<work-report-line hours="12" hour-type="Normal"
work-order="proxecto-00001-00002" resource="66666666F"
date="2010-03-18T00:00:00+01:00"
code="89ec8b66-5c21-4076-a06f-22f8e190dd36">
<text-field-list>
<text-field value="aaaaa" name="campoA" />
</text-field-list>
<work-report-line hours="4"
start-hour="2010-03-08" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="2010-03-09"
code="wr9-wrl1">
</work-report-line>
<work-report-line hours="15" hour-type="Normal"
work-order="proxecto-00001-00002" resource="66666666F"
date="2010-03-18T00:00:00+01:00"
code="89ec8b66-5c21-4076-a06f-22f8e190dd98">
<work-report-line hours="6"
finish-hour="2010-03-08"
start-hour="2010-03-08" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="210-03-09"
code="wr9-wrl2">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- the work report type has got the following structure:
Date: line
Resource: line
Order Element: line
Hours Management: Number of hours calculated by clock -->
<!-- missing finish-hour OK -->
<work-report date="2010-03-09"
work-report-type="wrt3"
code="wr10">
<work-report-line-list>
<work-report-line hours="6"
start-hour="201-07-05T00:00:00.000" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="2010-03-09" code="wr10-wrl2">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- incorrect start hour -->
<work-report date="2010-03-09"
work-report-type="wrt3"
code="wr10">
<work-report-line-list>
<work-report-line hours="6"
start-hour="201-07-05T00:00:00.000" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="2010-03-09" code="wr10-wrl2">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- finish-hour is incorrect -->
<work-report date="2010-03-09"
work-report-type="wrt3"
code="wr11">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="T01:00:00.000"
start-hour="T06:00:00.000" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="2010-03-09" code="wr11-wrl2">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- finish-hour is before start-hour -->
<work-report date="2010-03-09"
work-report-type="wrt3"
code="wr12">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="2010-07-08T01:00:00.000"
start-hour="2010-07-08T06:00:00.000" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="2010-03-09" code="wr12-wrl1">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- date incorrect -->
<work-report date="2010-03-09"
work-report-type="wrt3"
code="wr13">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="2010-07-08T06:00:00.000"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
work-order="PREFIX-00001" resource="30303030D"
date="200-03-09" code="wr13-wrl1">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- resource not specified -->
<!-- order element not specified -->
<work-report date="2010-03-09"
work-report-type="wrt3"
code="wr14">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="2010-07-08T06:00:00.000"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-09" code="wr14-wrl1">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- the work report type (wrt4) has got the following structure :
Date: heading
Resource: heading
Order Element: heading
Hours Management: Number of assigned hours and the time.
-->
<!-- the work report date does not match with the work report line date [OK] -->
<!-- the work report resource does not match with the work report line resource [OK] -->
<!-- the work report order element does not match with the work report order element [OK] -->
<work-report date="2010-03-09"
work-order="PREFIX-00001"
resource="30303030D"
work-report-type="wrt4"
code="wr15">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="2010-07-08T06:00:00.000"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr15-wrl1">
<text-field-list>
<text-field value="xxxxx" name="campoA" />
<text-field name="etiqueta1" value="value-etiqueta1" />
</text-field-list>
</work-report-line>
</work-report-line-list>
</work-report>
<!-- the work report have not assigned the description field" -->
<work-report date="2010-03-09"
work-order="PREFIX-00001"
resource="30303030D"
work-report-type="wrt4"
code="wr16">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="2010-07-08T06:00:00.000"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr16-wrl1">
</work-report-line>
</work-report-line-list>
</work-report>
<!-- Two work report lines with the same code -->
<work-report date="2010-03-09"
work-order="PREFIX-00001"
resource="30303030D"
work-report-type="wrt4"
code="wr17">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="2010-07-08T06:00:00.000"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr17-wrl1">
<text-field-list>
<text-field name="etiqueta1" value="value-etiqueta1" />
</text-field-list>
</work-report-line>
<work-report-line hours="6"
finish-hour="2010-07-08T06:00:00.000"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr17-wrl1">
<text-field-list>
<text-field name="etiqueta1" value="value-etiqueta1" />
</text-field-list>
</work-report-line>
</work-report-line-list>
</work-report>
<!-- Two text-fields with the same name -->
<work-report date="2010-03-09"
work-order="PREFIX-00001"
resource="30303030D"
work-report-type="wrt4"
code="wr18">
<work-report-line-list>
<work-report-line hours="6"
finish-hour="2010-07-08T06:00:00.000"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr18-wrl1">
<text-field-list>
<text-field name="etiqueta1" value="value-etiqueta1" />
<text-field name="etiqueta1" value="value-etiqueta2" />
</text-field-list>
</work-report-line>
</work-report-line-list>
</work-report>
<!-- missing finish-hour [OK] -->
<work-report date="2010-03-09"
work-order="PREFIX-00001"
resource="30303030D"
work-report-type="wrt4"
code="wr20">
<work-report-line-list>
<work-report-line hours="6"
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr20-wrl1">
<text-field-list>
<text-field name="etiqueta1" value="value-etiqueta1" />
</text-field-list>
</work-report-line>
</work-report-line-list>
</work-report>
<!-- missing finish-hour and hours -->
<work-report date="2010-03-09"
work-order="PREFIX-00001"
resource="30303030D"
work-report-type="wrt4"
code="wr21">
<work-report-line-list>
<work-report-line
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr21-wrl1">
<text-field-list>
<text-field name="etiqueta1" value="value-etiqueta1" />
</text-field-list>
</work-report-line>
</work-report-line-list>
</work-report>
<!-- repeated work report line code -->
<work-report date="2010-03-09"
work-order="PREFIX-00001"
resource="30303030D"
work-report-type="wrt4"
code="wr22">
<work-report-line-list>
<work-report-line
start-hour="2010-07-08T01:00:00.000" hour-type="t1"
date="2010-03-12" work-order="PREFIX-00022"
resource="w18-nif" code="wr20-wrl1">
<text-field-list>
<text-field name="etiqueta1" value="value-etiqueta1" />
</text-field-list>
</work-report-line>
</work-report-line-list>
</work-report>
</work-report-list>