Merge libreplan-business module with ZK branch.

Code refactoring.
This commit is contained in:
Vova Perebykivskyi 2016-10-17 16:54:49 +03:00 committed by Dgray16
parent 1fe6156527
commit 0f25b227fe
154 changed files with 3312 additions and 4073 deletions

View file

@ -33,12 +33,26 @@ import org.zkoss.ganttz.data.IDependency;
/** /**
* Represents a dependency in the domain. * Represents a dependency in the domain.
*
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*/ */
public class DomainDependency<T> implements IDependency<T> { public class DomainDependency<T> implements IDependency<T> {
private static final Log LOG = LogFactory.getLog(DomainDependency.class); private static final Log LOG = LogFactory.getLog(DomainDependency.class);
private final T source;
private final T destination;
private final DependencyType type;
private DomainDependency(T source, T destination, DependencyType type) {
super();
this.source = source;
this.destination = destination;
this.type = type;
}
public static <T> List<Dependency> toDependencies( public static <T> List<Dependency> toDependencies(
IDomainAndBeansMapper<T> mapper, Collection<DomainDependency<T>> dependencies) { IDomainAndBeansMapper<T> mapper, Collection<DomainDependency<T>> dependencies) {
@ -55,20 +69,7 @@ public class DomainDependency<T> implements IDependency<T> {
} }
public static <T> DomainDependency<T> createDependency(T source, T destination, DependencyType type) { public static <T> DomainDependency<T> createDependency(T source, T destination, DependencyType type) {
return new DomainDependency<T>(source, destination, type); return new DomainDependency<>(source, destination, type);
}
private final T source;
private final T destination;
private final DependencyType type;
private DomainDependency(T source, T destination, DependencyType type) {
super();
this.source = source;
this.destination = destination;
this.type = type;
} }
public T getSource() { public T getSource() {

View file

@ -1,5 +1,6 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
@ -79,7 +80,7 @@
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
</dependency> </dependency>
<!-- datasource for testing --> <!-- Datasource for testing -->
<dependency> <dependency>
<groupId>com.jolbox</groupId> <groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId> <artifactId>bonecp</artifactId>
@ -115,6 +116,11 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<!-- Log4j --> <!-- Log4j -->
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
@ -127,12 +133,6 @@
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
</dependency> </dependency>
<!-- DBUnit -->
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
</dependency>
<!-- Liquibase --> <!-- Liquibase -->
<dependency> <dependency>
<groupId>org.liquibase</groupId> <groupId>org.liquibase</groupId>

View file

@ -29,11 +29,10 @@ import java.lang.annotation.Target;
/** /**
* <p> * <p>
* It can be applied to a {@link IDataBootstrap} to indicate the order in which it will be executed. * It can be applied to a {@link IDataBootstrap} to indicate the order in which it will be executed.
* It's ensured that if a data bootstrap has a priority value greater than another one it will be executed before. * It's ensured that if a data bootstrap has a priority value greater than another one it will be executed before.
* * If two data bootstraps have the same priority value the order is unspecified.
* If two data bootstraps have the same priority value the order is unspecified. * If a data bootstrap doesn't have this annotation it's like it would have a value of zero.
* If a data bootstrap doesn't have this annotation it's like it would have a value of zero.
* </p> * </p>
* *
* It accepts negative values. * It accepts negative values.

View file

@ -24,12 +24,13 @@ package org.libreplan.business.advance.bootstrap;
import org.libreplan.business.IDataBootstrap; import org.libreplan.business.IDataBootstrap;
import org.libreplan.business.advance.daos.IAdvanceTypeDAO; import org.libreplan.business.advance.daos.IAdvanceTypeDAO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class DefaultAdvanceTypesBootstrapListener implements IDataBootstrap { public class DefaultAdvanceTypesBootstrapListener implements IDataBootstrap {
@Autowired @Autowired

View file

@ -91,7 +91,7 @@ public class AdvanceType extends BaseEntity implements IHumanIdentifiable{
private Boolean qualityForm = false; private Boolean qualityForm = false;
private IAdvanceTypeDAO avancedTypeDAO = Registry.getAdvanceTypeDao(); private IAdvanceTypeDAO advanceTypeDAO = Registry.getAdvanceTypeDao();
private boolean readOnly = false; private boolean readOnly = false;
@ -255,7 +255,7 @@ public class AdvanceType extends BaseEntity implements IHumanIdentifiable{
} }
if ( isNewObject() ) { if ( isNewObject() ) {
return !avancedTypeDAO.existsByNameInAnotherTransaction(unitName); return !advanceTypeDAO.existsByNameInAnotherTransaction(unitName);
} else { } else {
return checkNotExistsOrIsTheSame(); return checkNotExistsOrIsTheSame();
} }
@ -263,7 +263,7 @@ public class AdvanceType extends BaseEntity implements IHumanIdentifiable{
private boolean checkNotExistsOrIsTheSame() { private boolean checkNotExistsOrIsTheSame() {
try { try {
AdvanceType advanceType = avancedTypeDAO.findUniqueByNameInAnotherTransaction(unitName); AdvanceType advanceType = advanceTypeDAO.findUniqueByNameInAnotherTransaction(unitName);
return advanceType.getId().equals(getId()); return advanceType.getId().equals(getId());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {

View file

@ -38,8 +38,7 @@ import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.planner.entities.consolidations.NonCalculatedConsolidation; import org.libreplan.business.planner.entities.consolidations.NonCalculatedConsolidation;
/** /**
* Represents an {@link AdvanceAssignment} that is own of this * Represents an {@link AdvanceAssignment} that is own of this {@link OrderElement}.
* {@link OrderElement}.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
@ -52,7 +51,7 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
} }
public static DirectAdvanceAssignment create(boolean reportGlobalAdvance, public static DirectAdvanceAssignment create(boolean reportGlobalAdvance,
BigDecimal maxValue) { BigDecimal maxValue) {
DirectAdvanceAssignment advanceAssignment = new DirectAdvanceAssignment( DirectAdvanceAssignment advanceAssignment = new DirectAdvanceAssignment(
reportGlobalAdvance, maxValue); reportGlobalAdvance, maxValue);
advanceAssignment.setNewObject(true); advanceAssignment.setNewObject(true);
@ -62,8 +61,7 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
private BigDecimal maxValue; private BigDecimal maxValue;
@Valid @Valid
private SortedSet<AdvanceMeasurement> advanceMeasurements = new TreeSet<AdvanceMeasurement>( private SortedSet<AdvanceMeasurement> advanceMeasurements = new TreeSet<>(new AdvanceMeasurementComparator());
new AdvanceMeasurementComparator());
@Valid @Valid
private Set<NonCalculatedConsolidation> nonCalculatedConsolidations = new HashSet<NonCalculatedConsolidation>(); private Set<NonCalculatedConsolidation> nonCalculatedConsolidations = new HashSet<NonCalculatedConsolidation>();
@ -75,7 +73,7 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
} }
private DirectAdvanceAssignment(boolean reportGlobalAdvance, private DirectAdvanceAssignment(boolean reportGlobalAdvance,
BigDecimal maxValue) { BigDecimal maxValue) {
super(reportGlobalAdvance); super(reportGlobalAdvance);
this.maxValue = maxValue; this.maxValue = maxValue;
this.maxValue.setScale(2, BigDecimal.ROUND_HALF_UP); this.maxValue.setScale(2, BigDecimal.ROUND_HALF_UP);
@ -207,7 +205,7 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
&& (currentAdvance.getDate() != null) && (currentAdvance.getDate() != null)
&& (nextAdvance.getDate() != null) && (nextAdvance.getDate() != null)
&& (currentAdvance.getValue().compareTo( && (currentAdvance.getValue().compareTo(
nextAdvance.getValue()) < 0)) { nextAdvance.getValue()) < 0)) {
return false; return false;
} }
currentAdvance = nextAdvance; currentAdvance = nextAdvance;

View file

@ -32,67 +32,54 @@ import org.libreplan.business.common.IntegrationEntity;
import org.libreplan.business.common.Registry; import org.libreplan.business.common.Registry;
/** /**
* Stores information about activating periods, that define the availability of * Stores information about activating periods, that define the availability of the resource.
* the resource.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
public class CalendarAvailability extends IntegrationEntity { public class CalendarAvailability extends IntegrationEntity {
public static CalendarAvailability craete() { public static final Comparator<CalendarAvailability> BY_START_DATE_COMPARATOR =
return create(new CalendarAvailability(new LocalDate(), null)); (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate());
}
public static CalendarAvailability craete(Date startDate, Date endDate) {
return create(new CalendarAvailability(new LocalDate(startDate),
new LocalDate(endDate)));
}
public static CalendarAvailability create(LocalDate startDate,
LocalDate endDate) {
return create(new CalendarAvailability(startDate, endDate));
}
@NotNull @NotNull
private LocalDate startDate; private LocalDate startDate;
private LocalDate endDate; private LocalDate endDate;
public static final Comparator<CalendarAvailability> BY_START_DATE_COMPARATOR = new Comparator<CalendarAvailability>() {
@Override
public int compare(CalendarAvailability o1, CalendarAvailability o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
};
/** /**
* Constructor for hibernate. Do not use! * Constructor for hibernate. Do not use!
*/ */
public CalendarAvailability() { public CalendarAvailability() {}
}
private CalendarAvailability(LocalDate startDate, LocalDate endDate) private CalendarAvailability(LocalDate startDate, LocalDate endDate) {
throws IllegalArgumentException {
setStartDate(startDate); setStartDate(startDate);
setEndDate(endDate); setEndDate(endDate);
} }
public static CalendarAvailability create() {
return create(new CalendarAvailability(new LocalDate(), null));
}
public static CalendarAvailability create(Date startDate, Date endDate) {
return create(new CalendarAvailability(new LocalDate(startDate), new LocalDate(endDate)));
}
public static CalendarAvailability create(LocalDate startDate, LocalDate endDate) {
return create(new CalendarAvailability(startDate, endDate));
}
public LocalDate getStartDate() { public LocalDate getStartDate() {
return startDate; return startDate;
} }
public void setStartDate(LocalDate startDate) public void setStartDate(LocalDate startDate) {
throws IllegalArgumentException {
if (startDate == null) { if (startDate == null) {
throw new IllegalArgumentException("Start date must not be null"); throw new IllegalArgumentException("Start date must not be null");
} }
if (endDate != null) { if (endDate != null && startDate.compareTo(endDate) > 0) {
if (startDate.compareTo(endDate) > 0) { throw new IllegalArgumentException("End date must be greater or equal than start date");
throw new IllegalArgumentException(
"End date must be greater or equal than start date");
}
} }
this.startDate = startDate; this.startDate = startDate;
} }
@ -100,26 +87,16 @@ public class CalendarAvailability extends IntegrationEntity {
return endDate; return endDate;
} }
public void setEndDate(LocalDate endDate) throws IllegalArgumentException { public void setEndDate(LocalDate endDate) {
if (endDate != null) { if (endDate != null && startDate.compareTo(endDate) > 0) {
if (startDate.compareTo(endDate) > 0) { throw new IllegalArgumentException("End date must be greater or equal than start date");
throw new IllegalArgumentException(
"End date must be greater or equal than start date");
}
} }
this.endDate = endDate; this.endDate = endDate;
} }
public boolean isActive(LocalDate date) { public boolean isActive(LocalDate date) {
if (startDate.compareTo(date) > 0) { return startDate.compareTo(date) <= 0 && !((endDate != null) && (endDate.compareTo(date) < 0));
return false;
}
if ((endDate != null) && (endDate.compareTo(date) < 0)) {
return false;
}
return true;
} }
@Override @Override
@ -127,8 +104,7 @@ public class CalendarAvailability extends IntegrationEntity {
return Registry.getCalendarAvailabilityDAO(); return Registry.getCalendarAvailabilityDAO();
} }
public boolean isActiveBetween(LocalDate filterStartDate, public boolean isActiveBetween(LocalDate filterStartDate, LocalDate filterEndDate) {
LocalDate filterEndDate) {
if (filterStartDate == null && filterEndDate == null) { if (filterStartDate == null && filterEndDate == null) {
return true; return true;
} }
@ -137,29 +113,25 @@ public class CalendarAvailability extends IntegrationEntity {
if (endDate == null) { if (endDate == null) {
return startDate.compareTo(filterEndDate) <= 0; return startDate.compareTo(filterEndDate) <= 0;
} }
return startDate.compareTo(filterEndDate) <= 0
|| endDate.compareTo(filterEndDate) <= 0; return startDate.compareTo(filterEndDate) <= 0 || endDate.compareTo(filterEndDate) <= 0;
} }
if (filterEndDate == null) { if (filterEndDate == null) {
if (endDate == null) { return endDate == null || startDate.compareTo(filterStartDate) >= 0 ||
return true; endDate.compareTo(filterStartDate) >= 0;
}
return startDate.compareTo(filterStartDate) >= 0
|| endDate.compareTo(filterStartDate) >= 0;
} }
if (endDate == null) { if (endDate == null) {
return startDate.compareTo(filterStartDate) <= 0 return startDate.compareTo(filterStartDate) <= 0 || startDate.compareTo(filterEndDate) <= 0;
|| startDate.compareTo(filterEndDate) <= 0;
} }
Interval filterPeriod = new Interval( Interval filterPeriod = new Interval(filterStartDate.toDateTimeAtStartOfDay(),
filterStartDate.toDateTimeAtStartOfDay(), filterEndDate filterEndDate.plusDays(1).toDateTimeAtStartOfDay());
.plusDays(1).toDateTimeAtStartOfDay());
Interval activationPeriod = new Interval( Interval activationPeriod = new Interval(startDate.toDateTimeAtStartOfDay(),
startDate.toDateTimeAtStartOfDay(), endDate.plusDays(1) endDate.plusDays(1).toDateTimeAtStartOfDay());
.toDateTimeAtStartOfDay());
return filterPeriod.overlaps(activationPeriod); return filterPeriod.overlaps(activationPeriod);
} }

View file

@ -25,6 +25,7 @@ import org.libreplan.business.calendars.daos.ICalendarExceptionTypeDAO;
import org.libreplan.business.common.daos.IEntitySequenceDAO; import org.libreplan.business.common.daos.IEntitySequenceDAO;
import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.entities.EntityNameEnum;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -35,7 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class CalendarBootstrap implements ICalendarBootstrap { public class CalendarBootstrap implements ICalendarBootstrap {
@Autowired @Autowired

View file

@ -23,8 +23,6 @@ package org.libreplan.business.calendars.entities;
import static org.libreplan.business.i18n.I18nHelper._; import static org.libreplan.business.i18n.I18nHelper._;
import java.util.EnumMap;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
@ -38,7 +36,6 @@ import org.libreplan.business.common.IntegrationEntity;
import org.libreplan.business.common.Registry; import org.libreplan.business.common.Registry;
import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.workingday.EffortDuration; import org.libreplan.business.workingday.EffortDuration;
import org.libreplan.business.workingday.EffortDuration.Granularity;
import org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException; import org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException;
/** /**
@ -57,6 +54,18 @@ public class CalendarExceptionType extends IntegrationEntity implements IHumanId
private Capacity capacity = Capacity.zero(); private Capacity capacity = Capacity.zero();
/**
* Constructor for hibernate. Do not use!
*/
protected CalendarExceptionType() {}
public CalendarExceptionType(String name, CalendarExceptionTypeColor color, Boolean notOverAssignable) {
this.name = name;
this.color = color;
this.capacity = Capacity.zero();
this.capacity = this.capacity.overAssignableWithoutLimit(!BooleanUtils.isTrue(notOverAssignable));
}
public static CalendarExceptionType create() { public static CalendarExceptionType create() {
return create(new CalendarExceptionType()); return create(new CalendarExceptionType());
} }
@ -92,19 +101,6 @@ public class CalendarExceptionType extends IntegrationEntity implements IHumanId
return create(calendarExceptionType, code); return create(calendarExceptionType, code);
} }
/**
* Constructor for hibernate. Do not use!
*/
protected CalendarExceptionType() {
}
public CalendarExceptionType(String name, CalendarExceptionTypeColor color, Boolean notOverAssignable) {
this.name = name;
this.color = color;
this.capacity = Capacity.zero();
this.capacity = this.capacity.overAssignableWithoutLimit(!BooleanUtils.isTrue(notOverAssignable));
}
public boolean isUpdatable() { public boolean isUpdatable() {
return this.updatable; return this.updatable;
} }
@ -155,18 +151,6 @@ public class CalendarExceptionType extends IntegrationEntity implements IHumanId
return capacity.getStandardEffort(); return capacity.getStandardEffort();
} }
private String asString(EffortDuration duration) {
if ( duration == null ) {
return "";
}
EnumMap<Granularity, Integer> values = duration.decompose();
Integer hours = values.get(Granularity.HOURS);
Integer minutes = values.get(Granularity.MINUTES);
return hours + ":" + minutes;
}
public void setDuration(EffortDuration duration) { public void setDuration(EffortDuration duration) {
this.capacity = this.capacity.withStandardEffort(duration); this.capacity = this.capacity.withStandardEffort(duration);
} }
@ -191,12 +175,10 @@ public class CalendarExceptionType extends IntegrationEntity implements IHumanId
calendarExceptionTypeDAO.findUniqueByNameAnotherTransaction(name); calendarExceptionTypeDAO.findUniqueByNameAnotherTransaction(name);
return calendarExceptionType.getId().equals(getId()); return calendarExceptionType.getId().equals(getId());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException | HibernateOptimisticLockingFailureException e) {
return true; return true;
} catch (NonUniqueResultException e) { } catch (NonUniqueResultException e) {
return false; return false;
} catch (HibernateOptimisticLockingFailureException e) {
return true;
} }
} }

View file

@ -22,8 +22,7 @@ package org.libreplan.business.calendars.entities;
import static org.libreplan.business.i18n.I18nHelper._; import static org.libreplan.business.i18n.I18nHelper._;
/** /**
* Enum representing the possible colors to choose for a * Enum representing the possible colors to choose for a {@link CalendarExceptionType}.
* {@link CalendarExceptionType}
* *
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
*/ */
@ -39,7 +38,9 @@ public enum CalendarExceptionTypeColor {
PURPLE(_("purple"), "#801a80", "#b38eb3"); PURPLE(_("purple"), "#801a80", "#b38eb3");
private final String name; private final String name;
private final String colorOwnException; private final String colorOwnException;
private final String colorDerivedException; private final String colorDerivedException;
CalendarExceptionTypeColor(String name, String colorOwnException, String colorDerivedException) { CalendarExceptionTypeColor(String name, String colorOwnException, String colorDerivedException) {

View file

@ -33,13 +33,18 @@ import org.libreplan.business.workingday.EffortDuration.Granularity;
/** /**
* This class is intended as a Hibernate component. It's formed by two * This class is intended as a Hibernate component.
* components, the standard effort and the allowed extra effort. It represents * It's formed by two components, the standard effort and the allowed extra effort.
* the capacity for a resource. * It represents the capacity for a resource.
*
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*/ */
public class Capacity { public class Capacity {
private EffortDuration standardEffort;
private EffortDuration allowedExtraEffort;
public static Capacity sum(Capacity... capacities) { public static Capacity sum(Capacity... capacities) {
return sum(Arrays.asList(capacities)); return sum(Arrays.asList(capacities));
} }
@ -56,8 +61,7 @@ public class Capacity {
} }
public static Capacity min(Capacity a, Capacity b) { public static Capacity min(Capacity a, Capacity b) {
return new Capacity(EffortDuration.min(a.getStandardEffort(), return new Capacity(EffortDuration.min(a.getStandardEffort(), b.getStandardEffort()), minExtraEffort(a, b));
b.getStandardEffort()), minExtraEffort(a, b));
} }
private static EffortDuration minExtraEffort(Capacity a, Capacity b) { private static EffortDuration minExtraEffort(Capacity a, Capacity b) {
@ -90,17 +94,14 @@ public class Capacity {
} }
private static Capacity noCapacity() { private static Capacity noCapacity() {
return Capacity.create(EffortDuration.zero()) return Capacity.create(EffortDuration.zero()).notOverAssignableWithoutLimit();
.notOverAssignableWithoutLimit();
} }
public static Capacity zero() { public static Capacity zero() {
return new Capacity(EffortDuration.zero(), EffortDuration.zero()); return new Capacity(EffortDuration.zero(), EffortDuration.zero());
} }
private EffortDuration standardEffort;
private EffortDuration allowedExtraEffort;
/** /**
* Default constructor for hibernate. DO NOT USE! * Default constructor for hibernate. DO NOT USE!
@ -111,7 +112,7 @@ public class Capacity {
} }
private Capacity(EffortDuration standardEffort, private Capacity(EffortDuration standardEffort,
EffortDuration extraHours) { EffortDuration extraHours) {
Validate.notNull(standardEffort); Validate.notNull(standardEffort);
this.standardEffort = standardEffort; this.standardEffort = standardEffort;
this.allowedExtraEffort = extraHours; this.allowedExtraEffort = extraHours;
@ -229,7 +230,7 @@ public class Capacity {
Validate.notNull(assignedDuration); Validate.notNull(assignedDuration);
return isOverAssignableWithoutLimit() return isOverAssignableWithoutLimit()
|| assignedDuration.compareTo(standardEffort || assignedDuration.compareTo(standardEffort
.plus(allowedExtraEffort)) < 0; .plus(allowedExtraEffort)) < 0;
} }
public Capacity minus(EffortDuration assignment) { public Capacity minus(EffortDuration assignment) {
@ -243,7 +244,7 @@ public class Capacity {
standardEffort, assignment)); standardEffort, assignment));
EffortDuration newExtra = allowedExtraEffort == null ? null EffortDuration newExtra = allowedExtraEffort == null ? null
: allowedExtraEffort.minus(EffortDuration.min(pending, : allowedExtraEffort.minus(EffortDuration.min(pending,
allowedExtraEffort)); allowedExtraEffort));
return Capacity.create(newStandard).withAllowedExtraEffort(newExtra); return Capacity.create(newStandard).withAllowedExtraEffort(newExtra);
} }

View file

@ -29,39 +29,39 @@ import org.libreplan.business.workingday.ResourcesPerDay;
public interface ICalendar { public interface ICalendar {
/** /**
* Translates the received amount into the corresponding duration at the * Translates the received amount into the corresponding duration at the given date.
* given date. It takes into account the partial capacity of the day. * It takes into account the partial capacity of the day.
* *
* @param day * @param day
* @param amount * @param amount
* @return * @return
*/ */
public EffortDuration asDurationOn(PartialDay day, ResourcesPerDay amount); EffortDuration asDurationOn(PartialDay day, ResourcesPerDay amount);
/** /**
* Calculates the capacity duration at a given day. It means all the time * Calculates the capacity duration at a given day.
* that could be worked without having overtime. It considers the * It means all the time that could be worked without having overtime.
* {@link PartialDay} so if the day it's not complete the capacity is * It considers the {@link PartialDay} so if the day it's not complete the capacity is reduced.
* reduced *
* @param date * @param date
* the date at which the capacity is calculated * the date at which the capacity is calculated
* @return the capacity at which the resource can work at the day specified * @return the capacity at which the resource can work at the day specified
*/ */
public EffortDuration getCapacityOn(PartialDay partialDay); EffortDuration getCapacityOn(PartialDay partialDay);
/** /**
* Calculates the capacity information for a given date. It contains * Calculates the capacity information for a given date.
* information about the normal effort and the extra effort, i.e., the * It contains information about the normal effort and the extra effort, i.e., the overtime effort.
* overtime effort.
* *
* @param date * @param date
* a not null date * a not null date
* @return the capacity for the date provided * @return the capacity for the date provided
*/ */
public Capacity getCapacityWithOvertime(LocalDate date); Capacity getCapacityWithOvertime(LocalDate date);
public AvailabilityTimeLine getAvailability(); AvailabilityTimeLine getAvailability();
public boolean thereAreCapacityFor(AvailabilityTimeLine availability, boolean thereAreCapacityFor(AvailabilityTimeLine availability,
ResourcesPerDay resourcesPerDay, EffortDuration durationToAllocate); ResourcesPerDay resourcesPerDay,
EffortDuration durationToAllocate);
} }

View file

@ -28,6 +28,7 @@ import org.libreplan.business.resources.entities.Resource;
/** /**
* Calendar for a {@link Resource}. * Calendar for a {@link Resource}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com> * @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/ */
@ -41,6 +42,7 @@ public class ResourceCalendar extends BaseCalendar {
if (capacity == null) { if (capacity == null) {
return 1; return 1;
} }
return capacity; return capacity;
} }
@ -60,8 +62,7 @@ public class ResourceCalendar extends BaseCalendar {
private ResourceCalendar(CalendarData calendarData) { private ResourceCalendar(CalendarData calendarData) {
super(calendarData); super(calendarData);
CalendarAvailability calendarAvailability = CalendarAvailability CalendarAvailability calendarAvailability = CalendarAvailability.create(new LocalDate(), null);
.create(new LocalDate(), null);
addNewCalendarAvailability(calendarAvailability); addNewCalendarAvailability(calendarAvailability);
} }

View file

@ -32,10 +32,13 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class AdHocTransactionService implements IAdHocTransactionService { public class AdHocTransactionService implements IAdHocTransactionService {
private static <T> T proxy( private static <T> T proxy(IAdHocTransactionService transactionService,
IAdHocTransactionService transactionService, boolean readOnly, Class<T> interfaceClass, T interfaceObject) { boolean readOnly,
Class<T> interfaceClass,
T interfaceObject) {
Class<?>[] interfaces = { interfaceClass }; Class<?>[] interfaces = { interfaceClass };
return interfaceClass.cast(Proxy.newProxyInstance( return interfaceClass.cast(Proxy.newProxyInstance(
interfaceClass.getClassLoader(), interfaceClass.getClassLoader(),
interfaces, interfaces,
@ -43,51 +46,54 @@ public class AdHocTransactionService implements IAdHocTransactionService {
} }
/** /**
* Returns a new object implementing the same interface but with its calls * Returns a new object implementing the same interface but with its calls wrapped on read only transactions.
* wrapped on read only transactions *
* @param transactionService * @param transactionService
* @param interfaceClass * @param interfaceClass
* @param interfaceObject * @param interfaceObject
* @return * @return <T> T
*/ */
public static <T> T readOnlyProxy( public static <T> T readOnlyProxy(IAdHocTransactionService transactionService,
IAdHocTransactionService transactionService, Class<T> interfaceClass, T interfaceObject) { Class<T> interfaceClass,
T interfaceObject) {
return proxy(transactionService, true, interfaceClass, interfaceObject); return proxy(transactionService, true, interfaceClass, interfaceObject);
} }
/** /**
* Returns a new object implementing the same interface but with its calls * Returns a new object implementing the same interface but with its calls wrapped on transactions.
* wrapped on transactions *
* @param transactionService * @param transactionService
* @param interfaceClass * @param interfaceClass
* @param interfaceObject * @param interfaceObject
* @return * @return <T> T
*/ */
public static <T> T proxy(IAdHocTransactionService transactionService, Class<T> interfaceClass, T interfaceObject) { public static <T> T proxy(IAdHocTransactionService transactionService,
Class<T> interfaceClass,
T interfaceObject) {
return proxy(transactionService, false, interfaceClass, interfaceObject); return proxy(transactionService, false, interfaceClass, interfaceObject);
} }
private static InvocationHandler createHandler( private static InvocationHandler createHandler(final Object originalObject,
final Object originalObject, final IAdHocTransactionService transactionService, final boolean readOnly) { final IAdHocTransactionService transactionService,
final boolean readOnly) {
return (proxy, method, args) -> { return (proxy, method, args) -> {
IOnTransaction<Object> onTransaction = createOnTransaction(originalObject, method, args); IOnTransaction<Object> onTransaction = createOnTransaction(originalObject, method, args);
try { try {
if ( readOnly ) { return readOnly
return transactionService.runOnReadOnlyTransaction(onTransaction); ? transactionService.runOnReadOnlyTransaction(onTransaction)
} else { : transactionService.runOnTransaction(onTransaction);
return transactionService.runOnTransaction(onTransaction);
}
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw e.getCause(); throw e.getCause();
} }
}; };
} }
private static IOnTransaction<Object> createOnTransaction( private static IOnTransaction<Object> createOnTransaction(final Object originalObject,
final Object originalObject, final Method method, final Object[] args) { final Method method,
final Object[] args) {
return () -> { return () -> {
try { try {
return method.invoke(originalObject, args); return method.invoke(originalObject, args);

View file

@ -43,7 +43,6 @@ import org.libreplan.business.util.deepcopy.Strategy;
/** /**
* Base class for all the application entities. * Base class for all the application entities.
*
* It provides the basic behavior for id and version fields. * It provides the basic behavior for id and version fields.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
@ -126,8 +125,9 @@ public abstract class BaseEntity implements INewObject {
/** /**
* Once the has been really saved in DB (not a readonly transaction), it * Once the has been really saved in DB (not a readonly transaction), it
* could be necessary to unmark the object as newObject. This is the case if * could be necessary to unmark the object as newObject.
* you must use the same instance after the transaction. <br /> * This is the case if you must use the same instance after the transaction.
* <br />
*/ */
public void dontPoseAsTransientObjectAnymore() { public void dontPoseAsTransientObjectAnymore() {
setNewObject(false); setNewObject(false);

View file

@ -28,12 +28,12 @@ import org.apache.commons.lang3.BooleanUtils;
* *
* Currently we have three options: * Currently we have three options:
* <ul> * <ul>
* <li>Enable/Disable the warning changing default password</li> * <li>Enable/Disable the warning changing default password</li>
* * <li>
* <li>Enable/Disable default users * Enable/Disable default users
* (such as wsreader, wswriter, wssubcontracting, manager, hresources, outsourcing and reports)</li> * (such as wsreader, wswriter, wssubcontracting, manager, hresources, outsourcing and reports)
* * </li>
* <li>Enable/Disable E-mail sending functionality</li> * <li>Enable/Disable E-mail sending functionality</li>
* </ul> * </ul>
* *
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>

View file

@ -69,8 +69,8 @@ import org.libreplan.business.workreports.daos.IWorkReportTypeDAO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** /**
* A registry, AKA service locator, for objects in which dependency injection (DI) is not directly supported by Spring * A registry, AKA service locator, for objects in which dependency injection
* (e.g. entities) must use this class to access DAOs. * (DI) is not directly supported by Spring (e.g. entities) must use this class to access DAOs.
* For the rest of classes (e.g. services, tests, etc.), Spring DI is a more convenient option. * For the rest of classes (e.g. services, tests, etc.), Spring DI is a more convenient option.
* The DAOs or services are added to the registry as needed. * The DAOs or services are added to the registry as needed.
* *
@ -223,8 +223,7 @@ public class Registry {
@Autowired @Autowired
private IAdHocTransactionService transactionServiceDAO; private IAdHocTransactionService transactionServiceDAO;
private Registry() { private Registry() {}
}
public static Registry getInstance() { public static Registry getInstance() {
return singleton; return singleton;

View file

@ -22,7 +22,8 @@ package org.libreplan.business.common;
import java.util.Collection; import java.util.Collection;
/** /**
* Utilities class. <br /> * Utilities class.
* <br />
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
public class Util { public class Util {
@ -34,16 +35,17 @@ public class Util {
if (entity1.getId() == null || entity2.getId() == null) { if (entity1.getId() == null || entity2.getId() == null) {
return false; return false;
} }
return entity1.getId().equals(entity2.getId()); return entity1.getId().equals(entity2.getId());
} }
public static boolean contains(Collection<? extends BaseEntity> collection, public static boolean contains(Collection<? extends BaseEntity> collection, BaseEntity entity) {
BaseEntity entity) {
for (BaseEntity each : collection) { for (BaseEntity each : collection) {
if (each.getId().equals(entity.getId())) { if ( each.getId().equals(entity.getId()) ) {
return true; return true;
} }
} }
return false; return false;
} }

View file

@ -30,13 +30,12 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
/** /**
* It contains the current version of project and implements of singleton * It contains the current version of project and implements of singleton pattern. <br />
* pattern. <br /> * It also has a cached value with information about last project version published.
* It also has a cached value with information about last project version * It checks the last version against a URL.
* published. It checks the last version against a URL.
* *
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public class VersionInformation { public class VersionInformation {
@ -47,14 +46,11 @@ public class VersionInformation {
*/ */
private static final String LIBREPLAN_VERSION_URL = "http://libreplan.org/VERSION"; private static final String LIBREPLAN_VERSION_URL = "http://libreplan.org/VERSION";
private static final String LIBREPLAN_USAGE_STATS_PARAM = "stats";
private static final String LIBREPLAN_VERSION_PARAM = "version";
/** /**
* Delay to wait till we check the URL again * Delay to wait till we check the URL again
*/ */
private static final long DELAY_TO_CHECK_URL = 24 * 60 * 60 * 1000; // 1 day private static final long DELAY_TO_CHECK_URL = 24 * 60 * 60 * 1000L; // 1 day
private static final VersionInformation singleton = new VersionInformation(); private static final VersionInformation singleton = new VersionInformation();
@ -64,31 +60,27 @@ public class VersionInformation {
private Date lastVersionCachedDate = new Date(); private Date lastVersionCachedDate = new Date();
private VersionInformation() { private VersionInformation() {}
}
private void loadNewVersionFromURL() { private void loadNewVersionFromURL() {
lastVersionCachedDate = new Date(); lastVersionCachedDate = new Date();
try { try {
URL url = getURL(); URL url = getURL();
String lastVersion = (new BufferedReader(new InputStreamReader( String lastVersion = (new BufferedReader(new InputStreamReader(url.openStream()))).readLine();
url.openStream()))).readLine();
if (projectVersion != null && lastVersion != null) { if (projectVersion != null && lastVersion != null) {
newVersionCached = !projectVersion.equals(lastVersion); newVersionCached = !projectVersion.equals(lastVersion);
} }
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
LOG.warn("Problems generating URL to check LibrePlan version. MalformedURLException: " LOG.warn("Problems generating URL to check LibrePlan version. MalformedURLException: " + e.getMessage());
+ e.getMessage());
} catch (IOException e) { } catch (IOException e) {
LOG.info("Could not check LibrePlan version information from " LOG.info(
+ LIBREPLAN_VERSION_URL + ". IOException: " "Could not check LibrePlan version information from " +
+ e.getMessage()); LIBREPLAN_VERSION_URL + ". IOException: " + e.getMessage());
} }
} }
private URL getURL() throws MalformedURLException { private URL getURL() throws MalformedURLException {
String url = LIBREPLAN_VERSION_URL; return new URL(LIBREPLAN_VERSION_URL);
return new URL(url);
} }
public static VersionInformation getInstance() { public static VersionInformation getInstance() {
@ -120,13 +112,11 @@ public class VersionInformation {
/** /**
* If there is a new version already detected, it doesn't check it again. * If there is a new version already detected, it doesn't check it again.
* Otherwise, during one day it returns the cached value. And it checks it * Otherwise, during one day it returns the cached value. And it checks it again after that time.
* again after that time.
*/ */
private boolean checkIsNewVersionAvailable() { private boolean checkIsNewVersionAvailable() {
if ( !newVersionCached ) { if ( !newVersionCached ) {
long oneDayLater = lastVersionCachedDate.getTime() long oneDayLater = lastVersionCachedDate.getTime() + DELAY_TO_CHECK_URL;
+ DELAY_TO_CHECK_URL;
if ( oneDayLater < new Date().getTime() ) { if ( oneDayLater < new Date().getTime() ) {
loadNewVersionFromURL(); loadNewVersionFromURL();
} }
@ -138,10 +128,7 @@ public class VersionInformation {
String lastVersion = ""; String lastVersion = "";
try { try {
URL url = new URL(LIBREPLAN_VERSION_URL); URL url = new URL(LIBREPLAN_VERSION_URL);
lastVersion = (new BufferedReader(new InputStreamReader( lastVersion = (new BufferedReader(new InputStreamReader(url.openStream()))).readLine();
url.openStream()))).readLine();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View file

@ -41,12 +41,11 @@ import org.springframework.transaction.annotation.Transactional;
public class ConfigurationDAO extends GenericDAOHibernate<Configuration, Long> implements IConfigurationDAO { public class ConfigurationDAO extends GenericDAOHibernate<Configuration, Long> implements IConfigurationDAO {
@Override @Override
@Transactional(readOnly = true)
public Configuration getConfiguration() { public Configuration getConfiguration() {
List<Configuration> list = list(Configuration.class); List<Configuration> list = list(Configuration.class);
if ( list.isEmpty() ) {
return null; return list.isEmpty() ? null : list.get(0);
}
return list.get(0);
} }
@Override @Override
@ -60,6 +59,7 @@ public class ConfigurationDAO extends GenericDAOHibernate<Configuration, Long> i
public void saveChangedDefaultPassword(String user, boolean change) { public void saveChangedDefaultPassword(String user, boolean change) {
user = user.substring(0, 1).toUpperCase() + user.substring(1).toLowerCase(); user = user.substring(0, 1).toUpperCase() + user.substring(1).toLowerCase();
String sql = "UPDATE Configuration e SET e.changedDefault" + user + "Password = :change"; String sql = "UPDATE Configuration e SET e.changedDefault" + user + "Password = :change";
Query query = getSession().createQuery(sql); Query query = getSession().createQuery(sql);
query.setParameter("change", change); query.setParameter("change", change);
query.executeUpdate(); query.executeUpdate();

View file

@ -40,6 +40,7 @@ import org.springframework.transaction.annotation.Transactional;
/** /**
* DAO for {@link EntitySequence}. * DAO for {@link EntitySequence}.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/ */
@Repository @Repository
@ -53,7 +54,7 @@ public class EntitySequenceDAO extends GenericDAOHibernate<EntitySequence, Long>
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<EntitySequence> findEntitySquencesNotIn(List<EntitySequence> entitySequences) { public List<EntitySequence> findEntitySequencesNotIn(List<EntitySequence> entitySequences) {
List<Long> entitySequenceIds = new ArrayList<>(); List<Long> entitySequenceIds = new ArrayList<>();
for (EntitySequence entitySequence : entitySequences) { for (EntitySequence entitySequence : entitySequences) {
if ( !entitySequence.isNewObject() ) { if ( !entitySequence.isNewObject() ) {
@ -61,8 +62,10 @@ public class EntitySequenceDAO extends GenericDAOHibernate<EntitySequence, Long>
} }
} }
return getSession().createCriteria(EntitySequence.class) return getSession()
.add(Restrictions.not(Restrictions.in("id", entitySequenceIds))).list(); .createCriteria(EntitySequence.class)
.add(Restrictions.not(Restrictions.in("id", entitySequenceIds)))
.list();
} }
@Override @Override

View file

@ -43,9 +43,9 @@ import org.springframework.transaction.annotation.Transactional;
/** /**
* An implementation of <code>IGenericDao</code> based on Hibernate's native API. * An implementation of <code>IGenericDao</code> based on Hibernate's native API.
* Concrete DAOs must extend directly from this class. * Concrete DAOs must extend directly from this class.
* This constraint is imposed by the constructor of this class that must infer the * This constraint is imposed by the constructor of this class that must infer the type of the
* type of the entity from the declaration of the concrete DAO. * entity from the declaration of the concrete DAO.
* <p/> *
* This class autowires a <code>SessionFactory</code> bean and allows to implement DAOs with Hibernate's native API. * This class autowires a <code>SessionFactory</code> bean and allows to implement DAOs with Hibernate's native API.
* Subclasses access Hibernate's <code>Session</code> by calling on <code>getSession()</code> method. * Subclasses access Hibernate's <code>Session</code> by calling on <code>getSession()</code> method.
* Operations must be implemented by catching <code>HibernateException</code> * Operations must be implemented by catching <code>HibernateException</code>
@ -87,8 +87,8 @@ public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable>
/** /**
* It's necessary to save and validate later. * It's necessary to save and validate later.
* *
* Validate may retrieve the entity from DB and put it into the Session, * Validate may retrieve the entity from DB and put it into the Session, which can eventually lead to
* which can eventually lead to a NonUniqueObject exception. * a NonUniqueObject exception.
* Save works here to reattach the object as well as saving. * Save works here to reattach the object as well as saving.
*/ */
public void save(E entity) throws ValidationException { public void save(E entity) throws ValidationException {
@ -96,16 +96,16 @@ public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable>
entity.validate(); entity.validate();
} }
public void saveWithoutValidating(E entity) { public void saveWithoutValidating(E entity) {
getSession().saveOrUpdate(entity); getSession().saveOrUpdate(entity);
} }
public void reattachUnmodifiedEntity(E entity) { public void reattachUnmodifiedEntity(E entity) {
if ( Hibernate.isInitialized(entity) && entity.isNewObject() ) { if ( Hibernate.isInitialized(entity) && entity.isNewObject() ) {
return; return;
} }
// TODO resolve deprecated
getSession().lock(entity, LockMode.NONE); getSession().lock(entity, LockMode.NONE);
} }
public E merge(E entity) { public E merge(E entity) {
@ -114,7 +114,7 @@ public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable>
public void checkVersion(E entity) { public void checkVersion(E entity) {
/* Get id and version from entity. */ /* Get id and version from entity */
Serializable id; Serializable id;
Long versionValueInMemory; Long versionValueInMemory;
@ -138,10 +138,12 @@ public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable>
throw new RuntimeException(e); throw new RuntimeException(e);
} }
/* Check version. */ /* Check version */
Long versionValueInDB = (Long) getSession().createCriteria(entityClass) Long versionValueInDB = (Long) getSession()
.createCriteria(entityClass)
.add(Restrictions.idEq(id)) .add(Restrictions.idEq(id))
.setProjection(Projections.property("version")).uniqueResult(); .setProjection(Projections.property("version"))
.uniqueResult();
if ( versionValueInDB == null ) { if ( versionValueInDB == null ) {
return; return;
@ -159,15 +161,11 @@ public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable>
} }
public void associateToSession(E entity) {
getSession().lock(entity, LockMode.NONE);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Transactional(readOnly = true) @Transactional(readOnly = true)
public E find(PK id) throws InstanceNotFoundException { public E find(PK id) throws InstanceNotFoundException {
E entity = getSession().get(entityClass, id); E entity = (E) getSession().get(entityClass, id);
if ( entity == null ) { if ( entity == null ) {
throw new InstanceNotFoundException(id, entityClass.getName()); throw new InstanceNotFoundException(id, entityClass.getName());
@ -188,7 +186,8 @@ public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable>
public boolean exists(final PK id) { public boolean exists(final PK id) {
return getSession().createCriteria(entityClass) return getSession()
.createCriteria(entityClass)
.add(Restrictions.idEq(id)) .add(Restrictions.idEq(id))
.setProjection(Projections.id()) .setProjection(Projections.id())
.uniqueResult() != null; .uniqueResult() != null;
@ -212,6 +211,7 @@ public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable>
} }
@Override @Override
@Transactional
public void reattach(E entity) { public void reattach(E entity) {
getSession().saveOrUpdate(entity); getSession().saveOrUpdate(entity);
} }

View file

@ -33,6 +33,7 @@ import org.springframework.stereotype.Repository;
/** /**
* DAO interface for {@link EntitySequenceDAO}. * DAO interface for {@link EntitySequenceDAO}.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/ */
@Repository @Repository
@ -41,12 +42,12 @@ public interface IEntitySequenceDAO extends IGenericDAO<EntitySequence, Long> {
List<EntitySequence> getAll(); List<EntitySequence> getAll();
List<EntitySequence> findEntitySquencesNotIn(List<EntitySequence> entitySequences); List<EntitySequence> findEntitySequencesNotIn(List<EntitySequence> entitySequences);
void remove(EntitySequence entitySequence) throws InstanceNotFoundException, IllegalArgumentException; void remove(EntitySequence entitySequence) throws InstanceNotFoundException, IllegalArgumentException;
EntitySequence getActiveEntitySequence(EntityNameEnum entityName) throws InstanceNotFoundException, EntitySequence getActiveEntitySequence(EntityNameEnum entityName)
NonUniqueResultException; throws InstanceNotFoundException, NonUniqueResultException;
String getNextEntityCode(EntityNameEnum entityName); String getNextEntityCode(EntityNameEnum entityName);

View file

@ -25,15 +25,15 @@ import java.util.List;
/** /**
* DAO interface for the <code>Limits</code> entity. * DAO interface for the <code>Limits</code> entity.
* Contract for {@link LimitsDAO} * Contract for {@link LimitsDAO}.
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 17.12.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 17.12.2015.
*/ */
public interface ILimitsDAO extends IGenericDAO<Limits, Long> { public interface ILimitsDAO extends IGenericDAO<Limits, Long> {
List<Limits> getAll(); List<Limits> getAll();
Limits getUsersType(); Limits getUsersType();
Limits getResourcesType(); Limits getResourcesType();
} }

View file

@ -33,13 +33,13 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Default implementation of <code>IIntegrationEntityDAO</code>. DAOs of * Default implementation of <code>IIntegrationEntityDAO</code>.
* entities used in application integration may extend from this interface. * DAOs of entities used in application integration may extend from this interface.
* *
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
*/ */
public class IntegrationEntityDAO<E extends IntegrationEntity> public class IntegrationEntityDAO<E extends IntegrationEntity>
extends GenericDAOHibernate<E, Long> implements IIntegrationEntityDAO<E> { extends GenericDAOHibernate<E, Long> implements IIntegrationEntityDAO<E> {
@Override @Override
public boolean existsByCode(String code) { public boolean existsByCode(String code) {
@ -66,15 +66,15 @@ public class IntegrationEntityDAO<E extends IntegrationEntity>
if (StringUtils.isBlank(code)) { if (StringUtils.isBlank(code)) {
throw new InstanceNotFoundException(null, throw new InstanceNotFoundException(null,
getEntityClass().getName()); getEntityClass().getName());
} }
E entity = (E) getSession().createCriteria(getEntityClass()).add( E entity = (E) getSession().createCriteria(getEntityClass()).add(
Restrictions.eq("code", code.trim()).ignoreCase()).uniqueResult(); Restrictions.eq("code", code.trim()).ignoreCase()).uniqueResult();
if (entity == null) { if (entity == null) {
throw new InstanceNotFoundException( throw new InstanceNotFoundException(
code, getEntityClass().getName()); code, getEntityClass().getName());
} else { } else {
return entity; return entity;
} }
@ -84,7 +84,7 @@ public class IntegrationEntityDAO<E extends IntegrationEntity>
@Override @Override
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW) @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public E findByCodeAnotherTransaction(String code) public E findByCodeAnotherTransaction(String code)
throws InstanceNotFoundException { throws InstanceNotFoundException {
return findByCode(code); return findByCode(code);
@ -104,8 +104,7 @@ public class IntegrationEntityDAO<E extends IntegrationEntity>
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public List<E> findAll() { public List<E> findAll() {
return getSession().createCriteria(getEntityClass()). return getSession().createCriteria(getEntityClass()).addOrder(Order.asc("code")).list();
addOrder(Order.asc("code")).list();
} }
} }

View file

@ -25,11 +25,9 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/** /**
* DAO for {@link Limits} * DAO for {@link Limits}.
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 24.09.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 24.09.15.
*/ */
@Repository @Repository

View file

@ -37,14 +37,10 @@ import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
* @author Cristina Alvarino Perez <cristina.alvarino@comtecsf.es> * @author Cristina Alvarino Perez <cristina.alvarino@comtecsf.es>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es> * @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public class Configuration extends BaseEntity { public class Configuration extends BaseEntity {
public static Configuration create() {
return create(new Configuration());
}
private BaseCalendar defaultCalendar; private BaseCalendar defaultCalendar;
private String companyCode; private String companyCode;
@ -111,6 +107,7 @@ public class Configuration extends BaseEntity {
* Currency code according to ISO-4217 (3 letters) * Currency code according to ISO-4217 (3 letters)
*/ */
private String currencyCode = "EUR"; private String currencyCode = "EUR";
private String currencySymbol = ""; private String currencySymbol = "";
private TypeOfWorkHours personalTimesheetsTypeOfWorkHours; private TypeOfWorkHours personalTimesheetsTypeOfWorkHours;
@ -137,6 +134,10 @@ public class Configuration extends BaseEntity {
private String repositoryLocation; private String repositoryLocation;
public static Configuration create() {
return create(new Configuration());
}
public void setDefaultCalendar(BaseCalendar defaultCalendar) { public void setDefaultCalendar(BaseCalendar defaultCalendar) {
this.defaultCalendar = defaultCalendar; this.defaultCalendar = defaultCalendar;
@ -151,6 +152,7 @@ public class Configuration extends BaseEntity {
if (companyCode != null) { if (companyCode != null) {
companyCode = companyCode.trim(); companyCode = companyCode.trim();
} }
this.companyCode = companyCode; this.companyCode = companyCode;
} }
@ -161,53 +163,30 @@ public class Configuration extends BaseEntity {
@AssertTrue(message = "company code cannot contain whitespaces") @AssertTrue(message = "company code cannot contain whitespaces")
public boolean isCompanyCodeWithoutWhiteSpacesConstraint() { public boolean isCompanyCodeWithoutWhiteSpacesConstraint() {
if ((companyCode == null) || (companyCode.isEmpty())) { return !((companyCode == null) || (companyCode.isEmpty())) && !companyCode.contains(" ");
return false;
}
return !companyCode.contains(" ");
} }
@AssertTrue(message = "host not specified") @AssertTrue(message = "host not specified")
public boolean isLdapHostWithoutWhiteSpacesConstraint() { public boolean isLdapHostWithoutWhiteSpacesConstraint() {
if (getLdapConfiguration().getLdapAuthEnabled()) { return !getLdapConfiguration().getLdapAuthEnabled() || !StringUtils.isBlank(getLdapConfiguration().getLdapHost());
if (StringUtils.isBlank(getLdapConfiguration().getLdapHost())) {
return false;
}
}
return true;
} }
@AssertTrue(message = "port not specified") @AssertTrue(message = "port not specified")
public boolean isLdapPortWithoutWhiteSpacesConstraint() { public boolean isLdapPortWithoutWhiteSpacesConstraint() {
if (getLdapConfiguration().getLdapAuthEnabled()) { return !getLdapConfiguration().getLdapAuthEnabled() || !StringUtils.isBlank(getLdapConfiguration().getLdapPort());
if (StringUtils.isBlank(getLdapConfiguration().getLdapPort())) {
return false;
}
}
return true;
} }
@AssertTrue(message = "base not specified") @AssertTrue(message = "base not specified")
public boolean isLdapBaseWithoutWhiteSpacesConstraint() { public boolean isLdapBaseWithoutWhiteSpacesConstraint() {
if (getLdapConfiguration().getLdapAuthEnabled()) { return !getLdapConfiguration().getLdapAuthEnabled() || !StringUtils.isBlank(getLdapConfiguration().getLdapBase());
if (StringUtils.isBlank(getLdapConfiguration().getLdapBase())) {
return false;
}
}
return true;
} }
@AssertTrue(message = "userId not specified") @AssertTrue(message = "userId not specified")
public boolean isLdapUserIdWithoutWhiteSpacesConstraint() { public boolean isLdapUserIdWithoutWhiteSpacesConstraint() {
if (getLdapConfiguration().getLdapAuthEnabled()) { return !getLdapConfiguration().getLdapAuthEnabled() || !StringUtils.isBlank(getLdapConfiguration().getLdapUserId());
if (StringUtils.isBlank(getLdapConfiguration().getLdapUserId())) {
return false;
}
}
return true;
} }
//TODO 2 added methods follow below
public void setGeneratedCodeForProjectLog(Boolean generateCodeForProjectLog) { public void setGeneratedCodeForProjectLog(Boolean generateCodeForProjectLog) {
this.generateCodeForProjectLog = generateCodeForProjectLog; this.generateCodeForProjectLog = generateCodeForProjectLog;
} }
@ -245,8 +224,7 @@ public class Configuration extends BaseEntity {
return generateCodeForResources; return generateCodeForResources;
} }
public void setGenerateCodeForTypesOfWorkHours( public void setGenerateCodeForTypesOfWorkHours(Boolean generateCodeForTypesOfWorkHours) {
Boolean generateCodeForTypesOfWorkHours) {
this.generateCodeForTypesOfWorkHours = generateCodeForTypesOfWorkHours; this.generateCodeForTypesOfWorkHours = generateCodeForTypesOfWorkHours;
} }
@ -254,8 +232,7 @@ public class Configuration extends BaseEntity {
return generateCodeForTypesOfWorkHours; return generateCodeForTypesOfWorkHours;
} }
public void setGenerateCodeForMaterialCategories( public void setGenerateCodeForMaterialCategories(Boolean generateCodeForMaterialCategories) {
Boolean generateCodeForMaterialCategories) {
this.generateCodeForMaterialCategories = generateCodeForMaterialCategories; this.generateCodeForMaterialCategories = generateCodeForMaterialCategories;
} }
@ -287,8 +264,7 @@ public class Configuration extends BaseEntity {
this.scenariosVisible = scenariosVisible; this.scenariosVisible = scenariosVisible;
} }
public void setGenerateCodeForBaseCalendars( public void setGenerateCodeForBaseCalendars(Boolean generateCodeForBaseCalendars) {
Boolean generateCodeForBaseCalendars) {
this.generateCodeForBaseCalendars = generateCodeForBaseCalendars; this.generateCodeForBaseCalendars = generateCodeForBaseCalendars;
} }
@ -296,8 +272,7 @@ public class Configuration extends BaseEntity {
return generateCodeForBaseCalendars; return generateCodeForBaseCalendars;
} }
public void setGenerateCodeForWorkReportType( public void setGenerateCodeForWorkReportType(Boolean generateCodeForWorkReportType) {
Boolean generateCodeForWorkReportType) {
this.generateCodeForWorkReportType = generateCodeForWorkReportType; this.generateCodeForWorkReportType = generateCodeForWorkReportType;
} }
@ -305,8 +280,7 @@ public class Configuration extends BaseEntity {
return generateCodeForWorkReportType; return generateCodeForWorkReportType;
} }
public void setGenerateCodeForCalendarExceptionType( public void setGenerateCodeForCalendarExceptionType(Boolean generateCodeForCalendarExceptionType) {
Boolean generateCodeForCalendarExceptionType) {
this.generateCodeForCalendarExceptionType = generateCodeForCalendarExceptionType; this.generateCodeForCalendarExceptionType = generateCodeForCalendarExceptionType;
} }
@ -314,8 +288,7 @@ public class Configuration extends BaseEntity {
return this.generateCodeForCalendarExceptionType; return this.generateCodeForCalendarExceptionType;
} }
public void setGenerateCodeForCostCategory( public void setGenerateCodeForCostCategory(Boolean generateCodeForCostCategory) {
Boolean generateCodeForCostCategory) {
this.generateCodeForCostCategory = generateCodeForCostCategory; this.generateCodeForCostCategory = generateCodeForCostCategory;
} }
@ -336,14 +309,14 @@ public class Configuration extends BaseEntity {
} }
public ProgressType getProgressType() { public ProgressType getProgressType() {
return (progressType == null) ? ProgressType.SPREAD_PROGRESS return (progressType == null) ? ProgressType.SPREAD_PROGRESS : progressType;
: progressType;
} }
public void setCompanyLogoURL(String companyLogoURL) { public void setCompanyLogoURL(String companyLogoURL) {
if (companyLogoURL != null) { if (companyLogoURL != null) {
companyLogoURL = companyLogoURL.trim(); companyLogoURL = companyLogoURL.trim();
} }
this.companyLogoURL = companyLogoURL; this.companyLogoURL = companyLogoURL;
} }
@ -351,84 +324,68 @@ public class Configuration extends BaseEntity {
return companyLogoURL; return companyLogoURL;
} }
public void setChangedDefaultAdminPassword( public void setChangedDefaultAdminPassword(Boolean changedDefaultAdminPassword) {
Boolean changedDefaultAdminPassword) {
this.changedDefaultAdminPassword = changedDefaultAdminPassword; this.changedDefaultAdminPassword = changedDefaultAdminPassword;
} }
public Boolean getChangedDefaultAdminPassword() { public Boolean getChangedDefaultAdminPassword() {
return changedDefaultAdminPassword == null ? false return changedDefaultAdminPassword == null ? false : changedDefaultAdminPassword;
: changedDefaultAdminPassword;
} }
public void setChangedDefaultWsreaderPassword( public void setChangedDefaultWsreaderPassword(Boolean changedDefaultWsreaderPassword) {
Boolean changedDefaultWsreaderPassword) {
this.changedDefaultWsreaderPassword = changedDefaultWsreaderPassword; this.changedDefaultWsreaderPassword = changedDefaultWsreaderPassword;
} }
public Boolean getChangedDefaultWsreaderPassword() { public Boolean getChangedDefaultWsreaderPassword() {
return changedDefaultWsreaderPassword != null ? changedDefaultWsreaderPassword return changedDefaultWsreaderPassword != null ? changedDefaultWsreaderPassword : false;
: false;
} }
public void setChangedDefaultWswriterPassword( public void setChangedDefaultWswriterPassword(Boolean changedDefaultWswriterPassword) {
Boolean changedDefaultWswriterPassword) {
this.changedDefaultWswriterPassword = changedDefaultWswriterPassword; this.changedDefaultWswriterPassword = changedDefaultWswriterPassword;
} }
public Boolean getChangedDefaultWswriterPassword() { public Boolean getChangedDefaultWswriterPassword() {
return changedDefaultWswriterPassword != null ? changedDefaultWswriterPassword return changedDefaultWswriterPassword != null ? changedDefaultWswriterPassword : false;
: false;
} }
public void setChangedDefaultWssubcontractingPassword( public void setChangedDefaultWssubcontractingPassword(Boolean changedDefaultWssubcontractingPassword) {
Boolean changedDefaultWssubcontractingPassword) {
this.changedDefaultWssubcontractingPassword = changedDefaultWssubcontractingPassword; this.changedDefaultWssubcontractingPassword = changedDefaultWssubcontractingPassword;
} }
public Boolean getChangedDefaultWssubcontractingPassword() { public Boolean getChangedDefaultWssubcontractingPassword() {
return changedDefaultWssubcontractingPassword != null ? changedDefaultWssubcontractingPassword return changedDefaultWssubcontractingPassword != null ? changedDefaultWssubcontractingPassword : false;
: false;
} }
public void setChangedDefaultManagerPassword( public void setChangedDefaultManagerPassword(Boolean changedDefaultManagerPassword) {
Boolean changedDefaultManagerPassword) {
this.changedDefaultManagerPassword = changedDefaultManagerPassword; this.changedDefaultManagerPassword = changedDefaultManagerPassword;
} }
public Boolean getChangedDefaultManagerPassword() { public Boolean getChangedDefaultManagerPassword() {
return changedDefaultManagerPassword != null ? changedDefaultManagerPassword return changedDefaultManagerPassword != null ? changedDefaultManagerPassword : false;
: false;
} }
public void setChangedDefaultHresourcesPassword( public void setChangedDefaultHresourcesPassword(Boolean changedDefaultHresourcesPassword) {
Boolean changedDefaultHresourcesPassword) {
this.changedDefaultHresourcesPassword = changedDefaultHresourcesPassword; this.changedDefaultHresourcesPassword = changedDefaultHresourcesPassword;
} }
public Boolean getChangedDefaultHresourcesPassword() { public Boolean getChangedDefaultHresourcesPassword() {
return changedDefaultHresourcesPassword != null ? changedDefaultHresourcesPassword return changedDefaultHresourcesPassword != null ? changedDefaultHresourcesPassword : false;
: false;
} }
public void setChangedDefaultOutsourcingPassword( public void setChangedDefaultOutsourcingPassword(Boolean changedDefaultOutsourcingPassword) {
Boolean changedDefaultOutsourcingPassword) {
this.changedDefaultOutsourcingPassword = changedDefaultOutsourcingPassword; this.changedDefaultOutsourcingPassword = changedDefaultOutsourcingPassword;
} }
public Boolean getChangedDefaultOutsourcingPassword() { public Boolean getChangedDefaultOutsourcingPassword() {
return changedDefaultOutsourcingPassword != null ? changedDefaultOutsourcingPassword return changedDefaultOutsourcingPassword != null ? changedDefaultOutsourcingPassword : false;
: false;
} }
public void setChangedDefaultReportsPassword( public void setChangedDefaultReportsPassword(Boolean changedDefaultReportsPassword) {
Boolean changedDefaultReportsPassword) {
this.changedDefaultReportsPassword = changedDefaultReportsPassword; this.changedDefaultReportsPassword = changedDefaultReportsPassword;
} }
public Boolean getChangedDefaultReportsPassword() { public Boolean getChangedDefaultReportsPassword() {
return changedDefaultReportsPassword != null ? changedDefaultReportsPassword return changedDefaultReportsPassword != null ? changedDefaultReportsPassword : false;
: false;
} }
public LDAPConfiguration getLdapConfiguration() { public LDAPConfiguration getLdapConfiguration() {
@ -455,13 +412,11 @@ public class Configuration extends BaseEntity {
this.checkNewVersionEnabled = checkNewVersionEnabled; this.checkNewVersionEnabled = checkNewVersionEnabled;
} }
public boolean isAllowToGatherUsageStatsEnabled() { public boolean isAllowedToGatherUsageStatsEnabled() {
return allowToGatherUsageStatsEnabled != null ? allowToGatherUsageStatsEnabled return allowToGatherUsageStatsEnabled != null ? allowToGatherUsageStatsEnabled : false;
: false;
} }
public void setAllowToGatherUsageStatsEnabled( public void setAllowToGatherUsageStatsEnabled(boolean allowToGatherUsageStatsEnabled) {
boolean allowToGatherUsageStatsEnabled) {
this.allowToGatherUsageStatsEnabled = allowToGatherUsageStatsEnabled; this.allowToGatherUsageStatsEnabled = allowToGatherUsageStatsEnabled;
} }
@ -487,8 +442,7 @@ public class Configuration extends BaseEntity {
return personalTimesheetsTypeOfWorkHours; return personalTimesheetsTypeOfWorkHours;
} }
public void setPersonalTimesheetsTypeOfWorkHours( public void setPersonalTimesheetsTypeOfWorkHours(TypeOfWorkHours typeOfWorkHours) {
TypeOfWorkHours typeOfWorkHours) {
personalTimesheetsTypeOfWorkHours = typeOfWorkHours; personalTimesheetsTypeOfWorkHours = typeOfWorkHours;
} }
@ -504,8 +458,7 @@ public class Configuration extends BaseEntity {
return personalTimesheetsPeriodicity; return personalTimesheetsPeriodicity;
} }
public void setPersonalTimesheetsPeriodicity( public void setPersonalTimesheetsPeriodicity(PersonalTimesheetsPeriodicityEnum personalTimesheetsPeriodicity) {
PersonalTimesheetsPeriodicityEnum personalTimesheetsPeriodicity) {
this.personalTimesheetsPeriodicity = personalTimesheetsPeriodicity; this.personalTimesheetsPeriodicity = personalTimesheetsPeriodicity;
} }
@ -538,6 +491,7 @@ public class Configuration extends BaseEntity {
public String getRepositoryLocation() { public String getRepositoryLocation() {
return repositoryLocation; return repositoryLocation;
} }
public void setRepositoryLocation(String repositoryLocation) { public void setRepositoryLocation(String repositoryLocation) {
this.repositoryLocation = repositoryLocation; this.repositoryLocation = repositoryLocation;
} }

View file

@ -35,17 +35,18 @@ import org.libreplan.business.common.daos.IConfigurationDAO;
import org.libreplan.business.common.daos.IEntitySequenceDAO; import org.libreplan.business.common.daos.IEntitySequenceDAO;
import org.libreplan.business.workingday.EffortDuration; import org.libreplan.business.workingday.EffortDuration;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Creates a default {@link Configuration} with default values. It also creates * Creates a default {@link Configuration} with default values.
* a default {@link OrderSequence}. *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
@BootstrapOrder(-1) @BootstrapOrder(-1)
public class ConfigurationBootstrap implements IConfigurationBootstrap { public class ConfigurationBootstrap implements IConfigurationBootstrap {
@ -94,9 +95,9 @@ public class ConfigurationBootstrap implements IConfigurationBootstrap {
} }
private Map<EntityNameEnum, List<EntitySequence>> initEntitySequences() { private Map<EntityNameEnum, List<EntitySequence>> initEntitySequences() {
Map<EntityNameEnum, List<EntitySequence>> entitySequences = new HashMap<EntityNameEnum, List<EntitySequence>>(); Map<EntityNameEnum, List<EntitySequence>> entitySequences = new HashMap<>();
for (EntityNameEnum entityName : EntityNameEnum.values()) { for (EntityNameEnum entityName : EntityNameEnum.values()) {
entitySequences.put(entityName, new ArrayList<EntitySequence>()); entitySequences.put(entityName, new ArrayList<>());
} }
for (EntitySequence entitySequence : entitySequenceDAO.getAll()) { for (EntitySequence entitySequence : entitySequenceDAO.getAll()) {
entitySequences.get(entitySequence.getEntityName()).add( entitySequences.get(entitySequence.getEntityName()).add(

View file

@ -27,29 +27,28 @@ import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
import org.libreplan.business.costcategories.entities.TypeOfWorkHoursBootstrap; import org.libreplan.business.costcategories.entities.TypeOfWorkHoursBootstrap;
import org.libreplan.business.workreports.entities.PredefinedWorkReportTypes; import org.libreplan.business.workreports.entities.PredefinedWorkReportTypes;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Fills the attributes {@link Configuration#personalTimesheetsTypeOfWorkHours} * Fills the attributes {@link Configuration#personalTimesheetsTypeOfWorkHours} with a default values.
* and {@link JiraConfiguration#jiraConnectorTypeOfWorkHours} with a default * <br />
* values.<br />
* *
* If possible it uses the "Default" {@link TypeOfWorkHours}, but if it doesn't * If possible it uses the "Default" {@link TypeOfWorkHours}, but if it doesn't
* exist, it uses the first {@link TypeOfWorkHours} found.<br /> * exist, it uses the first {@link TypeOfWorkHours} found.
* <br />
* *
* This bootstrap have to be executed after {@link ConfigurationBootstrap} and * This bootstrap have to be executed after {@link ConfigurationBootstrap} and
* {@link TypeOfWorkHoursBootstrap}, this is why it's marked with * {@link TypeOfWorkHoursBootstrap}, this is why it's marked with {@link BootstrapOrder BootstrapOrder(1)}.
* {@link BootstrapOrder BootstrapOrder(1)}.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
@BootstrapOrder(1) @BootstrapOrder(1)
public class ConfigurationTypeOfWorkHoursBootstrap implements public class ConfigurationTypeOfWorkHoursBootstrap implements IConfigurationTypeOfWorkHoursBootstrap {
IConfigurationTypeOfWorkHoursBootstrap {
@Autowired @Autowired
private IConfigurationDAO configurationDAO; private IConfigurationDAO configurationDAO;
@ -63,13 +62,10 @@ public class ConfigurationTypeOfWorkHoursBootstrap implements
Configuration configuration = configurationDAO.getConfiguration(); Configuration configuration = configurationDAO.getConfiguration();
// TypeOfWorkHoursBootstrap creates the TypeOfWorkHours objects // TypeOfWorkHoursBootstrap creates the TypeOfWorkHours objects
// specified by PredefinedWorkReportTypes if there isn't any // specified by PredefinedWorkReportTypes if there isn't any TypeOfWorkHours in the database
// TypeOfWorkHours in the database
TypeOfWorkHours typeOfWorkHours; TypeOfWorkHours typeOfWorkHours;
try { try {
typeOfWorkHours = typeOfWorkHoursDAO typeOfWorkHours = typeOfWorkHoursDAO.findUniqueByName(PredefinedWorkReportTypes.DEFAULT.getName());
.findUniqueByName(PredefinedWorkReportTypes.DEFAULT
.getName());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
typeOfWorkHours = typeOfWorkHoursDAO.findActive().get(0); typeOfWorkHours = typeOfWorkHoursDAO.findActive().get(0);
} }

View file

@ -21,6 +21,7 @@ package org.libreplan.business.common.entities;
import org.libreplan.business.common.daos.IConnectorDAO; import org.libreplan.business.common.daos.IConnectorDAO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -32,7 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class ConnectorBootstrap implements IConnectorBootstrap { public class ConnectorBootstrap implements IConnectorBootstrap {
@Autowired @Autowired

View file

@ -21,11 +21,10 @@ package org.libreplan.business.common.entities;
/** /**
* Defines the job class package and name to be used as data type in * Defines the job class package and name to be used as data type in {@link JobSchedulerConfiguration}.
* {@link JobSchedulerConfiguration}
* *
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl> * @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public enum JobClassNameEnum { public enum JobClassNameEnum {
@ -43,7 +42,7 @@ public enum JobClassNameEnum {
private String packageName; private String packageName;
private String name; private String name;
private JobClassNameEnum(String packageName, String name) { JobClassNameEnum(String packageName, String name) {
this.packageName = packageName; this.packageName = packageName;
this.name = name; this.name = name;
} }

View file

@ -26,11 +26,9 @@ import org.libreplan.business.common.BaseEntity;
* This class is intended to work as a Hibernate component. * This class is intended to work as a Hibernate component.
* It represents the limit that can be modified only in database. * It represents the limit that can be modified only in database.
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 17.12.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 17.12.2015.
*/ */
public class Limits extends BaseEntity{ public class Limits extends BaseEntity {
private String type; private String type;

View file

@ -22,12 +22,11 @@ package org.libreplan.business.common.entities;
import static org.libreplan.business.i18n.I18nHelper._; import static org.libreplan.business.i18n.I18nHelper._;
/** /**
* Simply class to keep constants of {@link ConnectorProperty properties} for * Simply class to keep constants of {@link ConnectorProperty properties} for LibrePlan {@link Connector connectors}.
* LibrePlan {@link Connector connectors}.
* *
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl> * @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public class PredefinedConnectorProperties { public class PredefinedConnectorProperties {

View file

@ -23,35 +23,32 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
* Defines the LibrePlan {@link Connector Connectors} together with its * Defines the LibrePlan {@link Connector Connectors} together with its configuration properties.
* configuration properties.
* *
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl> * @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public enum PredefinedConnectors { public enum PredefinedConnectors {
TIM("Tim", TIM("Tim",
ConnectorProperty.create(PredefinedConnectorProperties.ACTIVATED, "N"), ConnectorProperty.create(PredefinedConnectorProperties.ACTIVATED, "N"),
ConnectorProperty.create(PredefinedConnectorProperties.SERVER_URL, ""), ConnectorProperty.create(PredefinedConnectorProperties.SERVER_URL, ""),
ConnectorProperty.create(PredefinedConnectorProperties.USERNAME, ""), ConnectorProperty.create(PredefinedConnectorProperties.USERNAME, ""),
ConnectorProperty.create(PredefinedConnectorProperties.PASSWORD, ""), ConnectorProperty.create(PredefinedConnectorProperties.PASSWORD, ""),
ConnectorProperty.create(PredefinedConnectorProperties.TIM_NR_DAYS_TIMESHEET, "7"), ConnectorProperty.create(PredefinedConnectorProperties.TIM_NR_DAYS_TIMESHEET, "7"),
ConnectorProperty.create(PredefinedConnectorProperties.TIM_NR_DAYS_ROSTER, "90"), ConnectorProperty.create(PredefinedConnectorProperties.TIM_NR_DAYS_ROSTER, "90"),
ConnectorProperty.create(PredefinedConnectorProperties.TIM_PRODUCTIVITY_FACTOR, "100"), ConnectorProperty.create(PredefinedConnectorProperties.TIM_PRODUCTIVITY_FACTOR, "100"),
ConnectorProperty.create( ConnectorProperty.create(PredefinedConnectorProperties.TIM_DEPARTAMENTS_IMPORT_ROSTER, "0")),
PredefinedConnectorProperties.TIM_DEPARTAMENTS_IMPORT_ROSTER,
"0")),
JIRA("Jira", JIRA("Jira",
ConnectorProperty.create(PredefinedConnectorProperties.ACTIVATED, "N"), ConnectorProperty.create(PredefinedConnectorProperties.ACTIVATED, "N"),
ConnectorProperty.create(PredefinedConnectorProperties.SERVER_URL, ""), ConnectorProperty.create(PredefinedConnectorProperties.SERVER_URL, ""),
ConnectorProperty.create(PredefinedConnectorProperties.USERNAME, ""), ConnectorProperty.create(PredefinedConnectorProperties.USERNAME, ""),
ConnectorProperty.create(PredefinedConnectorProperties.PASSWORD, ""), ConnectorProperty.create(PredefinedConnectorProperties.PASSWORD, ""),
ConnectorProperty ConnectorProperty.create(PredefinedConnectorProperties.JIRA_LABELS, ""),
.create(PredefinedConnectorProperties.JIRA_LABELS, ""), ConnectorProperty.create(PredefinedConnectorProperties.JIRA_HOURS_TYPE, "Default")),
ConnectorProperty.create(
PredefinedConnectorProperties.JIRA_HOURS_TYPE, "Default")),
EMAIL("E-mail", EMAIL("E-mail",
ConnectorProperty.create(PredefinedConnectorProperties.ACTIVATED, "N"), ConnectorProperty.create(PredefinedConnectorProperties.ACTIVATED, "N"),
ConnectorProperty.create(PredefinedConnectorProperties.PROTOCOL, ""), ConnectorProperty.create(PredefinedConnectorProperties.PROTOCOL, ""),
@ -64,10 +61,10 @@ public enum PredefinedConnectors {
); );
private String name; private String name;
private List<ConnectorProperty> properties; private List<ConnectorProperty> properties;
private PredefinedConnectors(String name, PredefinedConnectors(String name, ConnectorProperty... properties) {
ConnectorProperty... properties) {
this.name = name; this.name = name;
this.properties = Arrays.asList(properties); this.properties = Arrays.asList(properties);
} }

View file

@ -26,19 +26,17 @@ package org.libreplan.business.common.exceptions;
* It contains a message, the key of the instance, and its class name. * It contains a message, the key of the instance, and its class name.
* *
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
*
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public abstract class InstanceException extends Exception { public abstract class InstanceException extends Exception {
private Object key; private final Object key;
private String className;
protected InstanceException(String specificMessage, Object key, private final String className;
String className) {
super(specificMessage + " (key = '" + key + "' - className = '" + protected InstanceException(String specificMessage, Object key, String className) {
className + "')");
super(specificMessage + " (key = '" + key + "' - className = '" + className + "')");
this.key = key; this.key = key;
this.className = className; this.className = className;

View file

@ -23,6 +23,7 @@ import org.libreplan.business.common.daos.IEntitySequenceDAO;
import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.entities.EntityNameEnum;
import org.libreplan.business.costcategories.daos.ITypeOfWorkHoursDAO; import org.libreplan.business.costcategories.daos.ITypeOfWorkHoursDAO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -33,7 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Ignacio Díaz Teijido <ignacio.diaz@cafedered.com> * @author Ignacio Díaz Teijido <ignacio.diaz@cafedered.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class TypeOfWorkHoursBootstrap implements ITypeOfWorkHoursBootstrap { public class TypeOfWorkHoursBootstrap implements ITypeOfWorkHoursBootstrap {
@Autowired @Autowired
@ -46,10 +47,8 @@ public class TypeOfWorkHoursBootstrap implements ITypeOfWorkHoursBootstrap {
@Transactional @Transactional
public void loadRequiredData() { public void loadRequiredData() {
if (typeOfWorkHoursDAO.findActive().size() == 0) { if (typeOfWorkHoursDAO.findActive().size() == 0) {
for (PredefinedTypeOfWorkHours predefinedTypeOfWorkHours : PredefinedTypeOfWorkHours for (PredefinedTypeOfWorkHours predefinedTypeOfWorkHours : PredefinedTypeOfWorkHours.values()) {
.values()) { TypeOfWorkHours typeOfWorkHours = predefinedTypeOfWorkHours.getTypeOfWorkHours();
TypeOfWorkHours typeOfWorkHours = predefinedTypeOfWorkHours
.getTypeOfWorkHours();
typeOfWorkHours.setCodeAutogenerated(true); typeOfWorkHours.setCodeAutogenerated(true);
typeOfWorkHours typeOfWorkHours
.setCode(entitySequenceDAO .setCode(entitySequenceDAO

View file

@ -30,7 +30,7 @@ import java.util.List;
/** /**
* Dao for {@link EmailNotification} * Dao for {@link EmailNotification}
* *
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 19.10.2015. * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 19.10.2015.
*/ */
@Repository @Repository
public class EmailNotificationDAO public class EmailNotificationDAO

View file

@ -33,7 +33,7 @@ import java.util.List;
/** /**
* DAO for {@link EmailTemplate} * DAO for {@link EmailTemplate}
* *
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 24.09.2015. * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 24.09.2015.
*/ */
@Repository @Repository
public class EmailTemplateDAO extends GenericDAOHibernate<EmailTemplate, Long> implements IEmailTemplateDAO{ public class EmailTemplateDAO extends GenericDAOHibernate<EmailTemplate, Long> implements IEmailTemplateDAO{
@ -68,7 +68,6 @@ public class EmailTemplateDAO extends GenericDAOHibernate<EmailTemplate, Long> i
public void delete(EmailTemplate entity) { public void delete(EmailTemplate entity) {
try { try {
remove(entity.getId()); remove(entity.getId());
} catch (InstanceNotFoundException ignored) { } catch (InstanceNotFoundException ignored) {}
}
} }
} }

View file

@ -28,7 +28,7 @@ import java.util.List;
/** /**
* Contract for {@link EmailNotificationDAO} * Contract for {@link EmailNotificationDAO}
* *
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 19.10.2015. * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 19.10.2015.
*/ */
public interface IEmailNotificationDAO extends IGenericDAO<EmailNotification, Long> { public interface IEmailNotificationDAO extends IGenericDAO<EmailNotification, Long> {

View file

@ -28,9 +28,9 @@ import java.util.List;
/** /**
* DAO interface for the <code>EmailTemplate</code> entity. * DAO interface for the <code>EmailTemplate</code> entity.
* Contract for {@link EmailTemplateDAO} * Contract for {@link EmailTemplateDAO}.
* *
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 29.09.2015. * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 29.09.2015.
*/ */
public interface IEmailTemplateDAO extends IGenericDAO<EmailTemplate, Long>{ public interface IEmailTemplateDAO extends IGenericDAO<EmailTemplate, Long>{

View file

@ -24,7 +24,7 @@ import java.util.Date;
import org.libreplan.business.common.BaseEntity; import org.libreplan.business.common.BaseEntity;
/** /**
* Entity EndDateCommunication * Entity EndDateCommunication.
* *
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/ */
@ -46,8 +46,7 @@ public class EndDateCommunication extends BaseEntity {
this.setSaveDate(new Date()); this.setSaveDate(new Date());
} }
protected EndDateCommunication(Date saveDate, Date endDate, protected EndDateCommunication(Date saveDate, Date endDate, Date communicationDate) {
Date communicationDate) {
this.setSaveDate(saveDate); this.setSaveDate(saveDate);
this.setEndDate(endDate); this.setEndDate(endDate);
this.setCommunicationDate(communicationDate); this.setCommunicationDate(communicationDate);
@ -61,8 +60,7 @@ public class EndDateCommunication extends BaseEntity {
return create(new EndDateCommunication(endDate)); return create(new EndDateCommunication(endDate));
} }
public static EndDateCommunication create(Date saveDate, Date endDate, public static EndDateCommunication create(Date saveDate, Date endDate, Date communicationDate) {
Date communicationDate) {
return create(new EndDateCommunication(saveDate, endDate, communicationDate)); return create(new EndDateCommunication(saveDate, endDate, communicationDate));
} }

View file

@ -32,12 +32,11 @@ import org.libreplan.business.externalcompanies.daos.IExternalCompanyDAO;
import org.libreplan.business.users.entities.User; import org.libreplan.business.users.entities.User;
/** /**
* Entity ExternalCompany * Entity ExternalCompany.
* *
* @author Jacobo Aragunde Perez <jaragunde@igalia.com> * @author Jacobo Aragunde Perez <jaragunde@igalia.com>
*/ */
public class ExternalCompany extends BaseEntity implements IHumanIdentifiable, public class ExternalCompany extends BaseEntity implements IHumanIdentifiable, Comparable<ExternalCompany> {
Comparable<ExternalCompany> {
private String name; private String name;
@ -60,7 +59,7 @@ public class ExternalCompany extends BaseEntity implements IHumanIdentifiable,
protected ExternalCompany() {} protected ExternalCompany() {}
public static ExternalCompany create() { public static ExternalCompany create() {
return (ExternalCompany) create(new ExternalCompany()); return create(new ExternalCompany());
} }
protected ExternalCompany(String name, String nif) { protected ExternalCompany(String name, String nif) {
@ -69,7 +68,7 @@ public class ExternalCompany extends BaseEntity implements IHumanIdentifiable,
} }
public static ExternalCompany create(String name, String nif) { public static ExternalCompany create(String name, String nif) {
return (ExternalCompany) create(new ExternalCompany(name,nif)); return create(new ExternalCompany(name,nif));
} }
public void setName(String name) { public void setName(String name) {
@ -154,8 +153,8 @@ public class ExternalCompany extends BaseEntity implements IHumanIdentifiable,
return !dao.existsByNameInAnotherTransaction(name); return !dao.existsByNameInAnotherTransaction(name);
} else { } else {
try { try {
ExternalCompany company = ExternalCompany company = dao.findUniqueByNameInAnotherTransaction(name);
dao.findUniqueByNameInAnotherTransaction(name);
return company.getId().equals(getId()); return company.getId().equals(getId());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
return true; return true;
@ -171,8 +170,8 @@ public class ExternalCompany extends BaseEntity implements IHumanIdentifiable,
return !dao.existsByNifInAnotherTransaction(nif); return !dao.existsByNifInAnotherTransaction(nif);
} else { } else {
try { try {
ExternalCompany company = ExternalCompany company = dao.findUniqueByNifInAnotherTransaction(nif);
dao.findUniqueByNifInAnotherTransaction(nif);
return company.getId().equals(getId()); return company.getId().equals(getId());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
return true; return true;
@ -182,13 +181,9 @@ public class ExternalCompany extends BaseEntity implements IHumanIdentifiable,
@AssertTrue(message = "interaction fields are empty and company is marked as interact with applications") @AssertTrue(message = "interaction fields are empty and company is marked as interact with applications")
public boolean isInteractionFieldsNotEmptyIfNeededConstraint() { public boolean isInteractionFieldsNotEmptyIfNeededConstraint() {
if (!interactsWithApplications) { return !interactsWithApplications || !StringUtils.isEmpty(appURI) && !StringUtils.isEmpty(ourCompanyLogin) &&
return true; !StringUtils.isEmpty(ourCompanyPassword);
}
return !StringUtils.isEmpty(appURI)
&& !StringUtils.isEmpty(ourCompanyLogin)
&& !StringUtils.isEmpty(ourCompanyPassword);
} }
@Override @Override

View file

@ -23,18 +23,23 @@ package org.libreplan.business.i18n;
/** /**
* This class provides a function to mark strings to be translated. Real * This class provides a function to mark strings to be translated.
* translation have to be done in webapp module depending on user language and * Real translation have to be done in webapp module depending on user language and
* not done here depending on server language. * not done here depending on server language.
* *
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
*/ */
public class I18nHelper { public class I18nHelper {
private I18nHelper() { private I18nHelper() {}
}
//TODO It should be changed since JDK9.
/**
* Use of '_' as an identifier might not be supported in releases after Java SE 8.
*
* @param str
* @return Text depends on locale
*/
public static String _(String text) { public static String _(String text) {
return text; return text;
} }

View file

@ -23,6 +23,7 @@ import org.libreplan.business.common.daos.IEntitySequenceDAO;
import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.entities.EntityNameEnum;
import org.libreplan.business.labels.daos.ILabelTypeDAO; import org.libreplan.business.labels.daos.ILabelTypeDAO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -33,7 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Ignacio Díaz Teijido <ignacio.diaz@cafedered.com> * @author Ignacio Díaz Teijido <ignacio.diaz@cafedered.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class LabelBootstrap implements ILabelBootstrap { public class LabelBootstrap implements ILabelBootstrap {
@Autowired @Autowired
@ -45,17 +46,16 @@ public class LabelBootstrap implements ILabelBootstrap {
@Override @Override
@Transactional @Transactional
public void loadRequiredData() { public void loadRequiredData() {
if (labelTypeDAO.getAll().size() == 0) { if (labelTypeDAO.getAll().isEmpty()) {
LabelType priorityType = LabelType.create("Priority"); LabelType priorityType = LabelType.create("Priority");
priorityType.setCodeAutogenerated(true); priorityType.setCodeAutogenerated(true);
priorityType.setCode(entitySequenceDAO priorityType.setCode(entitySequenceDAO.getNextEntityCodeWithoutTransaction(EntityNameEnum.LABEL));
.getNextEntityCodeWithoutTransaction(EntityNameEnum.LABEL));
for (PredefinedLabels predefinedLabel : PredefinedLabels.values()) { for (PredefinedLabels predefinedLabel : PredefinedLabels.values()) {
Label label = predefinedLabel.getLabel(); Label label = predefinedLabel.getLabel();
priorityType.addLabel(label); priorityType.addLabel(label);
} }
priorityType.generateLabelCodes(entitySequenceDAO priorityType.generateLabelCodes(entitySequenceDAO.getNumberOfDigitsCode(EntityNameEnum.LABEL));
.getNumberOfDigitsCode(EntityNameEnum.LABEL));
labelTypeDAO.save(priorityType); labelTypeDAO.save(priorityType);
} }

View file

@ -27,22 +27,30 @@ import org.libreplan.business.common.daos.IIntegrationEntityDAO;
import org.libreplan.business.users.entities.User; import org.libreplan.business.users.entities.User;
/** /**
* IssueLog entity, represents parameters to be able to administrate issues that * IssueLog entity, represents parameters to be able to administrate issues that come up in the project.
* come up in the project
* *
* @author Misha Gozhda <misha@libreplan-enterprise.com> * @author Misha Gozhda <misha@libreplan-enterprise.com>
*/ */
public class IssueLog extends ProjectLog { public class IssueLog extends ProjectLog {
private IssueTypeEnum type = IssueTypeEnum.getDefault(); private IssueTypeEnum type = IssueTypeEnum.getDefault();
private String status = "LOW"; private String status = "LOW";
private LowMediumHighEnum priority = LowMediumHighEnum.getDefault(); private LowMediumHighEnum priority = LowMediumHighEnum.getDefault();
private LowMediumHighEnum severity = LowMediumHighEnum.getDefault(); private LowMediumHighEnum severity = LowMediumHighEnum.getDefault();
private Date dateRaised; private Date dateRaised;
private User createdBy; private User createdBy;
private String assignedTo; private String assignedTo;
private Date dateResolved; private Date dateResolved;
private Date deadline; private Date deadline;
private String notes; private String notes;
@ -151,7 +159,6 @@ public class IssueLog extends ProjectLog {
@Override @Override
protected IIntegrationEntityDAO<? extends IntegrationEntity> getIntegrationEntityDAO() { protected IIntegrationEntityDAO<? extends IntegrationEntity> getIntegrationEntityDAO() {
return (IIntegrationEntityDAO<? extends IntegrationEntity>) Registry return Registry.getIssueLogDAO();
.getIssueLogDAO();
} }
} }

View file

@ -27,24 +27,34 @@ import org.libreplan.business.users.entities.User;
import java.util.Date; import java.util.Date;
/** /**
* RiskLog entity, represents parameters to be able to administrate risks that * RiskLog entity, represents parameters to be able to administrate risks that come up in the project.
* come up in the project
* *
* @author Misha Gozhda <misha@libreplan-enterprise.com> * @author Misha Gozhda <misha@libreplan-enterprise.com>
*/ */
public class RiskLog extends ProjectLog { public class RiskLog extends ProjectLog {
private String projectName; private String projectName;
private String status; private String status;
private LowMediumHighEnum probability = LowMediumHighEnum.getDefault(); private LowMediumHighEnum probability = LowMediumHighEnum.getDefault();
private LowMediumHighEnum impact = LowMediumHighEnum.getDefault(); private LowMediumHighEnum impact = LowMediumHighEnum.getDefault();
private Date dateCreated; private Date dateCreated;
private User createdBy; private User createdBy;
private String counterMeasures; private String counterMeasures;
private String contingency; private String contingency;
private String responsible; private String responsible;
private Date actionWhen; private Date actionWhen;
private String notes; private String notes;
private RiskScoreStatesEnum score = RiskScoreStatesEnum.getDefault(); private RiskScoreStatesEnum score = RiskScoreStatesEnum.getDefault();
public static RiskLog create() { public static RiskLog create() {
@ -169,8 +179,7 @@ public class RiskLog extends ProjectLog {
@Override @Override
protected IIntegrationEntityDAO<? extends IntegrationEntity> getIntegrationEntityDAO() { protected IIntegrationEntityDAO<? extends IntegrationEntity> getIntegrationEntityDAO() {
return (IIntegrationEntityDAO<? extends IntegrationEntity>) Registry return Registry.getRiskLogDAO();
.getRiskLogDAO();
} }
} }

View file

@ -27,6 +27,7 @@ import org.libreplan.business.common.entities.EntityNameEnum;
import org.libreplan.business.materials.daos.IMaterialCategoryDAO; import org.libreplan.business.materials.daos.IMaterialCategoryDAO;
import org.libreplan.business.materials.entities.MaterialCategory; import org.libreplan.business.materials.entities.MaterialCategory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -37,7 +38,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class MaterialCategoryBootstrap implements IMaterialCategoryBootstrap { public class MaterialCategoryBootstrap implements IMaterialCategoryBootstrap {
@Autowired @Autowired
@ -49,13 +50,10 @@ public class MaterialCategoryBootstrap implements IMaterialCategoryBootstrap {
@Override @Override
@Transactional @Transactional
public void loadRequiredData() { public void loadRequiredData() {
for (PredefinedMaterialCategories predefinedMaterialCategory : PredefinedMaterialCategories for (PredefinedMaterialCategories predefinedMaterialCategory : PredefinedMaterialCategories.values()) {
.values()) {
if (!materialCategoryDAO if (!materialCategoryDAO
.existsMaterialCategoryWithNameInAnotherTransaction(predefinedMaterialCategory .existsMaterialCategoryWithNameInAnotherTransaction(predefinedMaterialCategory.getName())) {
.getName())) { MaterialCategory materialCategory = predefinedMaterialCategory.createMaterialCategory();
MaterialCategory materialCategory = predefinedMaterialCategory
.createMaterialCategory();
materialCategory materialCategory
.setCode(entitySequenceDAO .setCode(entitySequenceDAO
.getNextEntityCodeWithoutTransaction(EntityNameEnum.MATERIAL_CATEGORY)); .getNextEntityCodeWithoutTransaction(EntityNameEnum.MATERIAL_CATEGORY));

View file

@ -28,17 +28,19 @@ import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.materials.daos.IUnitTypeDAO; import org.libreplan.business.materials.daos.IUnitTypeDAO;
import org.libreplan.business.materials.entities.UnitType; import org.libreplan.business.materials.entities.UnitType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Creates the bootstrap of the predefined {@link UnitType}. * Creates the bootstrap of the predefined {@link UnitType}.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class UnitTypeBootstrap implements IDataBootstrap { public class UnitTypeBootstrap implements IDataBootstrap {
@Autowired @Autowired
@ -52,24 +54,21 @@ public class UnitTypeBootstrap implements IDataBootstrap {
@Transactional @Transactional
@Override @Override
public void loadRequiredData() { public void loadRequiredData() {
for (PredefinedUnitTypes predefinedUnitType : PredefinedUnitTypes for (PredefinedUnitTypes predefinedUnitType : PredefinedUnitTypes.values()) {
.values()) { UnitType type;
UnitType type = null;
try { try {
type = unitTypeDAO type = unitTypeDAO
.findUniqueByNameInAnotherTransaction(predefinedUnitType .findUniqueByNameInAnotherTransaction(predefinedUnitType
.getMeasure()); .getMeasure());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
type = predefinedUnitType.createUnitType(); type = predefinedUnitType.createUnitType();
type type.setCode(entitySequenceDAO
.setCode(entitySequenceDAO .getNextEntityCodeWithoutTransaction(EntityNameEnum.UNIT_TYPE));
.getNextEntityCodeWithoutTransaction(EntityNameEnum.UNIT_TYPE));
type.setCodeAutogenerated(true); type.setCodeAutogenerated(true);
unitTypeDAO.save(type); unitTypeDAO.save(type);
} }
if (predefinedUnitType if (predefinedUnitType.equals(PredefinedUnitTypes.defaultUnitType())) {
.equals(PredefinedUnitTypes.defaultUnitType())) { UnitTypeBootstrap.defaultUnitType = type;
defaultUnitType = type;
} }
} }
} }
@ -78,6 +77,7 @@ public class UnitTypeBootstrap implements IDataBootstrap {
if (defaultUnitType.isNewObject()) { if (defaultUnitType.isNewObject()) {
defaultUnitType.dontPoseAsTransientObjectAnymore(); defaultUnitType.dontPoseAsTransientObjectAnymore();
} }
return defaultUnitType; return defaultUnitType;
} }
} }

View file

@ -40,30 +40,31 @@ import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.materials.daos.IMaterialCategoryDAO; import org.libreplan.business.materials.daos.IMaterialCategoryDAO;
/** /**
* MaterialCategory entity * MaterialCategory entity.
* *
* @author Jacobo Aragunde Perez <jaragunde@igalia.com> * @author Jacobo Aragunde Perez <jaragunde@igalia.com>
*
*/ */
public class MaterialCategory extends IntegrationEntity { public class MaterialCategory extends IntegrationEntity {
public static List<Material> getAllMaterialsFrom( public static List<Material> getAllMaterialsFrom(Collection<? extends MaterialCategory> categories) {
Collection<? extends MaterialCategory> categories) { List<Material> result = new ArrayList<>();
List<Material> result = new ArrayList<Material>();
for (MaterialCategory each : categories) { for (MaterialCategory each : categories) {
result.addAll(each.getMaterials()); result.addAll(each.getMaterials());
} }
return result; return result;
} }
public static List<Material> getAllMaterialsWithoutAutogeneratedCodeFrom( public static List<Material> getAllMaterialsWithoutAutogeneratedCodeFrom(
Collection<? extends MaterialCategory> categories) { Collection<? extends MaterialCategory> categories) {
List<Material> result = new ArrayList<Material>();
List<Material> result = new ArrayList<>();
for (MaterialCategory each : categories) { for (MaterialCategory each : categories) {
if (!each.isCodeAutogenerated()) { if (!each.isCodeAutogenerated()) {
result.addAll(each.getMaterials()); result.addAll(each.getMaterials());
} }
} }
return result; return result;
} }
@ -86,12 +87,13 @@ public class MaterialCategory extends IntegrationEntity {
} }
public static MaterialCategory create(String name) { public static MaterialCategory create(String name) {
return (MaterialCategory) create(new MaterialCategory(name)); return create(new MaterialCategory(name));
} }
public static MaterialCategory createUnvalidated(String code, String name) { public static MaterialCategory createUnvalidated(String code, String name) {
MaterialCategory materialCategory = create(new MaterialCategory(), code); MaterialCategory materialCategory = create(new MaterialCategory(), code);
materialCategory.name = name; materialCategory.name = name;
return materialCategory; return materialCategory;
} }
@ -153,32 +155,34 @@ public class MaterialCategory extends IntegrationEntity {
@AssertTrue(message="material category name has to be unique. It is already used") @AssertTrue(message="material category name has to be unique. It is already used")
public boolean isUniqueNameConstraint() { public boolean isUniqueNameConstraint() {
boolean result; boolean result;
if (isNewObject()) { if (isNewObject()) {
result = !existsMaterialCategoryWithTheName(); result = !existsMaterialCategoryWithTheName();
} else { } else {
result = isIfExistsTheExistentMaterialCategoryThisOne(); result = isIfExistsTheExistentMaterialCategoryThisOne();
} }
return result; return result;
} }
private boolean existsMaterialCategoryWithTheName() { private boolean existsMaterialCategoryWithTheName() {
IMaterialCategoryDAO materialCategoryDAO = Registry.getMaterialCategoryDAO(); IMaterialCategoryDAO materialCategoryDAO = Registry.getMaterialCategoryDAO();
return materialCategoryDAO.existsMaterialCategoryWithNameInAnotherTransaction(name); return materialCategoryDAO.existsMaterialCategoryWithNameInAnotherTransaction(name);
} }
private boolean isIfExistsTheExistentMaterialCategoryThisOne() { private boolean isIfExistsTheExistentMaterialCategoryThisOne() {
IMaterialCategoryDAO materialCategoryDAO = Registry.getMaterialCategoryDAO(); IMaterialCategoryDAO materialCategoryDAO = Registry.getMaterialCategoryDAO();
try { try {
MaterialCategory materialCategory = MaterialCategory materialCategory = materialCategoryDAO.findUniqueByNameInAnotherTransaction(name);
materialCategoryDAO.findUniqueByNameInAnotherTransaction(name);
return materialCategory.getId().equals(getId()); return materialCategory.getId().equals(getId());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
return true; return true;
} }
} }
public Material getMaterialByCode(String code) public Material getMaterialByCode(String code) throws InstanceNotFoundException {
throws InstanceNotFoundException {
if (StringUtils.isBlank(code)) { if (StringUtils.isBlank(code)) {
throw new InstanceNotFoundException(code, Material.class.getName()); throw new InstanceNotFoundException(code, Material.class.getName());
@ -194,12 +198,10 @@ public class MaterialCategory extends IntegrationEntity {
} }
public MaterialCategory getSubcategoryByCode(String code) public MaterialCategory getSubcategoryByCode(String code) throws InstanceNotFoundException {
throws InstanceNotFoundException {
if (StringUtils.isBlank(code)) { if (StringUtils.isBlank(code)) {
throw new InstanceNotFoundException(code, MaterialCategory.class throw new InstanceNotFoundException(code, MaterialCategory.class.getName());
.getName());
} }
for (MaterialCategory s : this.subcategories) { for (MaterialCategory s : this.subcategories) {
@ -208,8 +210,7 @@ public class MaterialCategory extends IntegrationEntity {
} }
} }
throw new InstanceNotFoundException(code, MaterialCategory.class throw new InstanceNotFoundException(code, MaterialCategory.class.getName());
.getName());
} }
@ -221,11 +222,13 @@ public class MaterialCategory extends IntegrationEntity {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@AssertTrue(message = "Subcategory names must be unique.") @AssertTrue(message = "Subcategory names must be unique.")
public boolean isUniqueSubcategoryNameConstraint() { public boolean isUniqueSubcategoryNameConstraint() {
Set<String> subcategoriesNames = new HashSet<String>(); Set<String> subcategoriesNames = new HashSet<>();
for (MaterialCategory mc : this.getAllSubcategories()) { for (MaterialCategory mc : this.getAllSubcategories()) {
if (!StringUtils.isBlank(mc.getName())) { if (!StringUtils.isBlank(mc.getName())) {
String name = StringUtils.deleteWhitespace(mc.getName() String name = StringUtils.deleteWhitespace(mc.getName().toLowerCase());
.toLowerCase());
if (subcategoriesNames.contains(name)) { if (subcategoriesNames.contains(name)) {
return false; return false;
} else { } else {
@ -240,42 +243,43 @@ public class MaterialCategory extends IntegrationEntity {
public boolean isNonRepeatedMaterialCategoryCodesConstraint() { public boolean isNonRepeatedMaterialCategoryCodesConstraint() {
Set<MaterialCategory> allSubcategories = getAllSubcategories(); Set<MaterialCategory> allSubcategories = getAllSubcategories();
allSubcategories.add(this); allSubcategories.add(this);
return getFirstRepeatedCode(allSubcategories) == null; return getFirstRepeatedCode(allSubcategories) == null;
} }
private Set<MaterialCategory> getAllSubcategories() { private Set<MaterialCategory> getAllSubcategories() {
Set<MaterialCategory> result = new HashSet<MaterialCategory>(subcategories); Set<MaterialCategory> result = new HashSet<>(subcategories);
for (MaterialCategory subcategory : subcategories) { for (MaterialCategory subcategory : subcategories) {
result.addAll(subcategory.getAllSubcategories()); result.addAll(subcategory.getAllSubcategories());
} }
return result; return result;
} }
@AssertTrue(message = "There are repeated material codes") @AssertTrue(message = "There are repeated material codes")
public boolean isNonRepeatedMaterialCodesConstraint() { public boolean isNonRepeatedMaterialCodesConstraint() {
Set<Material> allMaterials = getAllMaterials(); Set<Material> allMaterials = getAllMaterials();
return getFirstRepeatedCode(allMaterials) == null; return getFirstRepeatedCode(allMaterials) == null;
} }
private Set<Material> getAllMaterials() { private Set<Material> getAllMaterials() {
Set<Material> result = new HashSet<Material>(materials); Set<Material> result = new HashSet<>(materials);
for (MaterialCategory subcategory : subcategories) { for (MaterialCategory subcategory : subcategories) {
result.addAll(subcategory.getAllMaterials()); result.addAll(subcategory.getAllMaterials());
} }
return result; return result;
} }
public void generateMaterialCodes(int numberOfDigits) { public void generateMaterialCodes(int numberOfDigits) {
for (Material material : this.getMaterials()) { for (Material material : this.getMaterials()) {
if ((material.getCode() == null) || (material.getCode().isEmpty()) if ((material.getCode() == null) || (material.getCode().isEmpty()) ||
|| (!material.getCode().startsWith(this.getCode()))) { (!material.getCode().startsWith(this.getCode()))) {
this.incrementLastMaterialSequenceCode(); this.incrementLastMaterialSequenceCode();
String materialCode = EntitySequence.formatValue( String materialCode = EntitySequence.formatValue(numberOfDigits, this.getLastMaterialSequenceCode());
numberOfDigits, this.getLastMaterialSequenceCode()); material.setCode(this.getCode() + EntitySequence.CODE_SEPARATOR_CHILDREN + materialCode);
material
.setCode(this.getCode()
+ EntitySequence.CODE_SEPARATOR_CHILDREN
+ materialCode);
} }
} }
} }
@ -284,6 +288,7 @@ public class MaterialCategory extends IntegrationEntity {
if (this.lastMaterialSequenceCode == null) { if (this.lastMaterialSequenceCode == null) {
this.lastMaterialSequenceCode = 0; this.lastMaterialSequenceCode = 0;
} }
this.lastMaterialSequenceCode++; this.lastMaterialSequenceCode++;
} }

View file

@ -26,9 +26,7 @@ import org.libreplan.business.orders.entities.OrderFile;
import java.util.List; import java.util.List;
/** /**
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 12.24.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 12.24.2015.
*/ */
public interface IOrderFileDAO extends IGenericDAO<OrderFile, Long> { public interface IOrderFileDAO extends IGenericDAO<OrderFile, Long> {

View file

@ -64,7 +64,7 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Dao for {@link Order} * DAO for {@link Order}.
* *
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com> * @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
@ -72,8 +72,7 @@ import org.springframework.transaction.annotation.Transactional;
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class OrderDAO extends IntegrationEntityDAO<Order> implements public class OrderDAO extends IntegrationEntityDAO<Order> implements IOrderDAO {
IOrderDAO {
@Autowired @Autowired
private ITaskSourceDAO taskSourceDAO; private ITaskSourceDAO taskSourceDAO;
@ -90,6 +89,8 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
@Autowired @Autowired
private IAdHocTransactionService transactionService; private IAdHocTransactionService transactionService;
private String STATE_PARAMETER = "state";
@Override @Override
public List<Order> getOrders() { public List<Order> getOrders() {
return list(Order.class); return list(Order.class);
@ -111,34 +112,39 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return false; return false;
} }
private boolean matchFilterCriterion(OrderElement orderElement, private boolean matchFilterCriterion(OrderElement orderElement, List<Criterion> criterions) {
List<Criterion> criterions) {
if ((criterions != null) && (!criterions.isEmpty())) { if ((criterions != null) && (!criterions.isEmpty())) {
List<OrderElement> orderElements = new ArrayList<OrderElement>();
List<OrderElement> orderElements = new ArrayList<>();
orderElements.add(orderElement); orderElements.add(orderElement);
List<Task> tasks = this.getFilteredTask(orderElements, criterions); List<Task> tasks = this.getFilteredTask(orderElements, criterions);
return (!tasks.isEmpty());
return !tasks.isEmpty();
} }
return true; return true;
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
public List<OrderCostsPerResourceDTO> getOrderCostsPerResource( public List<OrderCostsPerResourceDTO> getOrderCostsPerResource(
List<Order> orders, Date startingDate, Date endingDate, List<Order> orders,
Date startingDate,
Date endingDate,
List<Criterion> criterions) { List<Criterion> criterions) {
String strQuery = "SELECT new org.libreplan.business.reports.dtos.OrderCostsPerResourceDTO(worker, wrl) " String strQuery = "SELECT new org.libreplan.business.reports.dtos.OrderCostsPerResourceDTO(worker, wrl) " +
+ "FROM Worker worker, WorkReportLine wrl " "FROM Worker worker, WorkReportLine wrl " +
+ "LEFT OUTER JOIN wrl.resource resource " "LEFT OUTER JOIN wrl.resource resource " +
+ "WHERE resource.id = worker.id "; "WHERE resource.id = worker.id ";
// Set date range // Set date range
if (startingDate != null && endingDate != null) { if (startingDate != null && endingDate != null) {
strQuery += "AND wrl.date BETWEEN :startingDate AND :endingDate "; strQuery += "AND wrl.date BETWEEN :startingDate AND :endingDate ";
} }
if (startingDate != null && endingDate == null) { if (startingDate != null && endingDate == null) {
strQuery += "AND wrl.date >= :startingDate "; strQuery += "AND wrl.date >= :startingDate ";
} }
if (startingDate == null && endingDate != null) { if (startingDate == null && endingDate != null) {
strQuery += "AND wrl.date <= :endingDate "; strQuery += "AND wrl.date <= :endingDate ";
} }
@ -151,34 +157,32 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
if (startingDate != null) { if (startingDate != null) {
query.setParameter("startingDate", startingDate); query.setParameter("startingDate", startingDate);
} }
if (endingDate != null) { if (endingDate != null) {
query.setParameter("endingDate", endingDate); query.setParameter("endingDate", endingDate);
} }
List<OrderCostsPerResourceDTO> list = query.list(); List<OrderCostsPerResourceDTO> list = query.list();
List<OrderCostsPerResourceDTO> filteredList = new ArrayList<OrderCostsPerResourceDTO>(); List<OrderCostsPerResourceDTO> filteredList = new ArrayList<>();
for (OrderCostsPerResourceDTO each : list) { for (OrderCostsPerResourceDTO each : list) {
Order order = loadOrderAvoidingProxyFor(each.getOrderElement()); Order order = loadOrderAvoidingProxyFor(each.getOrderElement());
// Apply filtering // Apply filtering
if (matchFilterCriterion(each.getOrderElement(), criterions) if (matchFilterCriterion(each.getOrderElement(), criterions) && isOrderContained(order, orders)) {
&& isOrderContained(order, orders)) {
// Attach ordername value // Attach ordername value
each.setOrderName(order.getName()); each.setOrderName(order.getName());
each.setOrderCode(order.getCode()); each.setOrderCode(order.getCode());
// Attach calculated pricePerHour // Attach calculated pricePerHour
BigDecimal pricePerHour = CostCategoryDAO BigDecimal pricePerHour = CostCategoryDAO.getPriceByResourceDateAndHourType(
.getPriceByResourceDateAndHourType(each.getWorker(), each.getWorker(), new LocalDate(each.getDate()), each.getHoursTypeCode());
new LocalDate(each.getDate()), each
.getHoursTypeCode());
if (pricePerHour == null) { if (pricePerHour == null) {
for (TypeOfWorkHours defaultprice : typeOfWorkHoursDAO for (TypeOfWorkHours defaultprice : typeOfWorkHoursDAO.list(TypeOfWorkHours.class)) {
.list(TypeOfWorkHours.class)) { if (defaultprice.getCode().equals(each.getHoursTypeCode())) {
if (defaultprice.getCode().equals(
each.getHoursTypeCode())) {
pricePerHour = defaultprice.getDefaultPrice(); pricePerHour = defaultprice.getDefaultPrice();
} }
} }
@ -194,21 +198,24 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
@Override @Override
public List<Order> getOrdersByReadAuthorization(User user) { public List<Order> getOrdersByReadAuthorization(User user) {
if (user.isInRole(UserRole.ROLE_SUPERUSER) if (user.isInRole(UserRole.ROLE_SUPERUSER) ||
|| user.isInRole(UserRole.ROLE_READ_ALL_PROJECTS) user.isInRole(UserRole.ROLE_READ_ALL_PROJECTS) ||
|| user.isInRole(UserRole.ROLE_EDIT_ALL_PROJECTS)) { user.isInRole(UserRole.ROLE_EDIT_ALL_PROJECTS)) {
return getOrders(); return getOrders();
} }
else { else {
List<Order> orders = new ArrayList<Order>(); List<Order> orders = new ArrayList<>();
List<OrderAuthorization> authorizations = orderAuthorizationDAO.listByUserAndItsProfiles(user); List<OrderAuthorization> authorizations = orderAuthorizationDAO.listByUserAndItsProfiles(user);
for(OrderAuthorization authorization : authorizations) { for(OrderAuthorization authorization : authorizations) {
if (authorization.getAuthorizationType() == OrderAuthorizationType.READ_AUTHORIZATION || if (authorization.getAuthorizationType() == OrderAuthorizationType.READ_AUTHORIZATION ||
authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) { authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) {
Order order = authorization.getOrder(); Order order = authorization.getOrder();
if(!orders.contains(order)) { if (!orders.contains(order)) {
order.getName(); //this lines forces the load of the basic attributes of the order // These lines forces the load of the basic attributes of the order
order.getName();
orders.add(order); orders.add(order);
} }
} }
@ -218,11 +225,15 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
} }
private List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState( private List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
User user, Date startDate, Date endDate, List<Label> labels, User user,
List<Criterion> criteria, ExternalCompany customer, Date startDate,
Date endDate,
List<Label> labels,
List<Criterion> criteria,
ExternalCompany customer,
OrderStatusEnum state) { OrderStatusEnum state) {
List<Long> ordersIdsFiltered = getOrdersIdsFiltered(user, labels,
criteria, customer, state); List<Long> ordersIdsFiltered = getOrdersIdsFiltered(user, labels, criteria, customer, state);
if (ordersIdsFiltered != null && ordersIdsFiltered.isEmpty()) { if (ordersIdsFiltered != null && ordersIdsFiltered.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
@ -232,19 +243,22 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return Collections.emptyList(); return Collections.emptyList();
} }
List<Long> ordersIdsUnscheduled = getOrdersIdsUnscheduled(startDate, List<Long> ordersIdsUnscheduled = getOrdersIdsUnscheduled(startDate, endDate);
endDate);
Criteria c = getSession().createCriteria(Order.class); Criteria c = getSession().createCriteria(Order.class);
if (ordersIdsFiltered != null && ordersIdsByDates != null) { if (ordersIdsFiltered != null && ordersIdsByDates != null) {
org.hibernate.criterion.Criterion and = Restrictions.and( org.hibernate.criterion.Criterion and = Restrictions.and(
Restrictions.in("id", ordersIdsFiltered), Restrictions.in("id", ordersIdsFiltered),
Restrictions.in("id", ordersIdsByDates)); Restrictions.in("id", ordersIdsByDates));
c.add(and); c.add(and);
} else { } else {
if (ordersIdsFiltered != null) { if (ordersIdsFiltered != null) {
c.add(Restrictions.in("id", ordersIdsFiltered)); c.add(Restrictions.in("id", ordersIdsFiltered));
} }
if (ordersIdsByDates != null) { if (ordersIdsByDates != null) {
if (ordersIdsUnscheduled.isEmpty()) { if (ordersIdsUnscheduled.isEmpty()) {
c.add(Restrictions.in("id", ordersIdsByDates)); c.add(Restrictions.in("id", ordersIdsByDates));
@ -258,13 +272,15 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
c.addOrder(org.hibernate.criterion.Order.desc("initDate")); c.addOrder(org.hibernate.criterion.Order.desc("initDate"));
c.addOrder(org.hibernate.criterion.Order.asc("infoComponent.name")); c.addOrder(org.hibernate.criterion.Order.asc("infoComponent.name"));
return c.list(); return c.list();
} }
private List<Long> getOrdersIdsUnscheduled(Date startDate, Date endDate) { private List<Long> getOrdersIdsUnscheduled(Date startDate, Date endDate) {
String strQuery = "SELECT s.orderElement.id " String strQuery = "SELECT s.orderElement.id " +
+ "FROM SchedulingDataForVersion s " "FROM SchedulingDataForVersion s " +
+ "WHERE s.schedulingStateType = :type"; "WHERE s.schedulingStateType = :type";
Query query = getSession().createQuery(strQuery); Query query = getSession().createQuery(strQuery);
query.setParameter("type", SchedulingState.Type.NO_SCHEDULED); query.setParameter("type", SchedulingState.Type.NO_SCHEDULED);
@ -273,9 +289,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return Collections.emptyList(); return Collections.emptyList();
} }
String strQueryDates = "SELECT o.id " String strQueryDates = "SELECT o.id " + "FROM Order o " + "WHERE o.id IN (:ids) ";
+ "FROM Order o "
+ "WHERE o.id IN (:ids) ";
if (startDate != null) { if (startDate != null) {
strQueryDates += "AND o.initDate >= :startDate "; strQueryDates += "AND o.initDate >= :startDate ";
@ -298,28 +312,32 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
/** /**
* If both params are <code>null</code> it returns <code>null</code>. * If both params are <code>null</code> it returns <code>null</code>.
* Otherwise it filters the list of tasks to return the ones wihtout parent * Otherwise it filters the list of tasks to return the ones without parent between the dates.
* between the dates.
*/ */
private List<Long> getOrdersIdsByDates(Date startDate, Date endDate) { private List<Long> getOrdersIdsByDates(Date startDate, Date endDate) {
if (startDate == null && endDate == null) { if (startDate == null && endDate == null) {
/* Don't replace null with Collections.emptyList(), as the prompt says (sometimes), because it breaks logic */
return null; return null;
} }
String strQuery = "SELECT t.taskSource.schedulingData.orderElement.id " String strQuery = "SELECT t.taskSource.schedulingData.orderElement.id "
+ "FROM TaskElement t " + "FROM TaskElement t "
+ "WHERE t.parent IS NULL "; + "WHERE t.parent IS NULL ";
if (endDate != null) { if (endDate != null) {
strQuery += "AND t.startDate.date <= :endDate "; strQuery += "AND t.startDate.date <= :endDate ";
} }
if (startDate != null) { if (startDate != null) {
strQuery += "AND t.endDate.date >= :startDate "; strQuery += "AND t.endDate.date >= :startDate ";
} }
Query query = getSession().createQuery(strQuery); Query query = getSession().createQuery(strQuery);
if (startDate != null) { if (startDate != null) {
query.setParameter("startDate", LocalDate.fromDateFields(startDate)); query.setParameter("startDate", LocalDate.fromDateFields(startDate));
} }
if (endDate != null) { if (endDate != null) {
query.setParameter("endDate", LocalDate.fromDateFields(endDate)); query.setParameter("endDate", LocalDate.fromDateFields(endDate));
} }
@ -328,13 +346,16 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
} }
/** /**
* If user has permissions over all orders and not filters are passed it * If user has permissions over all orders and not filters are passed it returns <code>null</code>.
* returns <code>null</code>. Otherwise, it returns the list of orders * Otherwise, it returns the list of orders
* identifiers for which the user has read permissions and the filters pass. * identifiers for which the user has read permissions and the filters pass.
*/ */
private List<Long> getOrdersIdsFiltered(User user, List<Label> labels, private List<Long> getOrdersIdsFiltered(User user,
List<Criterion> criteria, ExternalCompany customer, List<Label> labels,
OrderStatusEnum state) { List<Criterion> criteria,
ExternalCompany customer,
OrderStatusEnum state) {
List<Long> ordersIdsByReadAuthorization = getOrdersIdsByReadAuthorization(user); List<Long> ordersIdsByReadAuthorization = getOrdersIdsByReadAuthorization(user);
String strQuery = "SELECT o.id "; String strQuery = "SELECT o.id ";
@ -389,8 +410,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return ordersIdsByReadAuthorization; return ordersIdsByReadAuthorization;
} }
if (ordersIdsByReadAuthorization != null if (ordersIdsByReadAuthorization != null && !ordersIdsByReadAuthorization.isEmpty()) {
&& !ordersIdsByReadAuthorization.isEmpty()) {
if (where.isEmpty()) { if (where.isEmpty()) {
where += "WHERE "; where += "WHERE ";
} else { } else {
@ -401,6 +421,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
strQuery += where + whereFinal; strQuery += where + whereFinal;
Query query = getSession().createQuery(strQuery); Query query = getSession().createQuery(strQuery);
if (labels != null && !labels.isEmpty()) { if (labels != null && !labels.isEmpty()) {
int i = 0; int i = 0;
for (Label label : labels) { for (Label label : labels) {
@ -408,6 +429,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
i++; i++;
} }
} }
if (criteria != null && !criteria.isEmpty()) { if (criteria != null && !criteria.isEmpty()) {
query.setParameterList("criteria", criteria); query.setParameterList("criteria", criteria);
query.setParameter("criteriaSize", (long) criteria.size()); query.setParameter("criteriaSize", (long) criteria.size());
@ -418,11 +440,10 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
} }
if (state != null) { if (state != null) {
query.setParameter("state", state); query.setParameter(STATE_PARAMETER, state);
} }
if (ordersIdsByReadAuthorization != null if (ordersIdsByReadAuthorization != null && !ordersIdsByReadAuthorization.isEmpty()) {
&& !ordersIdsByReadAuthorization.isEmpty()) {
query.setParameterList("ids", ordersIdsByReadAuthorization); query.setParameterList("ids", ordersIdsByReadAuthorization);
} }
@ -431,8 +452,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
/** /**
* If user has permissions over all orders it returns <code>null</code>. * If user has permissions over all orders it returns <code>null</code>.
* Otherwise, it returns the list of orders identifiers for which the user * Otherwise, it returns the list of orders identifiers for which the user has read permissions.
* has read permissions.
*/ */
private List<Long> getOrdersIdsByReadAuthorization(User user) { private List<Long> getOrdersIdsByReadAuthorization(User user) {
if (user.isInRole(UserRole.ROLE_SUPERUSER) if (user.isInRole(UserRole.ROLE_SUPERUSER)
@ -464,7 +484,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return getOrders(); return getOrders();
} }
else { else {
List<Order> orders = new ArrayList<Order>(); List<Order> orders = new ArrayList<>();
List<OrderAuthorization> authorizations = orderAuthorizationDAO.listByUserAndItsProfiles(user); List<OrderAuthorization> authorizations = orderAuthorizationDAO.listByUserAndItsProfiles(user);
for(OrderAuthorization authorization : authorizations) { for(OrderAuthorization authorization : authorizations) {
if (authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) { if (authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) {
@ -481,8 +501,10 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
@Override @Override
public List<Order> findAll() { public List<Order> findAll() {
return getSession().createCriteria(getEntityClass()).addOrder( return getSession()
org.hibernate.criterion.Order.asc("infoComponent.code")).list(); .createCriteria(getEntityClass())
.addOrder(org.hibernate.criterion.Order.asc("infoComponent.code"))
.list();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -491,18 +513,16 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
public Order findByCode(String code) throws InstanceNotFoundException { public Order findByCode(String code) throws InstanceNotFoundException {
if (StringUtils.isBlank(code)) { if (StringUtils.isBlank(code)) {
throw new InstanceNotFoundException(null, getEntityClass() throw new InstanceNotFoundException(null, getEntityClass().getName());
.getName());
} }
Order entity = (Order) getSession().createCriteria(getEntityClass()) Order entity = (Order) getSession()
.add( .createCriteria(getEntityClass())
Restrictions.eq("infoComponent.code", code.trim()) .add(Restrictions.eq("infoComponent.code", code.trim()).ignoreCase())
.ignoreCase()).uniqueResult(); .uniqueResult();
if (entity == null) { if (entity == null) {
throw new InstanceNotFoundException(code, getEntityClass() throw new InstanceNotFoundException(code, getEntityClass().getName());
.getName());
} else { } else {
return entity; return entity;
} }
@ -510,8 +530,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
} }
@Override @Override
public List<Order> getOrdersByReadAuthorizationByScenario(String username, public List<Order> getOrdersByReadAuthorizationByScenario(String username, Scenario scenario) {
Scenario scenario) {
User user; User user;
try { try {
user = userDAO.findByLoginName(username); user = userDAO.findByLoginName(username);
@ -523,23 +542,27 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
@Override @Override
public List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState( public List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
String username, Scenario scenario, Date startDate, Date endDate, String username,
List<Label> labels, List<Criterion> criteria, Scenario scenario,
ExternalCompany customer, OrderStatusEnum state) { Date startDate,
Date endDate,
List<Label> labels,
List<Criterion> criteria,
ExternalCompany customer,
OrderStatusEnum state) {
User user; User user;
try { try {
user = userDAO.findByLoginName(username); user = userDAO.findByLoginName(username);
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return existsInScenario( return existsInScenario(getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState( user, startDate, endDate, labels, criteria, customer, state), scenario);
user, startDate, endDate, labels, criteria, customer,
state), scenario);
} }
private List<Order> existsInScenario(List<Order> orders, Scenario scenario) { private List<Order> existsInScenario(List<Order> orders, Scenario scenario) {
List<Order> result = new ArrayList<Order>(); List<Order> result = new ArrayList<>();
for (Order each : orders) { for (Order each : orders) {
if (scenario.contains(each)) { if (scenario.contains(each)) {
result.add(each); result.add(each);
@ -549,28 +572,24 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
} }
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW) @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public Order findByNameAnotherTransaction(String name) public Order findByNameAnotherTransaction(String name) throws InstanceNotFoundException {
throws InstanceNotFoundException {
return findByName(name); return findByName(name);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Order findByName(String name) throws InstanceNotFoundException { private Order findByName(String name) throws InstanceNotFoundException {
if (StringUtils.isBlank(name)) { if (StringUtils.isBlank(name)) {
throw new InstanceNotFoundException(null, throw new InstanceNotFoundException(null, getEntityClass().getName());
getEntityClass().getName());
} }
Order order = (Order) getSession().createCriteria(getEntityClass()) Order order = (Order) getSession()
.createCriteria(getEntityClass())
.add(Restrictions.eq("infoComponent.name", name).ignoreCase()) .add(Restrictions.eq("infoComponent.name", name).ignoreCase())
.uniqueResult(); .uniqueResult();
if (order == null) { if (order == null) {
throw new InstanceNotFoundException( throw new InstanceNotFoundException(name, getEntityClass().getName());
name, getEntityClass().getName());
} else { } else {
return order; return order;
} }
@ -584,26 +603,25 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public List<Task> getFilteredTask(List<OrderElement> orderElements, public List<Task> getFilteredTask(List<OrderElement> orderElements, List<Criterion> criterions) {
List<Criterion> criterions) {
if (orderElements == null || orderElements.isEmpty()) { if (orderElements == null || orderElements.isEmpty()) {
return new ArrayList<Task>(); return new ArrayList<>();
} }
String strQuery = "SELECT taskSource.task " String strQuery = "SELECT taskSource.task " +
+ "FROM OrderElement orderElement, TaskSource taskSource, Task task " "FROM OrderElement orderElement, TaskSource taskSource, Task task " +
+ "LEFT OUTER JOIN taskSource.schedulingData.orderElement taskSourceOrderElement " "LEFT OUTER JOIN taskSource.schedulingData.orderElement taskSourceOrderElement " +
+ "LEFT OUTER JOIN taskSource.task taskElement " "LEFT OUTER JOIN taskSource.task taskElement " +
+ "WHERE taskSourceOrderElement.id = orderElement.id " "WHERE taskSourceOrderElement.id = orderElement.id " +
+ "AND taskElement.id = task.id AND orderElement IN (:orderElements) "; "AND taskElement.id = task.id AND orderElement IN (:orderElements) ";
// Set Criterions // Set Criterions
if (criterions != null && !criterions.isEmpty()) { if (criterions != null && !criterions.isEmpty()) {
strQuery += " AND (EXISTS (FROM task.resourceAllocations as allocation, GenericResourceAllocation as generic " strQuery += " AND (EXISTS (FROM task.resourceAllocations as allocation, GenericResourceAllocation as generic " +
+ " WHERE generic.id = allocation.id " " WHERE generic.id = allocation.id " +
+ " AND EXISTS( FROM generic.criterions criterion WHERE criterion IN (:criterions))))"; " AND EXISTS( FROM generic.criterions criterion WHERE criterion IN (:criterions))))";
} }
// Order by // Order by
@ -614,29 +632,24 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
query.setParameterList("orderElements", orderElements); query.setParameterList("orderElements", orderElements);
if (criterions != null && !criterions.isEmpty()) { if (criterions != null && !criterions.isEmpty()) {
query.setParameterList("criterions", query.setParameterList("criterions", Criterion.withAllDescendants(criterions));
Criterion.withAllDescendants(criterions));
} }
// Get result
return query.list(); return query.list();
} }
@Override @Override
public Order loadOrderAvoidingProxyFor(final OrderElement orderElement) { public Order loadOrderAvoidingProxyFor(final OrderElement orderElement) {
return loadOrdersAvoidingProxyFor( return loadOrdersAvoidingProxyFor(Collections.singletonList(orderElement)).get(0);
Collections.singletonList(orderElement)).get(0);
} }
@Override @Override
public List<Order> loadOrdersAvoidingProxyFor( public List<Order> loadOrdersAvoidingProxyFor(final List<OrderElement> orderElements) {
final List<OrderElement> orderElements) { List<OrderElement> orders =
List<OrderElement> orders = transactionService transactionService.runOnAnotherTransaction(new IOnTransaction<List<OrderElement>>() {
.runOnAnotherTransaction(new IOnTransaction<List<OrderElement>>() {
@Override @Override
public List<OrderElement> execute() { public List<OrderElement> execute() {
List<OrderElement> result = new ArrayList<OrderElement>(); List<OrderElement> result = new ArrayList<>();
for (OrderElement each : orderElements) { for (OrderElement each : orderElements) {
if (each.isNewObject()) { if (each.isNewObject()) {
result.add(each.getOrder()); result.add(each.getOrder());
@ -650,6 +663,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
private OrderElement orderFrom(OrderElement initial) { private OrderElement orderFrom(OrderElement initial) {
OrderElement current = initial; OrderElement current = initial;
OrderElement result = current; OrderElement result = current;
while (current != null) { while (current != null) {
result = current; result = current;
current = findParent(current); current = findParent(current);
@ -659,14 +673,14 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
private OrderElement findParent(OrderElement orderElement) { private OrderElement findParent(OrderElement orderElement) {
Query query = getSession() Query query = getSession()
.createQuery( .createQuery("select e.parent from OrderElement e where e.id = :id")
"select e.parent from OrderElement e where e.id = :id")
.setParameter("id", orderElement.getId()); .setParameter("id", orderElement.getId());
return (OrderElement) query.uniqueResult(); return (OrderElement) query.uniqueResult();
} }
}); });
List<Order> result = new ArrayList<Order>();
List<Order> result = new ArrayList<>();
for (OrderElement each : orders) { for (OrderElement each : orders) {
if (each != null) { if (each != null) {
result.add(findExistingEntity(each.getId())); result.add(findExistingEntity(each.getId()));
@ -692,26 +706,31 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Order> getActiveOrders() { public List<Order> getActiveOrders() {
Criteria criteria = getSession().createCriteria(getEntityClass()); Criteria criteria = getSession().createCriteria(getEntityClass());
criteria.add(Restrictions.not(Restrictions.eq("state", OrderStatusEnum.CANCELLED))); criteria.add(Restrictions.not(Restrictions.eq(STATE_PARAMETER, OrderStatusEnum.CANCELLED)));
criteria.add(Restrictions.not(Restrictions.eq("state", OrderStatusEnum.STORED))); criteria.add(Restrictions.not(Restrictions.eq(STATE_PARAMETER, OrderStatusEnum.STORED)));
return criteria.list(); return criteria.list();
} }
@Override @Override
public List<CostExpenseSheetDTO> getCostExpenseSheet(List<Order> orders, Date startingDate, public List<CostExpenseSheetDTO> getCostExpenseSheet(List<Order> orders,
Date endingDate, List<Criterion> criterions) { Date startingDate,
Date endingDate,
List<Criterion> criterions) {
String strQuery = "SELECT new org.libreplan.business.reports.dtos.CostExpenseSheetDTO(expense) " String strQuery = "SELECT new org.libreplan.business.reports.dtos.CostExpenseSheetDTO(expense) " +
+ "FROM OrderElement orderElement, ExpenseSheetLine expense " "FROM OrderElement orderElement, ExpenseSheetLine expense " +
+ "LEFT OUTER JOIN expense.orderElement exp_ord " "LEFT OUTER JOIN expense.orderElement exp_ord " +
+ "WHERE orderElement.id = exp_ord.id "; "WHERE orderElement.id = exp_ord.id ";
if (startingDate != null && endingDate != null) { if (startingDate != null && endingDate != null) {
strQuery += "AND expense.date BETWEEN :startingDate AND :endingDate "; strQuery += "AND expense.date BETWEEN :startingDate AND :endingDate ";
} }
if (startingDate != null && endingDate == null) { if (startingDate != null && endingDate == null) {
strQuery += "AND expense.date >= :startingDate "; strQuery += "AND expense.date >= :startingDate ";
} }
if (startingDate == null && endingDate != null) { if (startingDate == null && endingDate != null) {
strQuery += "AND expense.date <= :endingDate "; strQuery += "AND expense.date <= :endingDate ";
} }
@ -725,18 +744,19 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
if (startingDate != null) { if (startingDate != null) {
query.setParameter("startingDate", new LocalDate(startingDate)); query.setParameter("startingDate", new LocalDate(startingDate));
} }
if (endingDate != null) { if (endingDate != null) {
query.setParameter("endingDate", new LocalDate(endingDate)); query.setParameter("endingDate", new LocalDate(endingDate));
} }
List<CostExpenseSheetDTO> list = query.list(); List<CostExpenseSheetDTO> list = query.list();
List<CostExpenseSheetDTO> filteredList = new ArrayList<CostExpenseSheetDTO>(); List<CostExpenseSheetDTO> filteredList = new ArrayList<>();
for (CostExpenseSheetDTO each : list) { for (CostExpenseSheetDTO each : list) {
Order order = loadOrderAvoidingProxyFor(each.getOrderElement()); Order order = loadOrderAvoidingProxyFor(each.getOrderElement());
// Apply filtering // Apply filtering
if (matchFilterCriterion(each.getOrderElement(), criterions) if (matchFilterCriterion(each.getOrderElement(), criterions) && isOrderContained(order, orders)) {
&& isOrderContained(order, orders)) {
each.setOrder(order); each.setOrder(order);
filteredList.add(each); filteredList.add(each);
} }

View file

@ -61,7 +61,7 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Dao for {@link OrderElement} * Dao for {@link OrderElement}.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino García <dpino@igalia.com> * @author Diego Pino García <dpino@igalia.com>
@ -86,10 +86,10 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
@Override @Override
public List<OrderElement> findWithoutParent() { public List<OrderElement> findWithoutParent() {
Criteria c = getSession().createCriteria(OrderElement.class); return getSession()
c.add(Restrictions.isNull("parent")); .createCriteria(OrderElement.class)
.add(Restrictions.isNull("parent"))
return (List<OrderElement>) c.list(); .list();
} }
public List<OrderElement> findByCodeAndParent(OrderElement parent, String code) { public List<OrderElement> findByCodeAndParent(OrderElement parent, String code) {
@ -116,11 +116,11 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
@Transactional(readOnly = true) @Transactional(readOnly = true)
public EffortDuration getAssignedDirectEffort(OrderElement orderElement) { public EffortDuration getAssignedDirectEffort(OrderElement orderElement) {
List<WorkReportLine> listWRL = this.workReportLineDAO.findByOrderElement(orderElement); List<WorkReportLine> listWRL = this.workReportLineDAO.findByOrderElement(orderElement);
EffortDuration asignedDirectHours = EffortDuration.zero(); EffortDuration assignedDirectHours = EffortDuration.zero();
for (WorkReportLine aListWRL : listWRL) { for (WorkReportLine aListWRL : listWRL) {
asignedDirectHours = asignedDirectHours.plus(aListWRL.getEffort()); assignedDirectHours = assignedDirectHours.plus(aListWRL.getEffort());
} }
return asignedDirectHours; return assignedDirectHours;
} }
@Override @Override
@ -134,11 +134,9 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
BigDecimal assignedHours = totalChargedEffort.toHoursAsDecimalWithScale(2); BigDecimal assignedHours = totalChargedEffort.toHoursAsDecimalWithScale(2);
BigDecimal estimatedHours = new BigDecimal(orderElement.getWorkHours()).setScale(2); BigDecimal estimatedHours = new BigDecimal(orderElement.getWorkHours()).setScale(2);
if ( estimatedHours.compareTo(BigDecimal.ZERO) <= 0 ) { return estimatedHours.compareTo(BigDecimal.ZERO) <= 0
return BigDecimal.ZERO; ? BigDecimal.ZERO
} : assignedHours.divide(estimatedHours, RoundingMode.DOWN);
return assignedHours.divide(estimatedHours, RoundingMode.DOWN);
} }
@Override @Override
@ -185,7 +183,8 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
public List<OrderElement> findAll() { public List<OrderElement> findAll() {
return getSession() return getSession()
.createCriteria(getEntityClass()) .createCriteria(getEntityClass())
.addOrder(org.hibernate.criterion.Order.asc("infoComponent.code")).list(); .addOrder(org.hibernate.criterion.Order.asc("infoComponent.code"))
.list();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -211,10 +210,10 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
} }
public List<OrderElement> findByTemplate(OrderElementTemplate template) { public List<OrderElement> findByTemplate(OrderElementTemplate template) {
Criteria c = getSession().createCriteria(OrderElement.class); return getSession()
c.add(Restrictions.eq("template", template)); .createCriteria(OrderElement.class)
.add(Restrictions.eq("template", template))
return (List<OrderElement>) c.list(); .list();
} }
@Override @Override
@ -244,10 +243,10 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
@Override @Override
public List<OrderElement> findOrderElementsWithExternalCode() { public List<OrderElement> findOrderElementsWithExternalCode() {
Criteria c = getSession().createCriteria(OrderElement.class); return getSession()
c.add(Restrictions.isNotNull("externalCode")); .createCriteria(OrderElement.class)
.add(Restrictions.isNotNull("externalCode"))
return c.list(); .list();
} }
@ -259,9 +258,10 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
throw new InstanceNotFoundException(null, getEntityClass().getName()); throw new InstanceNotFoundException(null, getEntityClass().getName());
} }
Criteria c = getSession().createCriteria(OrderElement.class); OrderElement entity = (OrderElement) getSession()
c.add(Restrictions.eq("externalCode", code.trim()).ignoreCase()); .createCriteria(OrderElement.class)
OrderElement entity = (OrderElement) c.uniqueResult(); .add(Restrictions.eq("externalCode", code.trim()).ignoreCase())
.uniqueResult();
if ( entity == null ) { if ( entity == null ) {
throw new InstanceNotFoundException(code, getEntityClass().getName()); throw new InstanceNotFoundException(code, getEntityClass().getName());
@ -273,20 +273,17 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
/** /**
* Methods to calculate statistics with the estimated hours and worked hours of a set of order elements. * Methods to calculate statistics with the estimated hours and worked hours of a set of order elements.
* @param List *
* @param list
* <{@link OrderElement}> * <{@link OrderElement}>
*/ */
public BigDecimal calculateAverageEstimatedHours(final List<OrderElement> list) { public BigDecimal calculateAverageEstimatedHours(final List<OrderElement> list) {
BigDecimal sum = sumEstimatedHours(list); return average(new BigDecimal(list.size()), sumEstimatedHours(list));
return average(new BigDecimal(list.size()), sum);
} }
public EffortDuration calculateAverageWorkedHours(final List<OrderElement> list) { public EffortDuration calculateAverageWorkedHours(final List<OrderElement> list) {
EffortDuration sum = sumWorkedHours(list); return list.isEmpty() ? EffortDuration.zero() : EffortDuration.average(sumWorkedHours(list), list.size());
return (list.size() == 0) ? EffortDuration.zero() : EffortDuration.average(sum, list.size());
} }
private BigDecimal average(BigDecimal divisor, BigDecimal sum) { private BigDecimal average(BigDecimal divisor, BigDecimal sum) {
@ -484,16 +481,12 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
@Override @Override
public boolean hasImputedExpenseSheet(Long id) throws InstanceNotFoundException { public boolean hasImputedExpenseSheet(Long id) throws InstanceNotFoundException {
OrderElement orderElement = find(id); return !expenseSheetLineDAO.findByOrderElement(find(id)).isEmpty();
return (!expenseSheetLineDAO.findByOrderElement(orderElement).isEmpty());
} }
@Override @Override
public boolean hasImputedExpenseSheetThisOrAnyOfItsChildren(Long id) throws InstanceNotFoundException { public boolean hasImputedExpenseSheetThisOrAnyOfItsChildren(Long id) throws InstanceNotFoundException {
OrderElement orderElement = find(id); return !expenseSheetLineDAO.findByOrderElementAndChildren(find(id)).isEmpty();
return (!expenseSheetLineDAO.findByOrderElementAndChildren(orderElement).isEmpty());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -517,11 +510,13 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
if ( criteria != null && !criteria.isEmpty() ) { if ( criteria != null && !criteria.isEmpty() ) {
strQuery += "JOIN oe.criterionRequirements cr "; strQuery += "JOIN oe.criterionRequirements cr ";
if ( where.isEmpty() ) { if ( where.isEmpty() ) {
where += "WHERE "; where += "WHERE ";
} else { } else {
where += "AND "; where += "AND ";
} }
where += "cr.criterion IN (:criteria) "; where += "cr.criterion IN (:criteria) ";
where += "AND cr.class = DirectCriterionRequirement "; where += "AND cr.class = DirectCriterionRequirement ";
where += "GROUP BY oe.id "; where += "GROUP BY oe.id ";
@ -562,9 +557,7 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
private boolean existsByCodeInAnotherOrder(OrderElement orderElement) { private boolean existsByCodeInAnotherOrder(OrderElement orderElement) {
try { try {
OrderElement found = findUniqueByCode(orderElement.getCode()); return !areInTheSameOrder(orderElement, findUniqueByCode(orderElement.getCode()));
return !areInTheSameOrder(orderElement, found);
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
return false; return false;
} }

View file

@ -29,9 +29,8 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/** /**
* Created by *
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com> * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 12.24.2015.
* on 12.24.2015.
*/ */
@Repository @Repository
@ -46,12 +45,14 @@ public class OrderFileDAO extends GenericDAOHibernate<OrderFile, Long> implement
public void delete(OrderFile file) { public void delete(OrderFile file) {
try { try {
remove(file.getId()); remove(file.getId());
} catch (InstanceNotFoundException ignored) { } catch (InstanceNotFoundException ignored) {}
}
} }
@Override @Override
public List<OrderFile> findByParent(OrderElement parent) { public List<OrderFile> findByParent(OrderElement parent) {
return getSession().createCriteria(OrderFile.class).add(Restrictions.eq("parent", parent)).list(); return getSession()
.createCriteria(OrderFile.class)
.add(Restrictions.eq("parent", parent))
.list();
} }
} }

View file

@ -51,8 +51,7 @@ import org.springframework.transaction.annotation.Transactional;
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class SumExpensesDAO extends GenericDAOHibernate<SumExpenses, Long> implements public class SumExpensesDAO extends GenericDAOHibernate<SumExpenses, Long> implements ISumExpensesDAO {
ISumExpensesDAO {
@Autowired @Autowired
private SessionFactory sessionFactory; private SessionFactory sessionFactory;
@ -69,8 +68,7 @@ public class SumExpensesDAO extends GenericDAOHibernate<SumExpenses, Long> imple
private Map<OrderElement, SumExpenses> mapSumExpenses; private Map<OrderElement, SumExpenses> mapSumExpenses;
@Override @Override
public void updateRelatedSumExpensesWithExpenseSheetLineSet( public void updateRelatedSumExpensesWithExpenseSheetLineSet(Set<ExpenseSheetLine> expenseSheetLineSet) {
Set<ExpenseSheetLine> expenseSheetLineSet) {
resetMapSumExpenses(); resetMapSumExpenses();
for (ExpenseSheetLine expenseSheetLine : expenseSheetLineSet) { for (ExpenseSheetLine expenseSheetLine : expenseSheetLineSet) {

View file

@ -37,30 +37,32 @@ import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.ResourceEnum; import org.libreplan.business.resources.entities.ResourceEnum;
/** /**
* A collection of HoursGroup with the same name required <br /> * A collection of HoursGroup with the same name required.
* <br />
*
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*/ */
public class AggregatedHoursGroup { public class AggregatedHoursGroup {
private static class GroupingCriteria { private static class GroupingCriteria {
private static Map<GroupingCriteria, List<HoursGroup>> byCriterions( private static Map<GroupingCriteria, List<HoursGroup>> byCriterions(Collection<? extends HoursGroup> hours) {
Collection<? extends HoursGroup> hours) { Map<GroupingCriteria, List<HoursGroup>> result = new HashMap<>();
Map<GroupingCriteria, List<HoursGroup>> result = new HashMap<GroupingCriteria, List<HoursGroup>>();
for (HoursGroup each : hours) { for (HoursGroup each : hours) {
GroupingCriteria key = asGroupingCriteria(each); GroupingCriteria key = asGroupingCriteria(each);
if (!result.containsKey(key)) { if (!result.containsKey(key)) {
result.put(key, result.put(key, new ArrayList<>());
new ArrayList<HoursGroup>());
} }
result.get(key).add(each); result.get(key).add(each);
} }
return result; return result;
} }
private static GroupingCriteria asGroupingCriteria(HoursGroup hoursGroup) { private static GroupingCriteria asGroupingCriteria(HoursGroup hoursGroup) {
return new GroupingCriteria(hoursGroup.getResourceType(), return new GroupingCriteria(hoursGroup.getResourceType(), hoursGroup.getValidCriterions());
hoursGroup.getValidCriterions());
} }
private final ResourceEnum type; private final ResourceEnum type;
@ -74,18 +76,16 @@ public class AggregatedHoursGroup {
@Override @Override
public int hashCode() { public int hashCode() {
return new HashCodeBuilder().append(type).append(criterions) return new HashCodeBuilder().append(type).append(criterions).toHashCode();
.toHashCode();
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof GroupingCriteria) { if (obj instanceof GroupingCriteria) {
GroupingCriteria other = (GroupingCriteria) obj; GroupingCriteria other = (GroupingCriteria) obj;
return new EqualsBuilder().append(type, other.type).append( return new EqualsBuilder().append(type, other.type).append(criterions, other.criterions).isEquals();
criterions,
other.criterions).isEquals();
} }
return false; return false;
} }
} }
@ -94,15 +94,12 @@ public class AggregatedHoursGroup {
return aggregate(Arrays.asList(hours)); return aggregate(Arrays.asList(hours));
} }
public static List<AggregatedHoursGroup> aggregate( public static List<AggregatedHoursGroup> aggregate(Collection<? extends HoursGroup> hours) {
Collection<? extends HoursGroup> hours) { List<AggregatedHoursGroup> result = new ArrayList<>();
List<AggregatedHoursGroup> result = new ArrayList<AggregatedHoursGroup>(); for (Entry<GroupingCriteria, List<HoursGroup>> entry : GroupingCriteria.byCriterions(hours).entrySet()) {
for (Entry<GroupingCriteria, List<HoursGroup>> entry : GroupingCriteria result.add(new AggregatedHoursGroup(entry.getKey(), entry.getValue()));
.byCriterions(hours)
.entrySet()) {
result.add(new AggregatedHoursGroup(entry.getKey(), entry
.getValue()));
} }
return result; return result;
} }
@ -111,6 +108,7 @@ public class AggregatedHoursGroup {
for (AggregatedHoursGroup each : aggregated) { for (AggregatedHoursGroup each : aggregated) {
result += each.getHours(); result += each.getHours();
} }
return result; return result;
} }
@ -121,10 +119,8 @@ public class AggregatedHoursGroup {
private ResourceEnum resourceType; private ResourceEnum resourceType;
private AggregatedHoursGroup(GroupingCriteria groupingCriteria, private AggregatedHoursGroup(GroupingCriteria groupingCriteria, List<HoursGroup> hours) {
List<HoursGroup> hours) { this.criterions = Collections.unmodifiableSet(groupingCriteria.criterions);
this.criterions = Collections
.unmodifiableSet(groupingCriteria.criterions);
this.hoursGroup = Collections.unmodifiableList(hours); this.hoursGroup = Collections.unmodifiableList(hours);
this.resourceType = groupingCriteria.type; this.resourceType = groupingCriteria.type;
} }
@ -146,20 +142,23 @@ public class AggregatedHoursGroup {
for (HoursGroup each : hoursGroup) { for (HoursGroup each : hoursGroup) {
result += each.getWorkingHours(); result += each.getWorkingHours();
} }
return result; return result;
} }
public String getCriterionsJoinedByComma() { public String getCriterionsJoinedByComma() {
List<String> criterionNames = asNames(criterions); List<String> criterionNames = asNames(criterions);
Collections.sort(criterionNames); Collections.sort(criterionNames);
return StringUtils.join(criterionNames, ", "); return StringUtils.join(criterionNames, ", ");
} }
private List<String> asNames(Set<Criterion> criterions) { private List<String> asNames(Set<Criterion> criterions) {
List<String> result = new ArrayList<String>(); List<String> result = new ArrayList<>();
for (Criterion each : criterions) { for (Criterion each : criterions) {
result.add(each.getName()); result.add(each.getName());
} }
return result; return result;
} }

View file

@ -64,8 +64,24 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
private HoursGroup origin; private HoursGroup origin;
protected CriterionRequirementOrderElementHandler criterionRequirementHandler = protected CriterionRequirementOrderElementHandler criterionRequirementHandler =
CriterionRequirementOrderElementHandler.getInstance(); CriterionRequirementOrderElementHandler.getInstance();
/**
* Constructor for hibernate. Do not use!
*/
public HoursGroup() {}
private HoursGroup(OrderLine parentOrderLine) {
this.parentOrderLine = parentOrderLine;
String code = parentOrderLine.getCode();
this.setCode(code != null ? code : "");
this.setOrderLineTemplate(null);
}
private HoursGroup(OrderLineTemplate orderLineTemplate) {
this.orderLineTemplate = orderLineTemplate;
this.setParentOrderLine(null);
}
public static HoursGroup create(OrderLine parentOrderLine) { public static HoursGroup create(OrderLine parentOrderLine) {
HoursGroup result = new HoursGroup(parentOrderLine); HoursGroup result = new HoursGroup(parentOrderLine);
@ -91,17 +107,17 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
} }
/** /**
* Returns a copy of hoursGroup, and sets parent as its parent * Returns a copy of hoursGroup, and sets parent as its parent.
* *
* @param hoursGroup * @param hoursGroup
* @param parent * @param parent
* @return * @return {@link HoursGroup}
*/ */
public static HoursGroup copyFrom(HoursGroup hoursGroup, OrderLineTemplate parent) { public static HoursGroup copyFrom(HoursGroup hoursGroup, OrderLineTemplate parent) {
HoursGroup result = copyFrom(hoursGroup); HoursGroup result = copyFrom(hoursGroup);
result.setCriterionRequirements(copyDirectCriterionRequirements( result.setCriterionRequirements(
result, hoursGroup.getDirectCriterionRequirement())); copyDirectCriterionRequirements(result, hoursGroup.getDirectCriterionRequirement()));
result.setOrderLineTemplate(parent); result.setOrderLineTemplate(parent);
result.setParentOrderLine(null); result.setParentOrderLine(null);
@ -128,8 +144,8 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
public static HoursGroup copyFrom(HoursGroup hoursGroup, OrderLine parent) { public static HoursGroup copyFrom(HoursGroup hoursGroup, OrderLine parent) {
HoursGroup result = copyFrom(hoursGroup); HoursGroup result = copyFrom(hoursGroup);
result.setCriterionRequirements(copyDirectCriterionRequirements( result.setCriterionRequirements(
result, hoursGroup.getDirectCriterionRequirement())); copyDirectCriterionRequirements(result, hoursGroup.getDirectCriterionRequirement()));
result.setOrderLineTemplate(null); result.setOrderLineTemplate(null);
result.setParentOrderLine(parent); result.setParentOrderLine(parent);
@ -151,25 +167,6 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
return result; return result;
} }
/**
* Constructor for hibernate. Do not use!
*/
public HoursGroup() {
}
private HoursGroup(OrderLine parentOrderLine) {
this.parentOrderLine = parentOrderLine;
String code = parentOrderLine.getCode();
this.setCode(code != null ? code : "");
this.setOrderLineTemplate(null);
}
private HoursGroup(OrderLineTemplate orderLineTemplate) {
this.orderLineTemplate = orderLineTemplate;
this.setParentOrderLine(null);
}
public ResourceEnum getResourceType() { public ResourceEnum getResourceType() {
return resourceType; return resourceType;
} }
@ -259,6 +256,7 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
throw new IllegalStateException( throw new IllegalStateException(
"Criterion cannot be assigned to this Hours Group. Criterion Resource Type is of a different type"); "Criterion cannot be assigned to this Hours Group. Criterion Resource Type is of a different type");
} }
if ( existSameCriterionRequirement(requirement) ) { if ( existSameCriterionRequirement(requirement) ) {
throw new IllegalStateException( throw new IllegalStateException(
"Criterion cannot be assigned to this Hours Group. Criterion already exist within Hours Group"); "Criterion cannot be assigned to this Hours Group. Criterion already exist within Hours Group");
@ -327,14 +325,15 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
} }
private Set<CriterionRequirement> getCriterionRequirementsFromParent() { private Set<CriterionRequirement> getCriterionRequirementsFromParent() {
return (parentOrderLine != null) ? parentOrderLine.getCriterionRequirements() : return (parentOrderLine != null)
orderLineTemplate.getCriterionRequirements(); ? parentOrderLine.getCriterionRequirements()
: orderLineTemplate.getCriterionRequirements();
} }
public Set<IndirectCriterionRequirement> getIndirectCriterionRequirement() { public Set<IndirectCriterionRequirement> getIndirectCriterionRequirement() {
Set<IndirectCriterionRequirement> list = new HashSet<>(); Set<IndirectCriterionRequirement> list = new HashSet<>();
for(CriterionRequirement criterionRequirement : criterionRequirements ){ for (CriterionRequirement criterionRequirement : criterionRequirements ) {
if ( criterionRequirement instanceof IndirectCriterionRequirement ){ if ( criterionRequirement instanceof IndirectCriterionRequirement ) {
list.add((IndirectCriterionRequirement) criterionRequirement); list.add((IndirectCriterionRequirement) criterionRequirement);
} }
} }
@ -343,8 +342,8 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
public Set<DirectCriterionRequirement> getDirectCriterionRequirement() { public Set<DirectCriterionRequirement> getDirectCriterionRequirement() {
Set<DirectCriterionRequirement> list = new HashSet<>(); Set<DirectCriterionRequirement> list = new HashSet<>();
for(CriterionRequirement criterionRequirement : criterionRequirements ){ for (CriterionRequirement criterionRequirement : criterionRequirements ) {
if ( criterionRequirement instanceof DirectCriterionRequirement ){ if ( criterionRequirement instanceof DirectCriterionRequirement ) {
list.add((DirectCriterionRequirement) criterionRequirement); list.add((DirectCriterionRequirement) criterionRequirement);
} }
} }
@ -359,6 +358,14 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
(resourceTypeRequirement.equals(ResourceEnum.getDefault()))); (resourceTypeRequirement.equals(ResourceEnum.getDefault())));
} }
/**
* Duplicate of {@link HoursGroup#isValidResourceType(CriterionRequirement)}.
* Needed because in my case I do not need to check equality with {@link ResourceEnum#getDefault()}.
*/
public boolean isValidResourceTypeChanged(CriterionRequirement newRequirement) {
return resourceType == null || resourceType.equals(newRequirement.getCriterion().getType().getResource());
}
boolean existSameCriterionRequirement(CriterionRequirement newRequirement) { boolean existSameCriterionRequirement(CriterionRequirement newRequirement) {
Criterion criterion = newRequirement.getCriterion(); Criterion criterion = newRequirement.getCriterion();
for (CriterionRequirement requirement : getCriterionRequirements()){ for (CriterionRequirement requirement : getCriterionRequirements()){
@ -390,9 +397,11 @@ public class HoursGroup extends IntegrationEntity implements Cloneable, ICriteri
return Registry.getHoursGroupDAO(); return Registry.getHoursGroupDAO();
} }
/**
* The automatic checking of this constraint is avoided because it uses the wrong code property.
*/
@Override @Override
public boolean isUniqueCodeConstraint() { public boolean isUniqueCodeConstraint() {
// The automatic checking of this constraint is avoided because it uses the wrong code property
return true; return true;
} }

View file

@ -75,24 +75,6 @@ import org.libreplan.business.util.deepcopy.DeepCopy;
*/ */
public class Order extends OrderLineGroup implements Comparable { public class Order extends OrderLineGroup implements Comparable {
public static Order create() {
Order order = new Order();
order.setNewObject(true);
return order;
}
public static Order createUnvalidated(String code) {
Order order = create(new Order(), code);
return order;
}
/**
* Constructor for hibernate. Do not use!
*/
public Order() {
}
private String responsible; private String responsible;
private Boolean dependenciesConstraintsHavePriority; private Boolean dependenciesConstraintsHavePriority;
@ -113,24 +95,24 @@ public class Order extends OrderLineGroup implements Comparable {
private String customerReference; private String customerReference;
private Map<Scenario, OrderVersion> scenarios = new HashMap<Scenario, OrderVersion>(); private Map<Scenario, OrderVersion> scenarios = new HashMap<>();
private Set<OrderAuthorization> orderAuthorizations = new HashSet<OrderAuthorization>(); private Set<OrderAuthorization> orderAuthorizations = new HashSet<>();
private CurrentVersionInfo currentVersionInfo; private CurrentVersionInfo currentVersionInfo;
private Set<CustomerCommunication> customerCommunications = new HashSet<CustomerCommunication>(); private Set<CustomerCommunication> customerCommunications = new HashSet<>();
@Valid @Valid
private SortedSet<DeadlineCommunication> deliveringDates = new TreeSet<DeadlineCommunication>( private SortedSet<DeadlineCommunication> deliveringDates = new TreeSet<>(new DeliverDateComparator());
new DeliverDateComparator());
@Valid @Valid
private SortedSet<EndDateCommunication> endDateCommunicationToCustomer = new TreeSet<EndDateCommunication>( private SortedSet<EndDateCommunication> endDateCommunicationToCustomer = new TreeSet<>(
new EndDateCommunicationComparator()); new EndDateCommunicationComparator());
public enum SchedulingMode { public enum SchedulingMode {
FORWARD, BACKWARDS; FORWARD,
BACKWARDS
} }
private SchedulingMode schedulingMode = SchedulingMode.FORWARD; private SchedulingMode schedulingMode = SchedulingMode.FORWARD;
@ -143,14 +125,31 @@ public class Order extends OrderLineGroup implements Comparable {
private Integer budgetMargin; private Integer budgetMargin;
public Order() {
/**
* Constructor for hibernate. Do not use!
*/
}
public static Order create() {
Order order = new Order();
order.setNewObject(true);
return order;
}
public static Order createUnvalidated(String code) {
Order order = create(new Order(), code);
return order;
}
public static class CurrentVersionInfo { public static class CurrentVersionInfo {
private final OrderVersion orderVersion; private final OrderVersion orderVersion;
private final boolean modifyingTheOwnerScenario; private final boolean modifyingTheOwnerScenario;
static CurrentVersionInfo create(Scenario scenario, static CurrentVersionInfo create(Scenario scenario, OrderVersion orderVersion) {
OrderVersion orderVersion) {
return new CurrentVersionInfo(scenario, orderVersion); return new CurrentVersionInfo(scenario, orderVersion);
} }
@ -205,7 +204,7 @@ public class Order extends OrderLineGroup implements Comparable {
} }
public void writeSchedulingDataChangesTo(Scenario currentScenario, public void writeSchedulingDataChangesTo(Scenario currentScenario,
OrderVersion newOrderVersion) { OrderVersion newOrderVersion) {
setVersionForScenario(currentScenario, newOrderVersion); setVersionForScenario(currentScenario, newOrderVersion);
writeSchedulingDataChangesTo( writeSchedulingDataChangesTo(
deepCopyWithNeededReplaces(newOrderVersion), deepCopyWithNeededReplaces(newOrderVersion),
@ -403,7 +402,7 @@ public class Order extends OrderLineGroup implements Comparable {
@Override @Override
protected boolean applyConstraintBasedOnInitOrEndDate(Task task, protected boolean applyConstraintBasedOnInitOrEndDate(Task task,
boolean scheduleBackwards) { boolean scheduleBackwards) {
// the initDate or the deadline of a order doesn't imply a start // the initDate or the deadline of a order doesn't imply a start
// constraint at a task // constraint at a task
return false; return false;
@ -470,7 +469,7 @@ public class Order extends OrderLineGroup implements Comparable {
if ((hoursGroup.getCode() == null) if ((hoursGroup.getCode() == null)
|| (hoursGroup.getCode().isEmpty()) || (hoursGroup.getCode().isEmpty())
|| (!hoursGroup.getCode().startsWith( || (!hoursGroup.getCode().startsWith(
orderElement.getCode()))) { orderElement.getCode()))) {
((OrderLine) orderElement) ((OrderLine) orderElement)
.incrementLastHoursGroupSequenceCode(); .incrementLastHoursGroupSequenceCode();
String hoursGroupCode = EntitySequence.formatValue( String hoursGroupCode = EntitySequence.formatValue(
@ -493,7 +492,7 @@ public class Order extends OrderLineGroup implements Comparable {
result = prime result = prime
* result * result
+ ((getId() == null || isNewObject()) ? super.hashCode() + ((getId() == null || isNewObject()) ? super.hashCode()
: getId().hashCode()); : getId().hashCode());
return result; return result;
} }
@ -520,7 +519,7 @@ public class Order extends OrderLineGroup implements Comparable {
} }
public void setVersionForScenario(Scenario currentScenario, public void setVersionForScenario(Scenario currentScenario,
OrderVersion orderVersion) { OrderVersion orderVersion) {
scenarios.put(currentScenario, orderVersion); scenarios.put(currentScenario, orderVersion);
} }
@ -570,8 +569,7 @@ public class Order extends OrderLineGroup implements Comparable {
return null; return null;
} }
AdvanceType advanceType = PredefinedAdvancedTypes.SUBCONTRACTOR AdvanceType advanceType = PredefinedAdvancedTypes.SUBCONTRACTOR.getType();
.getType();
return getAdvanceAssignmentByType(advanceType); return getAdvanceAssignmentByType(advanceType);
} }
@ -696,7 +694,7 @@ public class Order extends OrderLineGroup implements Comparable {
@AssertTrue(message = "task code is repeated inside the project") @AssertTrue(message = "task code is repeated inside the project")
public boolean isUniqueCodeInsideOrderConstraint() { public boolean isUniqueCodeInsideOrderConstraint() {
List<String> codes = new ArrayList<String>(); List<String> codes = new ArrayList<>();
codes.add(getCode()); codes.add(getCode());
for (OrderElement child : getAllChildren()) { for (OrderElement child : getAllChildren()) {

View file

@ -29,9 +29,8 @@ import java.util.Date;
* This class is intended to work as a Hibernate component. * This class is intended to work as a Hibernate component.
* It represents the LibrePlan File to be stored in customer`s HDD. * It represents the LibrePlan File to be stored in customer`s HDD.
* *
* Created by *
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 25.12.2015.
* on 25.12.2015.
*/ */
public class OrderFile extends BaseEntity { public class OrderFile extends BaseEntity {

View file

@ -47,6 +47,19 @@ public class OrderLine extends OrderElement {
private HoursGroupOrderLineHandler hoursGroupOrderLineHandler = HoursGroupOrderLineHandler.getInstance(); private HoursGroupOrderLineHandler hoursGroupOrderLineHandler = HoursGroupOrderLineHandler.getInstance();
private BigDecimal budget = BigDecimal.ZERO.setScale(2);
private Set<HoursGroup> hoursGroups = new HashSet<>();
private Integer lastHoursGroupSequenceCode = 0;
private boolean convertedToContainer = false;
/**
* Constructor for hibernate. Do not use!
*/
public OrderLine() {}
public static OrderLine create() { public static OrderLine create() {
OrderLine result = new OrderLine(); OrderLine result = new OrderLine();
result.setNewObject(true); result.setNewObject(true);
@ -75,20 +88,6 @@ public class OrderLine extends OrderElement {
return result; return result;
} }
private BigDecimal budget = BigDecimal.ZERO.setScale(2);
/**
* Constructor for hibernate. Do not use!
*/
public OrderLine() {
}
private Set<HoursGroup> hoursGroups = new HashSet<>();
private Integer lastHoursGroupSequenceCode = 0;
private boolean convertedToContainer = false;
@Override @Override
public Integer getWorkHours() { public Integer getWorkHours() {
return hoursGroupOrderLineHandler.calculateTotalHours(hoursGroups); return hoursGroupOrderLineHandler.calculateTotalHours(hoursGroups);
@ -352,7 +351,6 @@ public class OrderLine extends OrderElement {
@Override @Override
public DirectAdvanceAssignment calculateFakeDirectAdvanceAssignment( public DirectAdvanceAssignment calculateFakeDirectAdvanceAssignment(
IndirectAdvanceAssignment indirectAdvanceAssignment) { IndirectAdvanceAssignment indirectAdvanceAssignment) {
return null; return null;
} }

View file

@ -60,8 +60,8 @@ import org.libreplan.business.trees.ITreeParentNode;
/** /**
* Represents every container in the WBS view. A task of the WBS that has some children.<br /> * Represents every container in the WBS view. A task of the WBS that has some children.
* * <br />
* The project itself is also an {@link OrderLineGroup}. * The project itself is also an {@link OrderLineGroup}.
* *
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>

View file

@ -33,15 +33,18 @@ import org.libreplan.business.util.deepcopy.DeepCopy;
/** /**
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*
*/ */
public class SchedulingDataForVersion extends BaseEntity { public class SchedulingDataForVersion extends BaseEntity {
public static class Data { @NotNull
private SchedulingState.Type schedulingStateType;
private static Data from(SchedulingDataForVersion version, OrderVersion orderVersion) { @NotNull
return new Data(orderVersion, version, version.getTaskSource(), version.getSchedulingStateType()); private OrderElement orderElement;
}
private TaskSource taskSource;
public static class Data {
private SchedulingDataForVersion originVersion; private SchedulingDataForVersion originVersion;
@ -68,6 +71,10 @@ public class SchedulingDataForVersion extends BaseEntity {
this.initialSchedulingStateType = schedulingStateType; this.initialSchedulingStateType = schedulingStateType;
} }
private static Data from(SchedulingDataForVersion version, OrderVersion orderVersion) {
return new Data(orderVersion, version, version.getTaskSource(), version.getSchedulingStateType());
}
public TaskSource getTaskSource() { public TaskSource getTaskSource() {
return taskSource; return taskSource;
} }
@ -134,12 +141,11 @@ public class SchedulingDataForVersion extends BaseEntity {
return hasPendingChanges; return hasPendingChanges;
} }
public Data pointsTo(DeepCopy deepCopy, OrderVersion orderVersion, public Data pointsTo(DeepCopy deepCopy, OrderVersion orderVersion, SchedulingDataForVersion schedulingVersion) {
SchedulingDataForVersion schedulingVersion) {
Validate.isTrue(!this.originVersion.equals(schedulingVersion)); Validate.isTrue(!this.originVersion.equals(schedulingVersion));
Data data = new Data(orderVersion, schedulingVersion, copy( Data data = new Data(orderVersion, schedulingVersion, copy(deepCopy, taskSource), schedulingStateType);
deepCopy, taskSource), schedulingStateType);
data.hasPendingChanges = true; data.hasPendingChanges = true;
return data; return data;
} }
@ -161,14 +167,6 @@ public class SchedulingDataForVersion extends BaseEntity {
return orderElement.isLeaf() ? Type.SCHEDULING_POINT : Type.NO_SCHEDULED; return orderElement.isLeaf() ? Type.SCHEDULING_POINT : Type.NO_SCHEDULED;
} }
@NotNull
private SchedulingState.Type schedulingStateType;
@NotNull
private OrderElement orderElement;
private TaskSource taskSource;
public SchedulingState.Type getSchedulingStateType() { public SchedulingState.Type getSchedulingStateType() {
return schedulingStateType; return schedulingStateType;
} }

View file

@ -45,9 +45,32 @@ import org.libreplan.business.util.deepcopy.Strategy;
*/ */
public class TaskSource extends BaseEntity { public class TaskSource extends BaseEntity {
@NotNull
private TaskElement task;
private SchedulingDataForVersion schedulingData;
@OnCopy(Strategy.SHARE_COLLECTION_ELEMENTS)
private Set<HoursGroup> hoursGroups = new HashSet<>();
public TaskSource() {}
public TaskSource(SchedulingDataForVersion schedulingState) {
Validate.notNull(schedulingState);
Validate.notNull(schedulingState.getOrderElement());
this.schedulingData = schedulingState;
OrderElement orderElement = schedulingState.getOrderElement();
Type orderElementType = orderElement.getSchedulingState().getType();
if (orderElementType == SchedulingState.Type.SCHEDULING_POINT) {
this.setHoursGroups(new HashSet<>(orderElement.getHoursGroups()));
}
}
public static TaskSource create(SchedulingDataForVersion schedulingState, List<HoursGroup> hoursGroups) { public static TaskSource create(SchedulingDataForVersion schedulingState, List<HoursGroup> hoursGroups) {
TaskSource result = create(new TaskSource(schedulingState)); TaskSource result = create(new TaskSource(schedulingState));
result.setHoursGroups(new HashSet<HoursGroup>(hoursGroups)); result.setHoursGroups(new HashSet<>(hoursGroups));
return result; return result;
} }
@ -59,6 +82,7 @@ public class TaskSource extends BaseEntity {
public Task createTaskWithoutDatesInitializedAndLinkItToTaskSource() { public Task createTaskWithoutDatesInitializedAndLinkItToTaskSource() {
TaskElement task = Task.createTaskWithoutDatesInitialized(this); TaskElement task = Task.createTaskWithoutDatesInitialized(this);
this.setTask(task); this.setTask(task);
return (Task) task; return (Task) task;
} }
@ -70,17 +94,18 @@ public class TaskSource extends BaseEntity {
public TaskGroup createTaskGroupWithoutDatesInitializedAndLinkItToTaskSource() { public TaskGroup createTaskGroupWithoutDatesInitializedAndLinkItToTaskSource() {
TaskElement task = TaskGroup.create(this); TaskElement task = TaskGroup.create(this);
this.setTask(task); this.setTask(task);
return (TaskGroup) task; return (TaskGroup) task;
} }
public static TaskSourceSynchronization mustAdd( public static TaskSourceSynchronization mustAdd(TaskSource taskSource) {
TaskSource taskSource) {
return new TaskSourceMustBeAdded(taskSource); return new TaskSourceMustBeAdded(taskSource);
} }
public static TaskSourceSynchronization mustAddGroup(TaskSource taskSource, public static TaskSourceSynchronization mustAddGroup(TaskSource taskSource,
List<TaskSourceSynchronization> childrenOfGroup) { List<TaskSourceSynchronization> childrenOfGroup) {
return new TaskGroupMustBeAdded(taskSource, childrenOfGroup); return new TaskGroupMustBeAdded(taskSource, childrenOfGroup);
} }
@ -90,18 +115,16 @@ public class TaskSource extends BaseEntity {
public interface IOptionalPersistence { public interface IOptionalPersistence {
public void save(TaskSource taskSource); void save(TaskSource taskSource);
public void remove(TaskSource taskSource); void remove(TaskSource taskSource);
} }
public static IOptionalPersistence persistTaskSources( public static IOptionalPersistence persistTaskSources(ITaskSourceDAO taskSourceDAO) {
ITaskSourceDAO taskSourceDAO) {
return new RealPersistence(taskSourceDAO, true); return new RealPersistence(taskSourceDAO, true);
} }
public static IOptionalPersistence persistButDontRemoveTaskSources( public static IOptionalPersistence persistButDontRemoveTaskSources(ITaskSourceDAO taskSourceDAO) {
ITaskSourceDAO taskSourceDAO) {
return new RealPersistence(taskSourceDAO, false); return new RealPersistence(taskSourceDAO, false);
} }
@ -115,8 +138,7 @@ public class TaskSource extends BaseEntity {
private final boolean removeTaskSources; private final boolean removeTaskSources;
public RealPersistence(ITaskSourceDAO taskSourceDAO, public RealPersistence(ITaskSourceDAO taskSourceDAO, boolean removeTaskSources) {
boolean removeTaskSources) {
Validate.notNull(taskSourceDAO); Validate.notNull(taskSourceDAO);
this.taskSourceDAO = taskSourceDAO; this.taskSourceDAO = taskSourceDAO;
this.removeTaskSources = removeTaskSources; this.removeTaskSources = removeTaskSources;
@ -132,34 +154,27 @@ public class TaskSource extends BaseEntity {
if (!removeTaskSources) { if (!removeTaskSources) {
return; return;
} }
try { try {
taskSourceDAO.remove(taskSource.getId()); taskSourceDAO.remove(taskSource.getId());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
// Flushing is required in order to avoid violation of
// unique // Flushing is required in order to avoid violation of unique constraint.
// constraint. If flush is not done and there is a task // If flush is not done and there is a task source that must be removed and another is created for the same
// source // order element the unique constraint "tasksource_orderelement_key" would be violated by Hibernate.
// that must be removed and another is created for the same
// order element the unique constraint
// "tasksource_orderelement_key" would be violated by
// hibernate
taskSourceDAO.flush(); taskSourceDAO.flush();
} }
} }
private static class NoPersistence implements IOptionalPersistence { private static class NoPersistence implements IOptionalPersistence {
@Override
public void save(TaskSource taskSource) {}
@Override @Override
public void save(TaskSource taskSource) { public void remove(TaskSource taskSource) {}
}
@Override
public void remove(TaskSource taskSource) {
}
} }
public static abstract class TaskSourceSynchronization { public static abstract class TaskSourceSynchronization {
@ -180,6 +195,7 @@ public class TaskSource extends BaseEntity {
Task result = Task.createTask(taskSource); Task result = Task.createTask(taskSource);
taskSource.setTask(result); taskSource.setTask(result);
persistence.save(taskSource); persistence.save(taskSource);
return result; return result;
} }
} }
@ -197,6 +213,7 @@ public class TaskSource extends BaseEntity {
updateTaskWithOrderElement(taskSource.getTask(), taskSource.getOrderElement()); updateTaskWithOrderElement(taskSource.getTask(), taskSource.getOrderElement());
updatePositionRestrictions(); updatePositionRestrictions();
persistence.save(taskSource); persistence.save(taskSource);
return taskSource.getTask(); return taskSource.getTask();
} }
@ -204,25 +221,22 @@ public class TaskSource extends BaseEntity {
if (hasSomeAllocationDone(taskSource.getTask())) { if (hasSomeAllocationDone(taskSource.getTask())) {
return; return;
} }
taskSource.getOrderElement().updatePositionConstraintOf( taskSource.getOrderElement().updatePositionConstraintOf((Task) taskSource.getTask());
(Task) taskSource.getTask());
} }
private static boolean hasSomeAllocationDone(TaskElement taskElement) {
} return !taskElement.getAllResourceAllocations().isEmpty();
}
private static boolean hasSomeAllocationDone(TaskElement taskElement) {
return !taskElement.getAllResourceAllocations().isEmpty();
} }
/** /**
* This method updates the task with a name and a start date. The start date * This method updates the task with a name and a start date.
* and end date should never be null, unless it's legacy data * The start date and end date should never be null, unless it's legacy data.
*
* @param task * @param task
* @param orderElement * @param orderElement
*/ */
private static void updateTaskWithOrderElement(TaskElement task, private static void updateTaskWithOrderElement(TaskElement task, OrderElement orderElement) {
OrderElement orderElement) {
task.setName(orderElement.getName()); task.setName(orderElement.getName());
Date orderInitDate = orderElement.getOrder().getInitDate(); Date orderInitDate = orderElement.getOrder().getInitDate();
if (task.getIntraDayStartDate() == null && orderInitDate != null) { if (task.getIntraDayStartDate() == null && orderInitDate != null) {
@ -232,15 +246,13 @@ public class TaskSource extends BaseEntity {
task.updateDeadlineFromOrderElement(); task.updateDeadlineFromOrderElement();
} }
public static abstract class TaskGroupSynchronization extends public abstract static class TaskGroupSynchronization extends TaskSourceSynchronization {
TaskSourceSynchronization {
protected final TaskSource taskSource; protected final TaskSource taskSource;
private final List<TaskSourceSynchronization> synchronizations; private final List<TaskSourceSynchronization> synchronizations;
protected TaskGroupSynchronization(TaskSource taskSource, protected TaskGroupSynchronization(TaskSource taskSource, List<TaskSourceSynchronization> synchronizations) {
List<TaskSourceSynchronization> synchronizations) {
Validate.notNull(taskSource); Validate.notNull(taskSource);
Validate.notNull(synchronizations); Validate.notNull(synchronizations);
this.taskSource = taskSource; this.taskSource = taskSource;
@ -254,11 +266,12 @@ public class TaskSource extends BaseEntity {
@Override @Override
public TaskElement apply(IOptionalPersistence persistence) { public TaskElement apply(IOptionalPersistence persistence) {
List<TaskElement> children = getChildren(persistence); List<TaskElement> children = getChildren(persistence);
return apply(children, persistence); return apply(children, persistence);
} }
private List<TaskElement> getChildren(IOptionalPersistence persistence) { private List<TaskElement> getChildren(IOptionalPersistence persistence) {
List<TaskElement> result = new ArrayList<TaskElement>(); List<TaskElement> result = new ArrayList<>();
for (TaskSourceSynchronization each : synchronizations) { for (TaskSourceSynchronization each : synchronizations) {
TaskElement t = each.apply(persistence); TaskElement t = each.apply(persistence);
if (t != null) { if (t != null) {
@ -266,49 +279,46 @@ public class TaskSource extends BaseEntity {
result.add(t); result.add(t);
} }
} }
return result; return result;
} }
protected abstract TaskElement apply(List<TaskElement> children, protected abstract TaskElement apply(List<TaskElement> children, IOptionalPersistence persistence);
IOptionalPersistence persistence);
} }
static class TaskGroupMustBeAdded extends TaskGroupSynchronization { static class TaskGroupMustBeAdded extends TaskGroupSynchronization {
private TaskGroupMustBeAdded(TaskSource taskSource, private TaskGroupMustBeAdded(TaskSource taskSource, List<TaskSourceSynchronization> synchronizations) {
List<TaskSourceSynchronization> synchronizations) {
super(taskSource, synchronizations); super(taskSource, synchronizations);
} }
@Override @Override
protected TaskElement apply(List<TaskElement> children, protected TaskElement apply(List<TaskElement> children, IOptionalPersistence persistence) {
IOptionalPersistence persistence) {
TaskGroup result = TaskGroup.create(taskSource); TaskGroup result = TaskGroup.create(taskSource);
for (TaskElement taskElement : children) { for (TaskElement taskElement : children) {
result.addTaskElement(taskElement); result.addTaskElement(taskElement);
} }
taskSource.setTask(result); taskSource.setTask(result);
persistence.save(taskSource); persistence.save(taskSource);
return result; return result;
} }
} }
static class TaskSourceForTaskGroupModified extends static class TaskSourceForTaskGroupModified extends TaskGroupSynchronization {
TaskGroupSynchronization {
TaskSourceForTaskGroupModified(TaskSource taskSource, TaskSourceForTaskGroupModified(TaskSource taskSource, List<TaskSourceSynchronization> synchronizations) {
List<TaskSourceSynchronization> synchronizations) {
super(taskSource, synchronizations); super(taskSource, synchronizations);
} }
@Override @Override
protected TaskElement apply(List<TaskElement> children, protected TaskElement apply(List<TaskElement> children, IOptionalPersistence persistence) {
IOptionalPersistence persistence) {
TaskGroup taskGroup = (TaskGroup) taskSource.getTask(); TaskGroup taskGroup = (TaskGroup) taskSource.getTask();
taskGroup.setTaskChildrenTo(children); taskGroup.setTaskChildrenTo(children);
updateTaskWithOrderElement(taskGroup, taskSource.getOrderElement()); updateTaskWithOrderElement(taskGroup, taskSource.getOrderElement());
persistence.save(taskSource); persistence.save(taskSource);
return taskGroup; return taskGroup;
} }
} }
@ -325,13 +335,13 @@ public class TaskSource extends BaseEntity {
public TaskElement apply(IOptionalPersistence optionalPersistence) { public TaskElement apply(IOptionalPersistence optionalPersistence) {
taskSource.getTask().detach(); taskSource.getTask().detach();
optionalPersistence.remove(taskSource); optionalPersistence.remove(taskSource);
return null; return null;
} }
} }
public static TaskSource withHoursGroupOf( public static TaskSource withHoursGroupOf(SchedulingDataForVersion schedulingState) {
SchedulingDataForVersion schedulingState) {
return create(new TaskSource(schedulingState)); return create(new TaskSource(schedulingState));
} }
@ -339,38 +349,12 @@ public class TaskSource extends BaseEntity {
return create(new TaskSource(schedulingState)); return create(new TaskSource(schedulingState));
} }
@NotNull public TaskSourceSynchronization withCurrentHoursGroup(List<HoursGroup> hoursGroups) {
private TaskElement task; setHoursGroups(new HashSet<>(hoursGroups));
private SchedulingDataForVersion schedulingData;
@OnCopy(Strategy.SHARE_COLLECTION_ELEMENTS)
private Set<HoursGroup> hoursGroups = new HashSet<HoursGroup>();
public TaskSource() {
}
public TaskSource(SchedulingDataForVersion schedulingState) {
Validate.notNull(schedulingState);
Validate.notNull(schedulingState.getOrderElement());
this.schedulingData = schedulingState;
OrderElement orderElement = schedulingState.getOrderElement();
Type orderElementType = orderElement
.getSchedulingState().getType();
if (orderElementType == SchedulingState.Type.SCHEDULING_POINT) {
this.setHoursGroups(new HashSet<HoursGroup>(orderElement
.getHoursGroups()));
}
}
public TaskSourceSynchronization withCurrentHoursGroup(
List<HoursGroup> hoursGroups) {
setHoursGroups(new HashSet<HoursGroup>(hoursGroups));
return new TaskSourceForTaskModified(this); return new TaskSourceForTaskModified(this);
} }
public TaskSourceSynchronization modifyGroup( public TaskSourceSynchronization modifyGroup(List<TaskSourceSynchronization> childrenOfGroup) {
List<TaskSourceSynchronization> childrenOfGroup) {
return new TaskSourceForTaskGroupModified(this, childrenOfGroup); return new TaskSourceForTaskGroupModified(this, childrenOfGroup);
} }
@ -408,6 +392,7 @@ public class TaskSource extends BaseEntity {
for (HoursGroup each : hoursGroups) { for (HoursGroup each : hoursGroups) {
result += each.getWorkingHours(); result += each.getWorkingHours();
} }
return result; return result;
} }

View file

@ -45,13 +45,13 @@ import org.libreplan.business.workingday.EffortDuration.IEffortFrom;
import org.libreplan.business.workingday.IntraDayDate.PartialDay; import org.libreplan.business.workingday.IntraDayDate.PartialDay;
/** /**
* This class groups the calculation of the three values needed for the * This class groups the calculation of the three values needed for the chart of the company global resource load.
* chart of the company global resource load. The purpose of the class is * The purpose of the class is having these data pre-calculated to prevent heavy algorithms being
* having these data pre-calculated to prevent heavy algorithms being
* run each time the chart is shown. * run each time the chart is shown.
* @see PredefinedDatabaseSnapshots
* @author Jacobo Aragunde Pérez<jaragunde@igalia.com>
* *
* @see PredefinedDatabaseSnapshots
*
* @author Jacobo Aragunde Pérez<jaragunde@igalia.com>
*/ */
public class ResourceLoadChartData implements ILoadChartData { public class ResourceLoadChartData implements ILoadChartData {
@ -66,25 +66,24 @@ public class ResourceLoadChartData implements ILoadChartData {
} }
public ResourceLoadChartData(List<DayAssignment> dayAssignments, public ResourceLoadChartData(List<DayAssignment> dayAssignments,
List<Resource> resources, LocalDate startInclusive, List<Resource> resources,
LocalDate endExclusive) { LocalDate startInclusive,
LocalDate endExclusive) {
ContiguousDaysLine<List<DayAssignment>> assignments = ContiguousDaysLine.byDay(dayAssignments);
ContiguousDaysLine<List<DayAssignment>> assignments = ContiguousDaysLine
.byDay(dayAssignments);
if (startInclusive != null && endExclusive != null) { if (startInclusive != null && endExclusive != null) {
assignments = assignments.subInterval(startInclusive, endExclusive); assignments = assignments.subInterval(startInclusive, endExclusive);
} }
ContiguousDaysLine<EffortDuration> load = assignments
.transform(extractLoad());
ContiguousDaysLine<EffortDuration> overload = assignments ContiguousDaysLine<EffortDuration> load = assignments.transform(extractLoad());
.transform(extractOverload());
ContiguousDaysLine<EffortDuration> availabilityOnAllResources = assignments ContiguousDaysLine<EffortDuration> overload = assignments.transform(extractOverload());
.transform(extractAvailabilityOnAllResources(resources));
this.load = toSortedMap(ContiguousDaysLine.min(load, ContiguousDaysLine<EffortDuration> availabilityOnAllResources =
availabilityOnAllResources)); assignments.transform(extractAvailabilityOnAllResources(resources));
this.load = toSortedMap(ContiguousDaysLine.min(load, availabilityOnAllResources));
this.overload = toSortedMap(sum(overload, availabilityOnAllResources)); this.overload = toSortedMap(sum(overload, availabilityOnAllResources));
this.availability = toSortedMap(availabilityOnAllResources); this.availability = toSortedMap(availabilityOnAllResources);
} }
@ -97,15 +96,11 @@ public class ResourceLoadChartData implements ILoadChartData {
return new IValueTransformer<List<DayAssignment>, Map<Resource, EffortDuration>>() { return new IValueTransformer<List<DayAssignment>, Map<Resource, EffortDuration>>() {
@Override @Override
public Map<Resource, EffortDuration> transform(LocalDate day, public Map<Resource, EffortDuration> transform(LocalDate day, List<DayAssignment> previousValue) {
List<DayAssignment> previousValue) { Map<Resource, List<DayAssignment>> byResource = DayAssignment.byResource(previousValue);
Map<Resource, List<DayAssignment>> byResource = DayAssignment Map<Resource, EffortDuration> result = new HashMap<>();
.byResource(previousValue); for (Entry<Resource, List<DayAssignment>> each : byResource.entrySet()) {
Map<Resource, EffortDuration> result = new HashMap<Resource, EffortDuration>(); result.put(each.getKey(), DayAssignment.sum(each.getValue()));
for (Entry<Resource, List<DayAssignment>> each : byResource
.entrySet()) {
result.put(each.getKey(),
DayAssignment.sum(each.getValue()));
} }
return result; return result;
} }
@ -114,24 +109,20 @@ public class ResourceLoadChartData implements ILoadChartData {
public static IValueTransformer<Map<Resource, EffortDuration>, EffortDuration> calculateOverload() { public static IValueTransformer<Map<Resource, EffortDuration>, EffortDuration> calculateOverload() {
return new IValueTransformer<Map<Resource, EffortDuration>, EffortDuration>() { return new IValueTransformer<Map<Resource, EffortDuration>, EffortDuration>() {
@Override @Override
public EffortDuration transform(LocalDate day, public EffortDuration transform(LocalDate day, Map<Resource, EffortDuration> previousValue) {
Map<Resource, EffortDuration> previousValue) {
final PartialDay wholeDay = PartialDay.wholeDay(day); final PartialDay wholeDay = PartialDay.wholeDay(day);
return EffortDuration.sum(previousValue.entrySet(),
new IEffortFrom<Entry<Resource, EffortDuration>>() {
@Override return EffortDuration.sum(previousValue.entrySet(), new IEffortFrom<Entry<Resource, EffortDuration>>() {
public EffortDuration from( @Override
Entry<Resource, EffortDuration> each) { public EffortDuration from(Entry<Resource, EffortDuration> each) {
EffortDuration capacity = calendarCapacityFor( EffortDuration capacity = calendarCapacityFor(each.getKey(), wholeDay);
each.getKey(), wholeDay); EffortDuration assigned = each.getValue();
EffortDuration assigned = each.getValue();
return assigned.minus(min(capacity, assigned)); return assigned.minus(min(capacity, assigned));
} }
}); });
} }
}; };
} }
@ -140,8 +131,7 @@ public class ResourceLoadChartData implements ILoadChartData {
return new IValueTransformer<List<DayAssignment>, EffortDuration>() { return new IValueTransformer<List<DayAssignment>, EffortDuration>() {
@Override @Override
public EffortDuration transform(LocalDate day, public EffortDuration transform(LocalDate day, List<DayAssignment> previousValue) {
List<DayAssignment> previousValue) {
return DayAssignment.sum(previousValue); return DayAssignment.sum(previousValue);
} }
}; };
@ -151,14 +141,14 @@ public class ResourceLoadChartData implements ILoadChartData {
return new IValueTransformer<List<DayAssignment>, EffortDuration>() { return new IValueTransformer<List<DayAssignment>, EffortDuration>() {
@Override @Override
public EffortDuration transform(LocalDate day, public EffortDuration transform(LocalDate day, List<DayAssignment> previousValue) {
List<DayAssignment> previousValue) {
Set<Resource> resources = getResources(previousValue); Set<Resource> resources = getResources(previousValue);
return sumCalendarCapacitiesForDay(resources, day); return sumCalendarCapacitiesForDay(resources, day);
} }
private Set<Resource> getResources(List<DayAssignment> assignments) { private Set<Resource> getResources(List<DayAssignment> assignments) {
Set<Resource> resources = new HashSet<Resource>(); Set<Resource> resources = new HashSet<>();
for (DayAssignment dayAssignment : assignments) { for (DayAssignment dayAssignment : assignments) {
resources.add(dayAssignment.getResource()); resources.add(dayAssignment.getResource());
} }
@ -169,11 +159,11 @@ public class ResourceLoadChartData implements ILoadChartData {
private IValueTransformer<List<DayAssignment>, EffortDuration> extractAvailabilityOnAllResources( private IValueTransformer<List<DayAssignment>, EffortDuration> extractAvailabilityOnAllResources(
final List<Resource> resources) { final List<Resource> resources) {
return new IValueTransformer<List<DayAssignment>, EffortDuration>() { return new IValueTransformer<List<DayAssignment>, EffortDuration>() {
@Override @Override
public EffortDuration transform(LocalDate day, public EffortDuration transform(LocalDate day, List<DayAssignment> previousValue) {
List<DayAssignment> previousValue) {
return sumCalendarCapacitiesForDay(resources, day); return sumCalendarCapacitiesForDay(resources, day);
} }
}; };
@ -191,13 +181,14 @@ public class ResourceLoadChartData implements ILoadChartData {
return availability; return availability;
} }
public ILoadChartData on(final LocalDate startInclusive, public ILoadChartData on(final LocalDate startInclusive, final LocalDate endExclusive) {
final LocalDate endExclusive) {
final ResourceLoadChartData original = ResourceLoadChartData.this; final ResourceLoadChartData original = ResourceLoadChartData.this;
if (startInclusive == null && endExclusive == null) { if (startInclusive == null && endExclusive == null) {
return original; return original;
} }
return new ILoadChartData() { return new ILoadChartData() {
@Override @Override
@ -215,21 +206,21 @@ public class ResourceLoadChartData implements ILoadChartData {
return filter(original.getAvailability()); return filter(original.getAvailability());
} }
private SortedMap<LocalDate, EffortDuration> filter( private SortedMap<LocalDate, EffortDuration> filter(SortedMap<LocalDate, EffortDuration> map) {
SortedMap<LocalDate, EffortDuration> map) {
if (startInclusive != null) { if (startInclusive != null) {
return map.tailMap(startInclusive); return map.tailMap(startInclusive);
} }
if (endExclusive != null) { if (endExclusive != null) {
return map.headMap(endExclusive); return map.headMap(endExclusive);
} }
return map.subMap(startInclusive, endExclusive); return map.subMap(startInclusive, endExclusive);
} }
}; };
} }
private static EffortDuration sumCalendarCapacitiesForDay( private static EffortDuration sumCalendarCapacitiesForDay(Collection<? extends Resource> resources, LocalDate day) {
Collection<? extends Resource> resources, LocalDate day) {
final PartialDay wholeDay = PartialDay.wholeDay(day); final PartialDay wholeDay = PartialDay.wholeDay(day);
@ -241,8 +232,7 @@ public class ResourceLoadChartData implements ILoadChartData {
}); });
} }
protected static EffortDuration calendarCapacityFor(Resource resource, protected static EffortDuration calendarCapacityFor(Resource resource, PartialDay day) {
PartialDay day) {
return resource.getCalendarOrDefault().getCapacityOn(day); return resource.getCalendarOrDefault().getCapacityOn(day);
} }

View file

@ -30,7 +30,7 @@ import org.libreplan.business.planner.entities.TaskGroup;
/** /**
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public interface ITaskElementDAO extends IGenericDAO<TaskElement, Long> { public interface ITaskElementDAO extends IGenericDAO<TaskElement, Long> {

View file

@ -25,7 +25,5 @@ import org.libreplan.business.orders.entities.TaskSource;
/** /**
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*
*/ */
public interface ITaskSourceDAO extends IGenericDAO<TaskSource, Long> { public interface ITaskSourceDAO extends IGenericDAO<TaskSource, Long> {}
}

View file

@ -21,7 +21,6 @@ package org.libreplan.business.planner.daos;
import java.util.List; import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.GenericDAOHibernate; import org.libreplan.business.common.daos.GenericDAOHibernate;
import org.libreplan.business.planner.entities.SubcontractorCommunication; import org.libreplan.business.planner.entities.SubcontractorCommunication;
@ -31,12 +30,14 @@ import org.springframework.stereotype.Repository;
/** /**
* DAO for {@link SubcontractorCommunication} * DAO for {@link SubcontractorCommunication}
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class SubcontractorCommunicationDAO extends GenericDAOHibernate<SubcontractorCommunication, Long> public class SubcontractorCommunicationDAO
extends GenericDAOHibernate<SubcontractorCommunication, Long>
implements ISubcontractorCommunicationDAO { implements ISubcontractorCommunicationDAO {
@Override @Override
@ -46,8 +47,9 @@ public class SubcontractorCommunicationDAO extends GenericDAOHibernate<Subcontra
@Override @Override
public List<SubcontractorCommunication> getAllNotReviewed(){ public List<SubcontractorCommunication> getAllNotReviewed(){
Criteria c = getSession().createCriteria(SubcontractorCommunication.class); return getSession()
c.add(Restrictions.eq("reviewed", false)); .createCriteria(SubcontractorCommunication.class)
return c.list(); .add(Restrictions.eq("reviewed", false))
.list();
} }
} }

View file

@ -42,12 +42,11 @@ import org.springframework.transaction.annotation.Transactional;
/** /**
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Jacobo Aragunde Pérez <jaragunde@igalia.com> * @author Jacobo Aragunde Pérez <jaragunde@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class TaskElementDAO extends GenericDAOHibernate<TaskElement, Long> public class TaskElementDAO extends GenericDAOHibernate<TaskElement, Long> implements ITaskElementDAO {
implements ITaskElementDAO {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
@ -102,7 +101,8 @@ public class TaskElementDAO extends GenericDAOHibernate<TaskElement, Long>
} }
private void updateSumOfAllocatedHoursToParent(TaskGroup taskGroup, private void updateSumOfAllocatedHoursToParent(TaskGroup taskGroup,
EffortDuration oldAssignedEffort, EffortDuration newAssignedEffort) { EffortDuration oldAssignedEffort,
EffortDuration newAssignedEffort) {
if (taskGroup != null) { if (taskGroup != null) {
if (!Hibernate.isInitialized(taskGroup)) { if (!Hibernate.isInitialized(taskGroup)) {
reattach(taskGroup); reattach(taskGroup);

View file

@ -28,11 +28,7 @@ import org.springframework.stereotype.Repository;
/** /**
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class TaskSourceDAO extends GenericDAOHibernate<TaskSource, Long> public class TaskSourceDAO extends GenericDAOHibernate<TaskSource, Long> implements ITaskSourceDAO {}
implements ITaskSourceDAO {
}

View file

@ -28,31 +28,27 @@ import java.util.List;
import org.libreplan.business.common.BaseEntity; import org.libreplan.business.common.BaseEntity;
/** /**
* Represents entity AssignmentFunction.
* *
* @author Diego Pino García <dpino@igalia.com> * @author Diego Pino García <dpino@igalia.com>
*
*/ */
public abstract class AssignmentFunction extends BaseEntity { public abstract class AssignmentFunction extends BaseEntity {
/** /**
* This method goes over the {@link ResourceAllocation} list and apply the * This method goes over the {@link ResourceAllocation} list and apply the assignment function if it is defined.
* assignment function if it is defined.
* *
* As this is called at the end of {@link Task#doAllocation} and a flat * As this is called at the end of {@link Task#doAllocation} and a flat allocation was already applied before.
* allocation was already applied before. If assignment function was set to * If assignment function was set to manual it is reseted to flat again.
* manual it is reseted to flat again.
* *
* @param resourceAllocations * @param resourceAllocations
* List of {@link ResourceAllocation} * List of {@link ResourceAllocation}
*/ */
public static void applyAssignmentFunctionsIfAny( public static void applyAssignmentFunctionsIfAny(List<ResourceAllocation<?>> resourceAllocations) {
List<ResourceAllocation<?>> resourceAllocations) {
for (ResourceAllocation<?> resourceAllocation : resourceAllocations) { for (ResourceAllocation<?> resourceAllocation : resourceAllocations) {
AssignmentFunction assignmentFunction = resourceAllocation AssignmentFunction assignmentFunction = resourceAllocation.getAssignmentFunction();
.getAssignmentFunction();
if (assignmentFunction != null) { if (assignmentFunction != null) {
if (assignmentFunction.isManual()) { if (assignmentFunction.isManual()) {
// reset to flat // Reset to flat
resourceAllocation.setAssignmentFunctionWithoutApply(null); resourceAllocation.setAssignmentFunctionWithoutApply(null);
} else { } else {
assignmentFunction.applyTo(resourceAllocation); assignmentFunction.applyTo(resourceAllocation);
@ -64,6 +60,7 @@ public abstract class AssignmentFunction extends BaseEntity {
/** /**
* This method applies the function to the received resourceAllocation * This method applies the function to the received resourceAllocation
* <i>This method is intended to be overridden by subclasses</i> * <i>This method is intended to be overridden by subclasses</i>
*
* @param resourceAllocation * @param resourceAllocation
*/ */
public abstract void applyTo(ResourceAllocation<?> resourceAllocation); public abstract void applyTo(ResourceAllocation<?> resourceAllocation);
@ -81,10 +78,11 @@ public abstract class AssignmentFunction extends BaseEntity {
private String name; private String name;
private AssignmentFunctionName(String name) { AssignmentFunctionName(String name) {
this.name = name; this.name = name;
} }
@Override
public String toString() { public String toString() {
return name; return name;
} }

View file

@ -56,86 +56,82 @@ import org.libreplan.business.workingday.ResourcesPerDay;
/** /**
* Represents the relation between {@link Task} and a generic {@link Resource}. * Represents the relation between {@link Task} and a generic {@link Resource}.
*
* @author Diego Pino García <dpino@igalia.com> * @author Diego Pino García <dpino@igalia.com>
*/ */
public class GenericResourceAllocation extends public class GenericResourceAllocation extends ResourceAllocation<GenericDayAssignment> {
ResourceAllocation<GenericDayAssignment> {
@OnCopy(Strategy.SHARE_COLLECTION_ELEMENTS)
private Set<Criterion> criterions = new HashSet<>();
@OnCopy(Strategy.SHARE)
private ResourceEnum resourceType;
private Set<GenericDayAssignmentsContainer> genericDayAssignmentsContainers = new HashSet<>();
private IAssignedEffortForResource assignedEffortForResource = null;
/**
* Constructor for Hibernate. DO NOT USE!
*/
public GenericResourceAllocation() {}
public static GenericResourceAllocation create() { public static GenericResourceAllocation create() {
return create(new GenericResourceAllocation()); return create(new GenericResourceAllocation());
} }
public static GenericResourceAllocation createForTesting( public static GenericResourceAllocation createForTesting(ResourcesPerDay resourcesPerDay, Task task) {
ResourcesPerDay resourcesPerDay, Task task) { return create(new GenericResourceAllocation(resourcesPerDay, task));
return create(new GenericResourceAllocation(
resourcesPerDay, task));
} }
public static Map<Set<Criterion>, List<GenericResourceAllocation>> byCriterions( public static Map<Set<Criterion>, List<GenericResourceAllocation>> byCriterions(
Collection<GenericResourceAllocation> genericAllocations) { Collection<GenericResourceAllocation> genericAllocations) {
Map<Set<Criterion>, List<GenericResourceAllocation>> result = new HashMap<Set<Criterion>, List<GenericResourceAllocation>>(); Map<Set<Criterion>, List<GenericResourceAllocation>> result = new HashMap<>();
for (GenericResourceAllocation genericResourceAllocation : genericAllocations) { for (GenericResourceAllocation genericResourceAllocation : genericAllocations) {
Set<Criterion> criterions = genericResourceAllocation.getCriterions(); Set<Criterion> criterions = genericResourceAllocation.getCriterions();
if( !result.containsKey(criterions) ){
result.put(criterions, new ArrayList<GenericResourceAllocation>()); if ( !result.containsKey(criterions) ) {
result.put(criterions, new ArrayList<>());
} }
result.get(criterions).add(genericResourceAllocation); result.get(criterions).add(genericResourceAllocation);
} }
return result; return result;
} }
@OnCopy(Strategy.SHARE_COLLECTION_ELEMENTS)
private Set<Criterion> criterions = new HashSet<Criterion>();
@OnCopy(Strategy.SHARE)
private ResourceEnum resourceType;
private Set<GenericDayAssignmentsContainer> genericDayAssignmentsContainers = new HashSet<GenericDayAssignmentsContainer>();
@Valid @Valid
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Set<GenericDayAssignmentsContainer> getGenericDayAssignmentsContainers() { private Set<GenericDayAssignmentsContainer> getGenericDayAssignmentsContainers() {
return new HashSet<GenericDayAssignmentsContainer>( return new HashSet<>(genericDayAssignmentsContainers);
genericDayAssignmentsContainers);
} }
private GenericResourceAllocation(ResourcesPerDay resourcesPerDay, Task task) { private GenericResourceAllocation(ResourcesPerDay resourcesPerDay, Task task) {
super(resourcesPerDay, task); super(resourcesPerDay, task);
} }
/**
* Constructor for Hibernate. DO NOT USE!
*/
public GenericResourceAllocation() {
}
public static GenericResourceAllocation create(Task task) { public static GenericResourceAllocation create(Task task) {
return create(new GenericResourceAllocation( return create(new GenericResourceAllocation(task));
task));
} }
public static GenericResourceAllocation create(Task task, public static GenericResourceAllocation create(Task task, Collection<? extends Criterion> criterions) {
Collection<? extends Criterion> criterions) {
return create(task, inferType(criterions), criterions); return create(task, inferType(criterions), criterions);
} }
public static ResourceEnum inferType( public static ResourceEnum inferType(Collection<? extends Criterion> criterions) {
Collection<? extends Criterion> criterions) { return criterions.isEmpty()
if (criterions.isEmpty()) { ? ResourceEnum.WORKER
return ResourceEnum.WORKER; : criterions.iterator().next().getType().getResource();
}
Criterion first = criterions.iterator().next();
return first.getType().getResource();
} }
public static GenericResourceAllocation create(Task task, ResourceEnum resourceType, public static GenericResourceAllocation create(
Collection<? extends Criterion> criterions) { Task task, ResourceEnum resourceType, Collection<? extends Criterion> criterions) {
Validate.notNull(resourceType); Validate.notNull(resourceType);
GenericResourceAllocation result = new GenericResourceAllocation(task); GenericResourceAllocation result = new GenericResourceAllocation(task);
result.criterions = new HashSet<Criterion>(criterions); result.criterions = new HashSet<>(criterions);
result.resourceType = resourceType; result.resourceType = resourceType;
result.setResourcesPerDayToAmount(1); result.setResourcesPerDayToAmount(1);
return create(result); return create(result);
} }
@ -145,27 +141,25 @@ public class GenericResourceAllocation extends
} }
@Override @Override
protected GenericDayAssignmentsContainer retrieveOrCreateContainerFor( protected GenericDayAssignmentsContainer retrieveOrCreateContainerFor(Scenario scenario) {
Scenario scenario) {
GenericDayAssignmentsContainer retrieved = retrieveContainerFor(scenario); GenericDayAssignmentsContainer retrieved = retrieveContainerFor(scenario);
if (retrieved != null) { if (retrieved != null) {
return retrieved; return retrieved;
} }
GenericDayAssignmentsContainer result = GenericDayAssignmentsContainer
.create(this, scenario); GenericDayAssignmentsContainer result = GenericDayAssignmentsContainer.create(this, scenario);
genericDayAssignmentsContainers.add(result); genericDayAssignmentsContainers.add(result);
return result; return result;
} }
@Override @Override
protected GenericDayAssignmentsContainer retrieveContainerFor( protected GenericDayAssignmentsContainer retrieveContainerFor(Scenario scenario) {
Scenario scenario) { return containersByScenario().get(scenario);
Map<Scenario, GenericDayAssignmentsContainer> containers = containersByScenario();
return containers.get(scenario);
} }
private Map<Scenario, GenericDayAssignmentsContainer> containersByScenario() { private Map<Scenario, GenericDayAssignmentsContainer> containersByScenario() {
Map<Scenario, GenericDayAssignmentsContainer> result = new HashMap<Scenario, GenericDayAssignmentsContainer>(); Map<Scenario, GenericDayAssignmentsContainer> result = new HashMap<>();
for (GenericDayAssignmentsContainer each : genericDayAssignmentsContainers) { for (GenericDayAssignmentsContainer each : genericDayAssignmentsContainers) {
assert !result.containsKey(each); assert !result.containsKey(each);
result.put(each.getScenario(), each); result.put(each.getScenario(), each);
@ -174,30 +168,25 @@ public class GenericResourceAllocation extends
} }
public List<GenericDayAssignment> getOrderedAssignmentsFor(Resource resource) { public List<GenericDayAssignment> getOrderedAssignmentsFor(Resource resource) {
List<GenericDayAssignment> list = getOrderedAssignmentsFor().get( List<GenericDayAssignment> list = getOrderedAssignmentsFor().get(resource);
resource);
if (list == null) { return list == null ? Collections.emptyList() : Collections.unmodifiableList(list);
return Collections.emptyList();
}
return Collections.unmodifiableList(list);
} }
private Map<Resource, List<GenericDayAssignment>> getOrderedAssignmentsFor() { private Map<Resource, List<GenericDayAssignment>> getOrderedAssignmentsFor() {
return DayAssignment.byResourceAndOrdered(getDayAssignmentsState() return DayAssignment.byResourceAndOrdered(getDayAssignmentsState().getUnorderedAssignments());
.getUnorderedAssignments());
} }
public Set<Criterion> getCriterions() { public Set<Criterion> getCriterions() {
return Collections.unmodifiableSet(criterions); return Collections.unmodifiableSet(criterions);
} }
private final class ResourcesSatisfyingCriterionsSelector implements private final class ResourcesSatisfyingCriterionsSelector implements IResourceSelector {
IResourceSelector {
@Override @Override
public boolean isSelectable(Resource resource, LocalDate day) { public boolean isSelectable(Resource resource, LocalDate day) {
ICriterion compoundCriterion = CriterionCompounder.buildAnd( ICriterion compoundCriterion = CriterionCompounder.buildAnd(criterions).getResult();
criterions).getResult();
return compoundCriterion.isSatisfiedBy(resource, day); return compoundCriterion.isSatisfiedBy(resource, day);
} }
} }
@ -205,22 +194,21 @@ public class GenericResourceAllocation extends
private class GenericAllocation extends AssignmentsAllocator { private class GenericAllocation extends AssignmentsAllocator {
private EffortDistributor hoursDistributor; private EffortDistributor hoursDistributor;
private final List<Resource> resources; private final List<Resource> resources;
public GenericAllocation(List<Resource> resources) { public GenericAllocation(List<Resource> resources) {
this.resources = resources; this.resources = resources;
hoursDistributor = new EffortDistributor(resources, getAssignedEffortForResource(),
new ResourcesSatisfyingCriterionsSelector()); hoursDistributor = new EffortDistributor(
resources, getAssignedEffortForResource(), new ResourcesSatisfyingCriterionsSelector());
} }
@Override @Override
public List<GenericDayAssignment> distributeForDay(PartialDay day, public List<GenericDayAssignment> distributeForDay(PartialDay day, EffortDuration effort) {
EffortDuration effort) { List<GenericDayAssignment> result = new ArrayList<>();
List<GenericDayAssignment> result = new ArrayList<GenericDayAssignment>(); for (ResourceWithAssignedDuration each : hoursDistributor.distributeForDay(day, effort)) {
for (ResourceWithAssignedDuration each : hoursDistributor result.add(GenericDayAssignment.create(day.getDate(), each.duration, each.resource));
.distributeForDay(day, effort)) {
result.add(GenericDayAssignment.create(day.getDate(),
each.duration, each.resource));
} }
return result; return result;
} }
@ -237,19 +225,14 @@ public class GenericResourceAllocation extends
} }
private IAssignedEffortForResource assignedEffortForResource = null; public void setAssignedEffortForResource(IAssignedEffortForResource assignedEffortForResource) {
public void setAssignedEffortForResource(
IAssignedEffortForResource assignedEffortForResource) {
this.assignedEffortForResource = assignedEffortForResource; this.assignedEffortForResource = assignedEffortForResource;
} }
private IAssignedEffortForResource getAssignedEffortForResource() { private IAssignedEffortForResource getAssignedEffortForResource() {
if (assignedEffortForResource != null) { return assignedEffortForResource != null
return assignedEffortForResource; ? assignedEffortForResource
} : AssignedEffortForResource.effortDiscounting(Collections.singletonList(this));
return AssignedEffortForResource.effortDiscounting(Collections
.singletonList(this));
} }
@Override @Override
@ -258,7 +241,7 @@ public class GenericResourceAllocation extends
} }
public IAllocatable forResources(Collection<? extends Resource> resources) { public IAllocatable forResources(Collection<? extends Resource> resources) {
return new GenericAllocation(new ArrayList<Resource>(resources)); return new GenericAllocation(new ArrayList<>(resources));
} }
@Override @Override
@ -273,8 +256,7 @@ public class GenericResourceAllocation extends
@Override @Override
public List<Resource> getAssociatedResources() { public List<Resource> getAssociatedResources() {
return new ArrayList<Resource>(DayAssignment return new ArrayList<>(DayAssignment.getAllResources(getAssignments()));
.getAllResources(getAssignments()));
} }
@Override @Override
@ -285,34 +267,32 @@ public class GenericResourceAllocation extends
@Override @Override
ResourceAllocation<GenericDayAssignment> createCopy(Scenario scenario) { ResourceAllocation<GenericDayAssignment> createCopy(Scenario scenario) {
GenericResourceAllocation allocation = create(); GenericResourceAllocation allocation = create();
allocation.criterions = new HashSet<Criterion>(criterions); allocation.criterions = new HashSet<>(criterions);
return allocation; return allocation;
} }
@Override @Override
public ResourcesPerDayModification withDesiredResourcesPerDay( public ResourcesPerDayModification withDesiredResourcesPerDay(ResourcesPerDay resourcesPerDay) {
ResourcesPerDay resourcesPerDay) { return ResourcesPerDayModification.create(this, resourcesPerDay, getAssociatedResources());
return ResourcesPerDayModification.create(this, resourcesPerDay,
getAssociatedResources());
} }
@Override @Override
public List<Resource> querySuitableResources( public List<Resource> querySuitableResources(IResourcesSearcher resourcesSearcher) {
IResourcesSearcher resourcesSearcher) { return resourcesSearcher.searchBoth().byCriteria(getCriterions()).execute();
return resourcesSearcher.searchBoth().byCriteria(getCriterions())
.execute();
} }
public static Map<Criterion, List<GenericResourceAllocation>> byCriterion( public static Map<Criterion, List<GenericResourceAllocation>> byCriterion(
List<GenericResourceAllocation> generics) { List<GenericResourceAllocation> generics) {
Map<Criterion, List<GenericResourceAllocation>> result = new HashMap<Criterion, List<GenericResourceAllocation>>();
Map<Criterion, List<GenericResourceAllocation>> result = new HashMap<>();
for (GenericResourceAllocation genericResourceAllocation : generics) { for (GenericResourceAllocation genericResourceAllocation : generics) {
Set<Criterion> criterions = genericResourceAllocation Set<Criterion> criterions = genericResourceAllocation.getCriterions();
.getCriterions();
for (Criterion criterion : criterions) { for (Criterion criterion : criterions) {
if (!result.containsKey(criterion)) { if (!result.containsKey(criterion)) {
result.put(criterion, result.put(criterion, new ArrayList<>());
new ArrayList<GenericResourceAllocation>());
} }
result.get(criterion).add(genericResourceAllocation); result.get(criterion).add(genericResourceAllocation);
} }
@ -347,20 +327,16 @@ public class GenericResourceAllocation extends
@Override @Override
protected void removeContainersFor(Scenario scenario) { protected void removeContainersFor(Scenario scenario) {
GenericDayAssignmentsContainer container = containersByScenario().get( GenericDayAssignmentsContainer container = containersByScenario().get(scenario);
scenario);
if (container != null) { if (container != null) {
genericDayAssignmentsContainers.remove(container); genericDayAssignmentsContainers.remove(container);
} }
} }
public void overrideConsolidatedDayAssignments( public void overrideConsolidatedDayAssignments(GenericResourceAllocation origin) {
GenericResourceAllocation origin) {
if (origin != null) { if (origin != null) {
List<GenericDayAssignment> originAssignments = origin List<GenericDayAssignment> originAssignments = origin.getConsolidatedAssignments();
.getConsolidatedAssignments(); resetAssignmentsTo(GenericDayAssignment.copyToAssignmentsWithoutParent(originAssignments));
resetAssignmentsTo(GenericDayAssignment
.copyToAssignmentsWithoutParent(originAssignments));
} }
} }
@ -369,13 +345,13 @@ public class GenericResourceAllocation extends
} }
@Override @Override
public EffortDuration getAssignedEffort(Criterion criterion, public EffortDuration getAssignedEffort(
IntraDayDate startInclusive, IntraDayDate endExclusive) { Criterion criterion, IntraDayDate startInclusive, IntraDayDate endExclusive) {
return super.getAssignedDuration(startInclusive, endExclusive); return super.getAssignedDuration(startInclusive, endExclusive);
} }
public IEffortDistributor<GenericDayAssignment> createEffortDistributor( public IEffortDistributor<GenericDayAssignment> createEffortDistributor(List<Resource> resources) {
List<Resource> resources) {
return new GenericAllocation(resources); return new GenericAllocation(resources);
} }

View file

@ -49,7 +49,7 @@ import org.springframework.stereotype.Component;
* Cost calulator in terms of hours. * Cost calulator in terms of hours.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
@Component @Component
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
@ -153,7 +153,7 @@ public class HoursCostCalculator implements ICostCalculator {
assert date != null; assert date != null;
LocalTime time = new LocalTime(date.getTime()); LocalTime time = new LocalTime(date.getTime());
// Time time = new Time(date.getTime()); // Time time = new Time(date.getTime());
BigDecimal hours = new BigDecimal(time.getHourOfDay()); BigDecimal hours = new BigDecimal(time.getHourOfDay());
additionOfAllAssignmentsMinutes += time.getMinuteOfHour(); additionOfAllAssignmentsMinutes += time.getMinuteOfHour();

View file

@ -22,7 +22,6 @@
package org.libreplan.business.planner.entities; package org.libreplan.business.planner.entities;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -58,21 +57,28 @@ import org.libreplan.business.workingday.ResourcesPerDay;
/** /**
* Represents the relation between {@link Task} and a specific {@link Worker}. * Represents the relation between {@link Task} and a specific {@link Worker}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAssignment> implements IAllocatable { public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAssignment> implements IAllocatable {
@OnCopy(Strategy.SHARE)
private Resource resource;
private Set<SpecificDayAssignmentsContainer> specificDayAssignmentsContainers = new HashSet<>();
public SpecificResourceAllocation() {}
public static SpecificResourceAllocation create(Task task) { public static SpecificResourceAllocation create(Task task) {
return create(new SpecificResourceAllocation(task)); return create(new SpecificResourceAllocation(task));
} }
/** /**
* Creates a {@link SpecificResourceAllocation} for a * Creates a {@link SpecificResourceAllocation} for a {@link LimitingResourceQueueElement}.
* {@link LimitingResourceQueueElement}
* *
* The process of creating a specific resource allocation for a queue * The process of creating a specific resource allocation for a queue
* element is different as it's necessary to assign a resource and a number * element is different as it's necessary to assign a resource and a number
* of resources per day without allocating day assignments * of resources per day without allocating day assignments.
* *
* @param resource * @param resource
* @param task * @param task
@ -83,26 +89,19 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
SpecificResourceAllocation result = create(new SpecificResourceAllocation(task)); SpecificResourceAllocation result = create(new SpecificResourceAllocation(task));
result.setResource(resource); result.setResource(resource);
result.setResourcesPerDayToAmount(1); result.setResourcesPerDayToAmount(1);
return result; return result;
} }
@OnCopy(Strategy.SHARE)
private Resource resource;
private Set<SpecificDayAssignmentsContainer> specificDayAssignmentsContainers = new HashSet<SpecificDayAssignmentsContainer>();
@Valid @Valid
public Set<SpecificDayAssignmentsContainer> getSpecificDayAssignmentsContainers() { public Set<SpecificDayAssignmentsContainer> getSpecificDayAssignmentsContainers() {
return new HashSet<SpecificDayAssignmentsContainer>(specificDayAssignmentsContainers); return new HashSet<>(specificDayAssignmentsContainers);
} }
public static SpecificResourceAllocation createForTesting(ResourcesPerDay resourcesPerDay, Task task) { public static SpecificResourceAllocation createForTesting(ResourcesPerDay resourcesPerDay, Task task) {
return create(new SpecificResourceAllocation(resourcesPerDay, task)); return create(new SpecificResourceAllocation(resourcesPerDay, task));
} }
public SpecificResourceAllocation() {
}
@Override @Override
protected SpecificDayAssignmentsContainer retrieveOrCreateContainerFor(Scenario scenario) { protected SpecificDayAssignmentsContainer retrieveOrCreateContainerFor(Scenario scenario) {
SpecificDayAssignmentsContainer retrieved = retrieveContainerFor(scenario); SpecificDayAssignmentsContainer retrieved = retrieveContainerFor(scenario);
@ -111,13 +110,13 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
} }
SpecificDayAssignmentsContainer result = SpecificDayAssignmentsContainer.create(this, scenario); SpecificDayAssignmentsContainer result = SpecificDayAssignmentsContainer.create(this, scenario);
specificDayAssignmentsContainers.add(result); specificDayAssignmentsContainers.add(result);
return result; return result;
} }
@Override @Override
protected SpecificDayAssignmentsContainer retrieveContainerFor(Scenario scenario) { protected SpecificDayAssignmentsContainer retrieveContainerFor(Scenario scenario) {
Map<Scenario, SpecificDayAssignmentsContainer> containers = containersByScenario(); return containersByScenario().get(scenario);
return containers.get(scenario);
} }
private SpecificResourceAllocation(ResourcesPerDay resourcesPerDay, Task task) { private SpecificResourceAllocation(ResourcesPerDay resourcesPerDay, Task task) {
@ -134,7 +133,7 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
} }
private Map<Scenario, SpecificDayAssignmentsContainer> containersByScenario() { private Map<Scenario, SpecificDayAssignmentsContainer> containersByScenario() {
Map<Scenario, SpecificDayAssignmentsContainer> result = new HashMap<Scenario, SpecificDayAssignmentsContainer>(); Map<Scenario, SpecificDayAssignmentsContainer> result = new HashMap<>();
for (SpecificDayAssignmentsContainer each : specificDayAssignmentsContainers) { for (SpecificDayAssignmentsContainer each : specificDayAssignmentsContainers) {
assert !result.containsKey(each); assert !result.containsKey(each);
result.put(each.getScenario(), each); result.put(each.getScenario(), each);
@ -160,8 +159,7 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
@Override @Override
public IAllocateResourcesPerDay resourcesPerDayFromEndUntil(IntraDayDate start) { public IAllocateResourcesPerDay resourcesPerDayFromEndUntil(IntraDayDate start) {
SpecificAssignmentsAllocator allocator = new SpecificAssignmentsAllocator(); return new SpecificAssignmentsAllocator().resourcesPerDayFromEndUntil(start);
return allocator.resourcesPerDayFromEndUntil(start);
} }
@Override @Override
@ -174,12 +172,11 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
return new SpecificAssignmentsAllocator().fromEndUntil(start); return new SpecificAssignmentsAllocator().fromEndUntil(start);
} }
private final class SpecificAssignmentsAllocator extends private final class SpecificAssignmentsAllocator extends AssignmentsAllocator {
AssignmentsAllocator {
@Override @Override
public List<SpecificDayAssignment> distributeForDay(PartialDay day, EffortDuration effort) { public List<SpecificDayAssignment> distributeForDay(PartialDay day, EffortDuration effort) {
return Arrays.asList(SpecificDayAssignment.create(day.getDate(), effort, resource)); return Collections.singletonList(SpecificDayAssignment.create(day.getDate(), effort, resource));
} }
@Override @Override
@ -189,8 +186,7 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
@Override @Override
protected Capacity getCapacityAt(PartialDay day) { protected Capacity getCapacityAt(PartialDay day) {
return day.limitCapacity(getAllocationCalendar() return day.limitCapacity(getAllocationCalendar().getCapacityWithOvertime(day.getDate()));
.getCapacityWithOvertime(day.getDate()));
} }
} }
@ -236,25 +232,24 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
@Override @Override
public List<Resource> getAssociatedResources() { public List<Resource> getAssociatedResources() {
return Arrays.asList(resource); return Collections.singletonList(resource);
} }
@Override @Override
ResourceAllocation<SpecificDayAssignment> createCopy(Scenario scenario) { ResourceAllocation<SpecificDayAssignment> createCopy(Scenario scenario) {
SpecificResourceAllocation result = create(getTask()); SpecificResourceAllocation result = create(getTask());
result.resource = getResource(); result.resource = getResource();
return result; return result;
} }
@Override @Override
public ResourcesPerDayModification withDesiredResourcesPerDay( public ResourcesPerDayModification withDesiredResourcesPerDay(ResourcesPerDay resourcesPerDay) {
ResourcesPerDay resourcesPerDay) {
return ResourcesPerDayModification.create(this, resourcesPerDay); return ResourcesPerDayModification.create(this, resourcesPerDay);
} }
@Override @Override
public List<Resource> querySuitableResources( public List<Resource> querySuitableResources(IResourcesSearcher resourcesSearcher) {
IResourcesSearcher resourcesSearcher) {
return Collections.singletonList(resource); return Collections.singletonList(resource);
} }
@ -290,8 +285,7 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
@Override @Override
protected void removeContainersFor(Scenario scenario) { protected void removeContainersFor(Scenario scenario) {
SpecificDayAssignmentsContainer container = containersByScenario().get( SpecificDayAssignmentsContainer container = containersByScenario().get(scenario);
scenario);
if (container != null) { if (container != null) {
specificDayAssignmentsContainers.remove(container); specificDayAssignmentsContainers.remove(container);
} }
@ -299,8 +293,8 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
/** /**
* It does an allocation using the provided {@link EffortDuration} in the * It does an allocation using the provided {@link EffortDuration} in the
* not consolidated part in interval from the first day not consolidated to * not consolidated part in interval from the first day not consolidated to the end provided.
* the end provided. All previous not consolidated assignments are removed. * All previous not consolidated assignments are removed.
* *
* @param effortForNotConsolidatedPart * @param effortForNotConsolidatedPart
* @param endExclusive * @param endExclusive
@ -329,7 +323,7 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
private List<SpecificDayAssignment> assignmentsForEfforts(List<DayAssignment> assignments, private List<SpecificDayAssignment> assignmentsForEfforts(List<DayAssignment> assignments,
EffortDuration[] newEffortsPerDay) { EffortDuration[] newEffortsPerDay) {
List<SpecificDayAssignment> result = new ArrayList<SpecificDayAssignment>(); List<SpecificDayAssignment> result = new ArrayList<>();
int i = 0; int i = 0;
for (DayAssignment each : assignments) { for (DayAssignment each : assignments) {
EffortDuration durationForAssignment = newEffortsPerDay[i++]; EffortDuration durationForAssignment = newEffortsPerDay[i++];
@ -356,12 +350,13 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
} }
@Override @Override
public EffortDuration getAssignedEffort(Criterion criterion, final IntraDayDate startInclusive, public EffortDuration getAssignedEffort(Criterion criterion,
final IntraDayDate startInclusive,
final IntraDayDate endExclusive) { final IntraDayDate endExclusive) {
return EffortDuration.sum(getIntervalsRelatedWith(criterion, startInclusive.getDate(), return EffortDuration.sum(
endExclusive.asExclusiveEnd()), new IEffortFrom<Interval>() { getIntervalsRelatedWith(criterion, startInclusive.getDate(), endExclusive.asExclusiveEnd()),
new IEffortFrom<Interval>() {
@Override @Override
public EffortDuration from(Interval each) { public EffortDuration from(Interval each) {
FixedPoint intervalStart = (FixedPoint) each.getStart(); FixedPoint intervalStart = (FixedPoint) each.getStart();
@ -374,12 +369,13 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
}); });
} }
private List<Interval> getIntervalsRelatedWith(Criterion criterion, LocalDate startInclusive, private List<Interval> getIntervalsRelatedWith(Criterion criterion,
LocalDate startInclusive,
LocalDate endExclusive) { LocalDate endExclusive) {
Interval queryInterval = AvailabilityTimeLine.Interval.create(startInclusive, endExclusive); Interval queryInterval = AvailabilityTimeLine.Interval.create(startInclusive, endExclusive);
List<Interval> result = new ArrayList<Interval>(); List<Interval> result = new ArrayList<>();
for (Interval each : getIntervalsThisAllocationInterferesWith(criterion)) { for (Interval each : getIntervalsThisAllocationInterferesWith(criterion)) {
if ( queryInterval.overlaps(each) ) { if ( queryInterval.overlaps(each) ) {
@ -390,17 +386,18 @@ public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAs
} }
private List<Interval> getIntervalsThisAllocationInterferesWith(Criterion criterion) { private List<Interval> getIntervalsThisAllocationInterferesWith(Criterion criterion) {
AvailabilityTimeLine availability = AvailabilityTimeLine availability =
AvailabilityCalculator.getCriterionsAvailabilityFor(Collections.singleton(criterion), resource); AvailabilityCalculator.getCriterionsAvailabilityFor(Collections.singleton(criterion), resource);
availability.invalidUntil(getStartDate()); availability.invalidUntil(getStartDate());
availability.invalidFrom(getEndDate()); availability.invalidFrom(getEndDate());
return availability.getValidPeriods(); return availability.getValidPeriods();
} }
public boolean interferesWith(Criterion criterion, LocalDate startInclusive, LocalDate endExclusive) { public boolean interferesWith(Criterion criterion, LocalDate startInclusive, LocalDate endExclusive) {
List<Interval> intervalsRelatedWith = getIntervalsRelatedWith(criterion, startInclusive, endExclusive); return !getIntervalsRelatedWith(criterion, startInclusive, endExclusive).isEmpty();
return !intervalsRelatedWith.isEmpty();
} }

View file

@ -397,11 +397,9 @@ public class StretchesFunction extends AssignmentFunction {
@Override @Override
public String getName() { public String getName() {
if ( StretchesFunctionTypeEnum.INTERPOLATED.equals(type) ) { return StretchesFunctionTypeEnum.INTERPOLATED.equals(type)
return AssignmentFunctionName.INTERPOLATION.toString(); ? AssignmentFunctionName.INTERPOLATION.toString()
} else { : AssignmentFunctionName.STRETCHES.toString();
return AssignmentFunctionName.STRETCHES.toString();
}
} }
public List<Interval> getIntervalsDefinedByStreches() { public List<Interval> getIntervalsDefinedByStreches() {
@ -415,9 +413,9 @@ public class StretchesFunction extends AssignmentFunction {
} }
private List<Stretch> stretchesFor() { private List<Stretch> stretchesFor() {
boolean condition = (getDesiredType().equals(StretchesFunctionTypeEnum.INTERPOLATED)); return getDesiredType().equals(StretchesFunctionTypeEnum.INTERPOLATED)
? getStretchesPlusConsolidated()
return condition ? getStretchesPlusConsolidated() : getStretches(); : getStretches();
} }
private void checkStretchesSumOneHundredPercent() { private void checkStretchesSumOneHundredPercent() {

View file

@ -45,6 +45,46 @@ import org.libreplan.business.util.deepcopy.Strategy;
*/ */
public class SubcontractedTaskData extends BaseEntity { public class SubcontractedTaskData extends BaseEntity {
private Task task;
@OnCopy(Strategy.SHARE)
private ExternalCompany externalCompany;
private Date subcontratationDate;
private Date subcontractCommunicationDate;
private String workDescription;
private BigDecimal subcontractPrice;
private String subcontractedCode;
private Boolean nodeWithoutChildrenExported;
private Boolean labelsExported;
private Boolean materialAssignmentsExported;
private Boolean hoursGroupsExported;
private SubcontractState state = SubcontractState.PENDING_INITIAL_SEND;
private final SortedSet<SubcontractorDeliverDate> requiredDeliveringDates =
new TreeSet<>(new DeliverDateComparator());
private SortedSet<EndDateCommunication> endDatesCommunicatedFromSubcontractor =
new TreeSet<>(new EndDateCommunicationComparator());
/**
* Constructor for hibernate. Do not use!
*/
public SubcontractedTaskData() {}
private SubcontractedTaskData(Task task) {
this.task = task;
}
public static SubcontractedTaskData create(Task task) { public static SubcontractedTaskData create(Task task) {
SubcontractedTaskData subcontractedTaskData = new SubcontractedTaskData(task); SubcontractedTaskData subcontractedTaskData = new SubcontractedTaskData(task);
subcontractedTaskData.subcontratationDate = new Date(); subcontractedTaskData.subcontratationDate = new Date();
@ -78,44 +118,6 @@ public class SubcontractedTaskData extends BaseEntity {
return create(result); return create(result);
} }
private Task task;
@OnCopy(Strategy.SHARE)
private ExternalCompany externalCompany;
private Date subcontratationDate;
private Date subcontractCommunicationDate;
private String workDescription;
private BigDecimal subcontractPrice;
private String subcontractedCode;
private Boolean nodeWithoutChildrenExported;
private Boolean labelsExported;
private Boolean materialAssignmentsExported;
private Boolean hoursGroupsExported;
private SubcontractState state = SubcontractState.PENDING_INITIAL_SEND;
private final SortedSet<SubcontractorDeliverDate> requiredDeliveringDates =
new TreeSet<>(new DeliverDateComparator());
private SortedSet<EndDateCommunication> endDatesCommunicatedFromSubcontractor =
new TreeSet<>(new EndDateCommunicationComparator());
/**
* Constructor for hibernate. Do not use!
*/
public SubcontractedTaskData() {
}
private SubcontractedTaskData(Task task) {
this.task = task;
}
@NotNull(message = "task not specified") @NotNull(message = "task not specified")
public Task getTask() { public Task getTask() {
return task; return task;
@ -163,11 +165,7 @@ public class SubcontractedTaskData extends BaseEntity {
} }
public boolean isNodeWithoutChildrenExported() { public boolean isNodeWithoutChildrenExported() {
if ( nodeWithoutChildrenExported == null ) { return nodeWithoutChildrenExported == null ? false : nodeWithoutChildrenExported;
return false;
}
return nodeWithoutChildrenExported;
} }
public void setNodeWithoutChildrenExported(Boolean nodeWithoutChildrenExported) { public void setNodeWithoutChildrenExported(Boolean nodeWithoutChildrenExported) {
@ -178,11 +176,7 @@ public class SubcontractedTaskData extends BaseEntity {
} }
public boolean isLabelsExported() { public boolean isLabelsExported() {
if ( labelsExported == null ) { return labelsExported == null ? false : labelsExported;
return false;
}
return labelsExported;
} }
public void setLabelsExported(Boolean labelsExported) { public void setLabelsExported(Boolean labelsExported) {
@ -193,11 +187,7 @@ public class SubcontractedTaskData extends BaseEntity {
} }
public Boolean isMaterialAssignmentsExported() { public Boolean isMaterialAssignmentsExported() {
if ( materialAssignmentsExported == null ) { return materialAssignmentsExported == null ? false : materialAssignmentsExported;
return false;
}
return materialAssignmentsExported;
} }
public void setMaterialAssignmentsExported(Boolean materialAssignmentsExported) { public void setMaterialAssignmentsExported(Boolean materialAssignmentsExported) {
@ -208,11 +198,7 @@ public class SubcontractedTaskData extends BaseEntity {
} }
public Boolean isHoursGroupsExported() { public Boolean isHoursGroupsExported() {
if ( hoursGroupsExported == null ) { return hoursGroupsExported == null ? false : hoursGroupsExported;
return false;
}
return hoursGroupsExported;
} }
public void setHoursGroupsExported(Boolean hoursGroupsExported) { public void setHoursGroupsExported(Boolean hoursGroupsExported) {
@ -246,7 +232,6 @@ public class SubcontractedTaskData extends BaseEntity {
@AssertTrue(message = "external company should be subcontractor") @AssertTrue(message = "external company should be subcontractor")
public boolean isExternalCompanyIsSubcontractorConstraint() { public boolean isExternalCompanyIsSubcontractorConstraint() {
return !firstLevelValidationsPassed() || externalCompany.isSubcontractor(); return !firstLevelValidationsPassed() || externalCompany.isSubcontractor();
} }
private boolean firstLevelValidationsPassed() { private boolean firstLevelValidationsPassed() {
@ -291,11 +276,9 @@ public class SubcontractedTaskData extends BaseEntity {
} }
public Date getLastRequiredDeliverDate() { public Date getLastRequiredDeliverDate() {
if ( this.requiredDeliveringDates != null && !this.requiredDeliveringDates.isEmpty() ) { return this.requiredDeliveringDates != null && !this.requiredDeliveringDates.isEmpty()
return this.requiredDeliveringDates.first().getSubcontractorDeliverDate(); ? this.requiredDeliveringDates.first().getSubcontractorDeliverDate()
} : null;
return null;
} }
public void setEndDatesCommunicatedFromSubcontractor( public void setEndDatesCommunicatedFromSubcontractor(
@ -309,10 +292,8 @@ public class SubcontractedTaskData extends BaseEntity {
} }
public EndDateCommunication getLastEndDatesCommunicatedFromSubcontractor() { public EndDateCommunication getLastEndDatesCommunicatedFromSubcontractor() {
if ( getEndDatesCommunicatedFromSubcontractor() != null ) { return getEndDatesCommunicatedFromSubcontractor() != null
return getEndDatesCommunicatedFromSubcontractor().first(); ? getEndDatesCommunicatedFromSubcontractor().first()
} : null;
return null;
} }
} }

View file

@ -44,10 +44,10 @@ public class SubcontractorCommunication extends BaseEntity {
private List<SubcontractorCommunicationValue> subcontractorCommunicationValues = new ArrayList<>(); private List<SubcontractorCommunicationValue> subcontractorCommunicationValues = new ArrayList<>();
// Default constructor, needed by Hibernate /**
protected SubcontractorCommunication() { * Default constructor, needed by Hibernate.
*/
} protected SubcontractorCommunication() {}
private SubcontractorCommunication(SubcontractedTaskData subcontractedTaskData, private SubcontractorCommunication(SubcontractedTaskData subcontractedTaskData,
CommunicationType communicationType, CommunicationType communicationType,
@ -116,17 +116,14 @@ public class SubcontractorCommunication extends BaseEntity {
return subcontractorCommunicationValues; return subcontractorCommunicationValues;
} }
public SubcontractorCommunicationValue getLastSubcontractorCommunicationValues(){ public SubcontractorCommunicationValue getLastSubcontractorCommunicationValues() {
if ( subcontractorCommunicationValues.isEmpty() ){ return subcontractorCommunicationValues.isEmpty()
return null; ? null
} : subcontractorCommunicationValues.get(subcontractorCommunicationValues.size() - 1);
return subcontractorCommunicationValues.get(subcontractorCommunicationValues.size()-1);
} }
public Date getLastSubcontractorCommunicationValueDate(){ public Date getLastSubcontractorCommunicationValueDate(){
SubcontractorCommunicationValue value = getLastSubcontractorCommunicationValues(); SubcontractorCommunicationValue value = getLastSubcontractorCommunicationValues();
return (value == null) ? null : value.getDate(); return (value == null) ? null : value.getDate();
} }
} }

View file

@ -32,34 +32,34 @@ import org.libreplan.business.INewObject;
*/ */
public class SubcontractorCommunicationValue implements INewObject { public class SubcontractorCommunicationValue implements INewObject {
public static SubcontractorCommunicationValue create() { private boolean newObject = false;
SubcontractorCommunicationValue subcontractorCommunicationValue = new SubcontractorCommunicationValue();
subcontractorCommunicationValue.setNewObject(true);
return subcontractorCommunicationValue;
}
public static SubcontractorCommunicationValue create(Date date, private Date date;
BigDecimal progress) {
SubcontractorCommunicationValue subcontractorCommunicationValue = new SubcontractorCommunicationValue(
date, progress);
subcontractorCommunicationValue.setNewObject(true);
return subcontractorCommunicationValue;
}
protected SubcontractorCommunicationValue() { private BigDecimal progress;
} protected SubcontractorCommunicationValue() {}
private SubcontractorCommunicationValue(Date date, BigDecimal progress) { private SubcontractorCommunicationValue(Date date, BigDecimal progress) {
this.setDate(date); this.setDate(date);
this.setProgress(progress); this.setProgress(progress);
} }
private boolean newObject = false; public static SubcontractorCommunicationValue create() {
SubcontractorCommunicationValue subcontractorCommunicationValue = new SubcontractorCommunicationValue();
subcontractorCommunicationValue.setNewObject(true);
private Date date; return subcontractorCommunicationValue;
}
private BigDecimal progress; public static SubcontractorCommunicationValue create(Date date, BigDecimal progress) {
SubcontractorCommunicationValue subcontractorCommunicationValue =
new SubcontractorCommunicationValue(date, progress);
subcontractorCommunicationValue.setNewObject(true);
return subcontractorCommunicationValue;
}
public boolean isNewObject() { public boolean isNewObject() {
return newObject; return newObject;
@ -72,11 +72,9 @@ public class SubcontractorCommunicationValue implements INewObject {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@AssertTrue(message = "progress should be greater than 0% and less than 100%") @AssertTrue(message = "progress should be greater than 0% and less than 100%")
public boolean isQualityFormItemPercentageConstraint() { public boolean isQualityFormItemPercentageConstraint() {
if (getProgress() == null) { return getProgress() == null ||
return true; (getProgress().compareTo(new BigDecimal(100).setScale(2)) <= 0 &&
} (getProgress().compareTo(new BigDecimal(0).setScale(2)) > 0));
return ((getProgress().compareTo(new BigDecimal(100).setScale(2)) <= 0) && (getProgress()
.compareTo(new BigDecimal(0).setScale(2)) > 0));
} }
public void setDate(Date date) { public void setDate(Date date) {
@ -97,8 +95,6 @@ public class SubcontractorCommunicationValue implements INewObject {
@Override @Override
public String toString() { public String toString() {
String progress_reported = progress != null ? progress.toString() return progress != null ? progress.toString() + "% - " + date : date.toString();
+ "% - " : "";
return progress_reported + date;
} }
} }

View file

@ -70,6 +70,46 @@ public abstract class TaskElement extends BaseEntity {
private static final Log LOG = LogFactory.getLog(TaskElement.class); private static final Log LOG = LogFactory.getLog(TaskElement.class);
private static final IDatesInterceptor EMPTY_INTERCEPTOR = new IDatesInterceptor() {
@Override
public void setStartDate(IntraDayDate previousStart, IntraDayDate previousEnd, IntraDayDate newStart) {}
@Override
public void setNewEnd(IntraDayDate previousEnd, IntraDayDate newEnd) {}
};
@OnCopy(Strategy.SHARE)
private IDatesInterceptor datesInterceptor = EMPTY_INTERCEPTOR;
@OnCopy(Strategy.SHARE)
private BaseCalendar calendar;
private IntraDayDate startDate;
private IntraDayDate endDate;
private LocalDate deadline;
private String name;
private String notes;
private BigDecimal advancePercentage = BigDecimal.ZERO;
private Boolean simplifiedAssignedStatusCalculationEnabled = false;
private Boolean updatedFromTimesheets = false;
private EffortDuration sumOfAssignedEffort = EffortDuration.zero();
private TaskGroup parent;
private Set<Dependency> dependenciesWithThisOrigin = new HashSet<>();
private Set<Dependency> dependenciesWithThisDestination = new HashSet<>();
private TaskSource taskSource;
public static List<Task> justTasks(Collection<? extends TaskElement> tasks) { public static List<Task> justTasks(Collection<? extends TaskElement> tasks) {
List<Task> result = new ArrayList<>(); List<Task> result = new ArrayList<>();
for (TaskElement taskElement : tasks) { for (TaskElement taskElement : tasks) {
@ -82,27 +122,14 @@ public abstract class TaskElement extends BaseEntity {
} }
public interface IDatesInterceptor { public interface IDatesInterceptor {
void setStartDate(IntraDayDate previousStart,
IntraDayDate previousEnd, IntraDayDate newStart); void setStartDate(IntraDayDate previousStart, IntraDayDate previousEnd, IntraDayDate newStart);
void setNewEnd(IntraDayDate previousEnd, IntraDayDate newEnd); void setNewEnd(IntraDayDate previousEnd, IntraDayDate newEnd);
} }
private static final IDatesInterceptor EMPTY_INTERCEPTOR = new IDatesInterceptor() {
@Override
public void setStartDate(IntraDayDate previousStart, IntraDayDate previousEnd, IntraDayDate newStart) {
}
@Override
public void setNewEnd(IntraDayDate previousEnd, IntraDayDate newEnd) {
}
};
public static Comparator<TaskElement> getByStartDateComparator() { public static Comparator<TaskElement> getByStartDateComparator() {
Comparator<TaskElement> result = new Comparator<TaskElement>() { Comparator<TaskElement> result = new Comparator<TaskElement>() {
@Override @Override
public int compare(TaskElement o1, TaskElement o2) { public int compare(TaskElement o1, TaskElement o2) {
return o1.getStartDate().compareTo(o2.getStartDate()); return o1.getStartDate().compareTo(o2.getStartDate());
@ -114,13 +141,10 @@ public abstract class TaskElement extends BaseEntity {
public static Comparator<? super TaskElement> getByEndAndDeadlineDateComparator() { public static Comparator<? super TaskElement> getByEndAndDeadlineDateComparator() {
return new Comparator<TaskElement>() { return new Comparator<TaskElement>() {
@Override @Override
public int compare(TaskElement o1, TaskElement o2) { public int compare(TaskElement o1, TaskElement o2) {
return o1.getBiggestAmongEndOrDeadline().compareTo( return o1.getBiggestAmongEndOrDeadline().compareTo(o2.getBiggestAmongEndOrDeadline());
o2.getBiggestAmongEndOrDeadline());
} }
}; };
} }
@ -129,11 +153,9 @@ public abstract class TaskElement extends BaseEntity {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public LocalDate getBiggestAmongEndOrDeadline() { public LocalDate getBiggestAmongEndOrDeadline() {
if ( this.getDeadline() != null ) { return this.getDeadline() != null
return Collections.max(asList(this.getDeadline(), this.getEndAsLocalDate())); ? Collections.max(asList(this.getDeadline(), this.getEndAsLocalDate()))
} : this.getEndAsLocalDate();
return this.getEndAsLocalDate();
} }
protected static <T extends TaskElement> T create(T taskElement, TaskSource taskSource) { protected static <T extends TaskElement> T create(T taskElement, TaskSource taskSource) {
@ -142,6 +164,7 @@ public abstract class TaskElement extends BaseEntity {
taskElement.setName(taskElement.getOrderElement().getName()); taskElement.setName(taskElement.getOrderElement().getName());
taskElement.updateAdvancePercentageFromOrderElement(); taskElement.updateAdvancePercentageFromOrderElement();
Order order = taskElement.getOrderElement().getOrder(); Order order = taskElement.getOrderElement().getOrder();
if ( order.isScheduleBackwards() ) { if ( order.isScheduleBackwards() ) {
taskElement.setEndDate(order.getDeadline()); taskElement.setEndDate(order.getDeadline());
} else { } else {
@ -154,36 +177,6 @@ public abstract class TaskElement extends BaseEntity {
return create(taskElement); return create(taskElement);
} }
@OnCopy(Strategy.SHARE)
private IDatesInterceptor datesInterceptor = EMPTY_INTERCEPTOR;
private IntraDayDate startDate;
private IntraDayDate endDate;
private LocalDate deadline;
private String name;
private String notes;
private TaskGroup parent;
private Set<Dependency> dependenciesWithThisOrigin = new HashSet<Dependency>();
private Set<Dependency> dependenciesWithThisDestination = new HashSet<Dependency>();
@OnCopy(Strategy.SHARE)
private BaseCalendar calendar;
private TaskSource taskSource;
private BigDecimal advancePercentage = BigDecimal.ZERO;
private Boolean simplifiedAssignedStatusCalculationEnabled = false;
private Boolean updatedFromTimesheets = false;
public void initializeDatesIfNeeded() { public void initializeDatesIfNeeded() {
if ( getIntraDayEndDate() == null || getIntraDayStartDate() == null ) { if ( getIntraDayEndDate() == null || getIntraDayStartDate() == null ) {
initializeDates(); initializeDates();
@ -203,11 +196,7 @@ public abstract class TaskElement extends BaseEntity {
} }
public Integer getWorkHours() { public Integer getWorkHours() {
if ( taskSource == null ) { return taskSource == null ? 0 : taskSource.getTotalHours();
return 0;
}
return taskSource.getTotalHours();
} }
protected void copyPropertiesFrom(TaskElement task) { protected void copyPropertiesFrom(TaskElement task) {
@ -227,12 +216,11 @@ public abstract class TaskElement extends BaseEntity {
protected void copyDependenciesTo(TaskElement result) { protected void copyDependenciesTo(TaskElement result) {
for (Dependency dependency : getDependenciesWithThisOrigin()) { for (Dependency dependency : getDependenciesWithThisOrigin()) {
Dependency.create(result, dependency.getDestination(), Dependency.create(result, dependency.getDestination(), dependency.getType());
dependency.getType());
} }
for (Dependency dependency : getDependenciesWithThisDestination()) { for (Dependency dependency : getDependenciesWithThisDestination()) {
Dependency.create(dependency.getOrigin(), result, Dependency.create(dependency.getOrigin(), result, dependency.getType());
dependency.getType());
} }
} }
@ -274,11 +262,7 @@ public abstract class TaskElement extends BaseEntity {
} }
public OrderElement getOrderElement() { public OrderElement getOrderElement() {
if ( getTaskSource() == null ) { return getTaskSource() == null ? null : getTaskSource().getOrderElement();
return null;
}
return getTaskSource().getOrderElement();
} }
public Set<Dependency> getDependenciesWithThisOrigin() { public Set<Dependency> getDependenciesWithThisOrigin() {
@ -290,7 +274,7 @@ public abstract class TaskElement extends BaseEntity {
} }
public Set<Dependency> getDependenciesWithThisDestinationAndAllParents() { public Set<Dependency> getDependenciesWithThisDestinationAndAllParents() {
Set<Dependency> result = new HashSet<Dependency>(getDependenciesWithThisDestination()); Set<Dependency> result = new HashSet<>(getDependenciesWithThisDestination());
if ( parent != null ) { if ( parent != null ) {
result.addAll(parent.getDependenciesWithThisDestinationAndAllParents()); result.addAll(parent.getDependenciesWithThisDestinationAndAllParents());
} }
@ -323,6 +307,7 @@ public abstract class TaskElement extends BaseEntity {
if ( startDate == null ) { if ( startDate == null ) {
LOG.error(doNotProvideNullsDiscouragingMessage()); LOG.error(doNotProvideNullsDiscouragingMessage());
} }
IntraDayDate previousStart = getIntraDayStartDate(); IntraDayDate previousStart = getIntraDayStartDate();
IntraDayDate previousEnd = getIntraDayEndDate(); IntraDayDate previousEnd = getIntraDayEndDate();
this.startDate = startDate; this.startDate = startDate;
@ -335,24 +320,26 @@ public abstract class TaskElement extends BaseEntity {
} }
public void setEndDate(Date endDate) { public void setEndDate(Date endDate) {
setIntraDayEndDate( (endDate != null) ? setIntraDayEndDate( (endDate != null)
IntraDayDate.create(LocalDate.fromDateFields(endDate), EffortDuration.zero()) : null); ? IntraDayDate.create(LocalDate.fromDateFields(endDate), EffortDuration.zero())
: null);
} }
public void setIntraDayEndDate(IntraDayDate endDate) { public void setIntraDayEndDate(IntraDayDate endDate) {
if ( endDate == null ) { if ( endDate == null ) {
LOG.error(doNotProvideNullsDiscouragingMessage()); LOG.error(doNotProvideNullsDiscouragingMessage());
} }
IntraDayDate previousEnd = getIntraDayEndDate(); IntraDayDate previousEnd = getIntraDayEndDate();
this.endDate = endDate; this.endDate = endDate;
datesInterceptor.setNewEnd(previousEnd, this.endDate); datesInterceptor.setNewEnd(previousEnd, this.endDate);
} }
private String doNotProvideNullsDiscouragingMessage() { private String doNotProvideNullsDiscouragingMessage() {
return "The provided date shouldn't be null.\n" return "The provided date shouldn't be null.\n" +
+ "Providing null values to start or end dates is not safe.\n" "Providing null values to start or end dates is not safe.\n" +
+ "In a near future an exception will be thrown if you provide a null value to a start or end date.\n" "In a near future an exception will be thrown if you provide a null value to a start or end date.\n" +
+ "Please detect the caller and fix it"; "Please detect the caller and fix it";
} }
@NotNull @NotNull
@ -360,8 +347,7 @@ public abstract class TaskElement extends BaseEntity {
return endDate; return endDate;
} }
public IDatesHandler getDatesHandler(Scenario scenario, public IDatesHandler getDatesHandler(Scenario scenario, IResourcesSearcher resourcesSearcher) {
IResourcesSearcher resourcesSearcher) {
return noNullDates(createDatesHandler(scenario, resourcesSearcher)); return noNullDates(createDatesHandler(scenario, resourcesSearcher));
} }
@ -388,15 +374,13 @@ public abstract class TaskElement extends BaseEntity {
}; };
} }
protected abstract IDatesHandler createDatesHandler(Scenario scenario, protected abstract IDatesHandler createDatesHandler(Scenario scenario, IResourcesSearcher resourcesSearcher);
IResourcesSearcher resourcesSearcher);
public interface IDatesHandler { public interface IDatesHandler {
/** /**
* Sets the startDate to newStartDate. It can update the endDate * Sets the startDate to newStartDate. It can update the endDate.
* *
* @param scenario
* @param newStartDate * @param newStartDate
*/ */
void moveTo(IntraDayDate newStartDate); void moveTo(IntraDayDate newStartDate);
@ -420,8 +404,10 @@ public abstract class TaskElement extends BaseEntity {
public void setDeadline(LocalDate deadline) { public void setDeadline(LocalDate deadline) {
this.deadline = deadline; this.deadline = deadline;
if ( taskSource != null && taskSource.getOrderElement() != null ) { if ( taskSource != null && taskSource.getOrderElement() != null ) {
taskSource.getOrderElement().setDeadline(
(deadline == null)? null : deadline.toDateTimeAtStartOfDay().toDate()); taskSource.getOrderElement().setDeadline((deadline == null)
? null
: deadline.toDateTimeAtStartOfDay().toDate());
} }
} }
@ -429,6 +415,7 @@ public abstract class TaskElement extends BaseEntity {
if ( this.equals(dependency.getOrigin()) ) { if ( this.equals(dependency.getOrigin()) ) {
dependenciesWithThisOrigin.add(dependency); dependenciesWithThisOrigin.add(dependency);
} }
if ( this.equals(dependency.getDestination()) ) { if ( this.equals(dependency.getDestination()) ) {
dependenciesWithThisDestination.add(dependency); dependenciesWithThisDestination.add(dependency);
} }
@ -445,7 +432,7 @@ public abstract class TaskElement extends BaseEntity {
} }
public void removeDependencyWithDestination(TaskElement destination, Type type) { public void removeDependencyWithDestination(TaskElement destination, Type type) {
ArrayList<Dependency> toBeRemoved = new ArrayList<Dependency>(); ArrayList<Dependency> toBeRemoved = new ArrayList<>();
for (Dependency dependency : dependenciesWithThisOrigin) { for (Dependency dependency : dependenciesWithThisOrigin) {
if ( dependency.getDestination().equals(destination) && dependency.getType().equals(type) ) { if ( dependency.getDestination().equals(destination) && dependency.getType().equals(type) ) {
toBeRemoved.add(dependency); toBeRemoved.add(dependency);
@ -498,7 +485,8 @@ public abstract class TaskElement extends BaseEntity {
private List<Dependency> getDependenciesWithOrigin(TaskElement t) { private List<Dependency> getDependenciesWithOrigin(TaskElement t) {
ArrayList<Dependency> result = new ArrayList<>(); ArrayList<Dependency> result = new ArrayList<>();
for (Dependency dependency : dependenciesWithThisDestination) { for (Dependency dependency : dependenciesWithThisDestination) {
if ( dependency.getOrigin().equals(t) ) {result.add(dependency); if ( dependency.getOrigin().equals(t) ) {
result.add(dependency);
} }
} }
@ -511,7 +499,7 @@ public abstract class TaskElement extends BaseEntity {
} }
private void detachIncomingDependencies() { private void detachIncomingDependencies() {
Set<TaskElement> tasksToNotify = new HashSet<TaskElement>(); Set<TaskElement> tasksToNotify = new HashSet<>();
for (Dependency dependency : dependenciesWithThisDestination) { for (Dependency dependency : dependenciesWithThisDestination) {
TaskElement origin = dependency.getOrigin(); TaskElement origin = dependency.getOrigin();
if ( origin != null ) { if ( origin != null ) {
@ -525,7 +513,7 @@ public abstract class TaskElement extends BaseEntity {
} }
private void detachOutcomingDependencies() { private void detachOutcomingDependencies() {
Set<TaskElement> tasksToNotify = new HashSet<TaskElement>(); Set<TaskElement> tasksToNotify = new HashSet<>();
for (Dependency dependency : dependenciesWithThisOrigin) { for (Dependency dependency : dependenciesWithThisOrigin) {
TaskElement destination = dependency.getDestination(); TaskElement destination = dependency.getDestination();
if ( destination != null ) { if ( destination != null ) {
@ -549,6 +537,7 @@ public abstract class TaskElement extends BaseEntity {
public BaseCalendar getCalendar() { public BaseCalendar getCalendar() {
if ( calendar == null ) { if ( calendar == null ) {
OrderElement orderElement = getOrderElement(); OrderElement orderElement = getOrderElement();
return orderElement != null ? orderElement.getOrder().getCalendar() : null; return orderElement != null ? orderElement.getOrder().getCalendar() : null;
} }
@ -590,8 +579,10 @@ public abstract class TaskElement extends BaseEntity {
return DayAssignment.filter(dayAssignments, filter); return DayAssignment.filter(dayAssignments, filter);
} }
/**
* Just Task could be subcontracted.
*/
public boolean isSubcontracted() { public boolean isSubcontracted() {
// Just Task could be subcontracted
return false; return false;
} }
@ -599,8 +590,10 @@ public abstract class TaskElement extends BaseEntity {
return ""; return "";
} }
/**
* Just Task could be subcontracted.
*/
public boolean isSubcontractedAndWasAlreadySent() { public boolean isSubcontractedAndWasAlreadySent() {
// Just Task could be subcontracted
return false; return false;
} }
@ -612,8 +605,10 @@ public abstract class TaskElement extends BaseEntity {
return false; return false;
} }
/**
* Just Task could be consolidated.
*/
public boolean hasConsolidations() { public boolean hasConsolidations() {
// Just Task could be consolidated
return false; return false;
} }
@ -637,20 +632,19 @@ public abstract class TaskElement extends BaseEntity {
} }
public String getAssignedStatus() { public String getAssignedStatus() {
if(isSimplifiedAssignedStatusCalculationEnabled()) { if (isSimplifiedAssignedStatusCalculationEnabled()) {
//simplified calculation has only two states: // Simplified calculation has only two states:
//unassigned, when hours allocated is zero, and // 1. Unassigned, when hours allocated is zero.
//assigned otherwise // 2. Assigned otherwise.
if ( getSumOfAssignedEffort().isZero() ) {
return "unassigned";
}
return "assigned"; return getSumOfAssignedEffort().isZero() ? "unassigned" : "assigned";
} }
Set<ResourceAllocation<?>> resourceAllocations = getSatisfiedResourceAllocations(); Set<ResourceAllocation<?>> resourceAllocations = getSatisfiedResourceAllocations();
if ( resourceAllocations.isEmpty() ) { if ( resourceAllocations.isEmpty() ) {
return "unassigned"; return "unassigned";
} }
for (ResourceAllocation<?> resourceAllocation : resourceAllocations) { for (ResourceAllocation<?> resourceAllocation : resourceAllocations) {
final ResourcesPerDay resourcesPerDay = resourceAllocation.getResourcesPerDay(); final ResourcesPerDay resourcesPerDay = resourceAllocation.getResourcesPerDay();
if ( resourcesPerDay != null && resourcesPerDay.isZero() ) { if ( resourcesPerDay != null && resourcesPerDay.isZero() ) {
@ -662,16 +656,11 @@ public abstract class TaskElement extends BaseEntity {
} }
public Boolean belongsClosedProject() { public Boolean belongsClosedProject() {
EnumSet<OrderStatusEnum> CLOSED = EnumSet.of(OrderStatusEnum.CANCELLED,
OrderStatusEnum.FINISHED,
OrderStatusEnum.STORED);
Order order = getOrderElement().getOrder(); EnumSet<OrderStatusEnum> CLOSED =
if( CLOSED.contains(order.getState()) ) { EnumSet.of(OrderStatusEnum.CANCELLED, OrderStatusEnum.FINISHED, OrderStatusEnum.STORED);
return true;
}
return false; return CLOSED.contains(getOrderElement().getOrder().getState());
} }
public abstract boolean hasLimitedResourceAllocation(); public abstract boolean hasLimitedResourceAllocation();
@ -695,15 +684,12 @@ public abstract class TaskElement extends BaseEntity {
/** /**
* For common tasks it just return the spread progress. * For common tasks it just return the spread progress.
* *
* It's overridden in {@link TaskGroup} to return different progresses * It's overridden in {@link TaskGroup} to return different progresses depending on parameter.
* depending on parameter
*/ */
public BigDecimal getAdvancePercentage(ProgressType progressType) { public BigDecimal getAdvancePercentage(ProgressType progressType) {
if ( progressType != null && progressType.equals(ProgressType.SPREAD_PROGRESS) ) { return progressType != null && progressType.equals(ProgressType.SPREAD_PROGRESS)
return advancePercentage; ? advancePercentage
} : BigDecimal.ZERO;
return BigDecimal.ZERO;
} }
public void setAdvancePercentage(BigDecimal advancePercentage) { public void setAdvancePercentage(BigDecimal advancePercentage) {
@ -711,15 +697,13 @@ public abstract class TaskElement extends BaseEntity {
this.resetStatus(); this.resetStatus();
} }
private EffortDuration sumOfAssignedEffort = EffortDuration.zero();
public void setSumOfAssignedEffort(EffortDuration sumOfAssignedEffort) { public void setSumOfAssignedEffort(EffortDuration sumOfAssignedEffort) {
this.sumOfAssignedEffort = sumOfAssignedEffort; this.sumOfAssignedEffort = sumOfAssignedEffort;
} }
public EffortDuration getSumOfAssignedEffort() { public EffortDuration getSumOfAssignedEffort() {
if ( this.getParent() == null ) { if ( this.getParent() == null ) {
//it's an order, we use the cached value // It's an order, we use the cached value
return sumOfAssignedEffort; return sumOfAssignedEffort;
} }
else { else {
@ -729,7 +713,7 @@ public abstract class TaskElement extends BaseEntity {
private EffortDuration getSumOfAssignedEffortCalculated() { private EffortDuration getSumOfAssignedEffortCalculated() {
EffortDuration result = EffortDuration.zero(); EffortDuration result = EffortDuration.zero();
for(ResourceAllocation<?> allocation : getAllResourceAllocations()) { for (ResourceAllocation<?> allocation : getAllResourceAllocations()) {
result = result.plus(allocation.getAssignedEffort()); result = result.plus(allocation.getAssignedEffort());
} }
return result; return result;
@ -743,7 +727,7 @@ public abstract class TaskElement extends BaseEntity {
public List<TaskElement> getAllChildren() { public List<TaskElement> getAllChildren() {
List<TaskElement> children = getChildren(); List<TaskElement> children = getChildren();
List<TaskElement> result = new ArrayList<TaskElement>(); List<TaskElement> result = new ArrayList<>();
for (TaskElement child : children) { for (TaskElement child : children) {
result.add(child); result.add(child);
result.addAll(child.getAllChildren()); result.addAll(child.getAllChildren());
@ -755,12 +739,15 @@ public abstract class TaskElement extends BaseEntity {
public abstract EffortDuration getTheoreticalCompletedTimeUntilDate(Date date); public abstract EffortDuration getTheoreticalCompletedTimeUntilDate(Date date);
public BigDecimal getTheoreticalAdvancePercentageUntilDate(Date date) { public BigDecimal getTheoreticalAdvancePercentageUntilDate(Date date) {
EffortDuration totalAllocatedTime = AggregateOfDayAssignments.create( EffortDuration totalAllocatedTime =
this.getDayAssignments(FilterType.KEEP_ALL)).getTotalTime(); AggregateOfDayAssignments.create(this.getDayAssignments(FilterType.KEEP_ALL)).getTotalTime();
EffortDuration totalTheoreticalCompletedTime = this.getTheoreticalCompletedTimeUntilDate(date); EffortDuration totalTheoreticalCompletedTime = this.getTheoreticalCompletedTimeUntilDate(date);
if ( totalAllocatedTime.isZero() || totalTheoreticalCompletedTime.isZero() ) { if ( totalAllocatedTime.isZero() || totalTheoreticalCompletedTime.isZero() ) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
Validate.isTrue(totalTheoreticalCompletedTime.getSeconds() <= totalAllocatedTime.getSeconds()); Validate.isTrue(totalTheoreticalCompletedTime.getSeconds() <= totalAllocatedTime.getSeconds());
return totalTheoreticalCompletedTime.dividedByAndResultAsBigDecimal(totalAllocatedTime); return totalTheoreticalCompletedTime.dividedByAndResultAsBigDecimal(totalAllocatedTime);
@ -779,23 +766,19 @@ public abstract class TaskElement extends BaseEntity {
} }
public Boolean isRoot() { public Boolean isRoot() {
return (this.getParent() == null); return this.getParent() == null;
} }
public BigDecimal getBudget() { public BigDecimal getBudget() {
if ( (taskSource != null) && (taskSource.getOrderElement() != null) ) { return (taskSource != null) && (taskSource.getOrderElement() != null)
return taskSource.getOrderElement().getBudget(); ? taskSource.getOrderElement().getBudget()
} : null;
return null;
} }
public BigDecimal getResourcesBudget() { public BigDecimal getResourcesBudget() {
if ( (taskSource != null) && (taskSource.getOrderElement() != null) ) { return (taskSource != null) && (taskSource.getOrderElement() != null)
return taskSource.getOrderElement().getResourcesBudget(); ? taskSource.getOrderElement().getResourcesBudget()
} : null;
return null;
} }
public ExternalCompany getSubcontractedCompany() { public ExternalCompany getSubcontractedCompany() {
@ -806,10 +789,13 @@ public abstract class TaskElement extends BaseEntity {
public TaskDeadlineViolationStatusEnum getDeadlineViolationStatus() { public TaskDeadlineViolationStatusEnum getDeadlineViolationStatus() {
LocalDate deadline = this.getDeadline(); LocalDate deadline = this.getDeadline();
if ( deadline == null ) { if ( deadline == null ) {
return TaskDeadlineViolationStatusEnum.NO_DEADLINE; return TaskDeadlineViolationStatusEnum.NO_DEADLINE;
} else if ( this.getEndAsLocalDate().isAfter(deadline) ) { } else if ( this.getEndAsLocalDate().isAfter(deadline) ) {
return TaskDeadlineViolationStatusEnum.DEADLINE_VIOLATED; return TaskDeadlineViolationStatusEnum.DEADLINE_VIOLATED;
} else { } else {
return TaskDeadlineViolationStatusEnum.ON_SCHEDULE; return TaskDeadlineViolationStatusEnum.ON_SCHEDULE;
} }

View file

@ -98,16 +98,16 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long> imple
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
public QualityForm findUniqueByName(QualityForm qualityForm) throws InstanceNotFoundException { public QualityForm findUniqueByName(QualityForm qualityForm) throws InstanceNotFoundException {
Validate.notNull(qualityForm); Validate.notNull(qualityForm);
return findUniqueByName(qualityForm.getName()); return findUniqueByName(qualityForm.getName());
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
public QualityForm findUniqueByName(String name) throws InstanceNotFoundException, NonUniqueResultException { public QualityForm findUniqueByName(String name) throws InstanceNotFoundException, NonUniqueResultException {
Criteria c = getSession().createCriteria(QualityForm.class); QualityForm qualityForm = (QualityForm) getSession()
c.add(Restrictions.eq("name", name)); .createCriteria(QualityForm.class)
QualityForm qualityForm = (QualityForm) c.uniqueResult(); .add(Restrictions.eq("name", name))
.uniqueResult();
if (qualityForm == null) { if (qualityForm == null) {
throw new InstanceNotFoundException(null, "QualityForm"); throw new InstanceNotFoundException(null, "QualityForm");
@ -120,7 +120,6 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long> imple
public boolean existsOtherWorkReportTypeByName(QualityForm qualityForm) { public boolean existsOtherWorkReportTypeByName(QualityForm qualityForm) {
try { try {
QualityForm t = findUniqueByName(qualityForm); QualityForm t = findUniqueByName(qualityForm);
return t != null && t != qualityForm; return t != null && t != qualityForm;
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
return false; return false;

View file

@ -36,14 +36,13 @@ import org.libreplan.business.orders.entities.OrderElement;
public class TaskQualityForm extends BaseEntity { public class TaskQualityForm extends BaseEntity {
public static TaskQualityForm create(OrderElement orderElement, private OrderElement orderElement;
QualityForm qualityForm) {
return create(new TaskQualityForm(orderElement, qualityForm));
}
protected TaskQualityForm() { private QualityForm qualityForm;
} private List<TaskQualityFormItem> taskQualityFormItems = new ArrayList<>();
private Boolean reportAdvance = false;
private TaskQualityForm(OrderElement orderElement, QualityForm qualityForm) { private TaskQualityForm(OrderElement orderElement, QualityForm qualityForm) {
this.orderElement = orderElement; this.orderElement = orderElement;
@ -51,21 +50,21 @@ public class TaskQualityForm extends BaseEntity {
createTaskQualityFormItems(); createTaskQualityFormItems();
} }
private OrderElement orderElement; protected TaskQualityForm() {
private QualityForm qualityForm; }
private List<TaskQualityFormItem> taskQualityFormItems = new ArrayList<TaskQualityFormItem>(); public static TaskQualityForm create(OrderElement orderElement,
QualityForm qualityForm) {
private Boolean reportAdvance = false; return create(new TaskQualityForm(orderElement, qualityForm));
}
@Valid @Valid
public List<TaskQualityFormItem> getTaskQualityFormItems() { public List<TaskQualityFormItem> getTaskQualityFormItems() {
return Collections.unmodifiableList(taskQualityFormItems); return Collections.unmodifiableList(taskQualityFormItems);
} }
public void setTaskQualityFormItems( public void setTaskQualityFormItems(List<TaskQualityFormItem> taskQualityFormItems) {
List<TaskQualityFormItem> taskQualityFormItems) {
this.taskQualityFormItems = taskQualityFormItems; this.taskQualityFormItems = taskQualityFormItems;
} }
@ -89,10 +88,8 @@ public class TaskQualityForm extends BaseEntity {
private void createTaskQualityFormItems() { private void createTaskQualityFormItems() {
Validate.notNull(qualityForm); Validate.notNull(qualityForm);
for (QualityFormItem qualityFormItem : qualityForm for (QualityFormItem qualityFormItem : qualityForm.getQualityFormItems()) {
.getQualityFormItems()) { TaskQualityFormItem taskQualityFormItem = TaskQualityFormItem.create(qualityFormItem);
TaskQualityFormItem taskQualityFormItem = TaskQualityFormItem
.create(qualityFormItem);
taskQualityFormItems.add(taskQualityFormItem); taskQualityFormItems.add(taskQualityFormItem);
} }
} }
@ -107,6 +104,7 @@ public class TaskQualityForm extends BaseEntity {
} }
} }
} }
return true; return true;
} }
@ -120,52 +118,48 @@ public class TaskQualityForm extends BaseEntity {
} }
} }
} }
return true; return true;
} }
public boolean isCorrectConsecutivePassed(TaskQualityFormItem item) { public boolean isCorrectConsecutivePassed(TaskQualityFormItem item) {
if (item.getPassed()) { return !item.getPassed() || (isPassedPreviousItem(item));
return (isPassedPreviousItem(item));
}
return true;
} }
public boolean isCorrectConsecutiveDate(TaskQualityFormItem item) { public boolean isCorrectConsecutiveDate(TaskQualityFormItem item) {
if (item.getPassed()) { if (item.getPassed()) {
return ((isPassedPreviousItem(item)) && (isLaterToPreviousItemDate(item))); return (isPassedPreviousItem(item)) && (isLaterToPreviousItemDate(item));
} }
return (item.getDate() == null);
return item.getDate() == null;
} }
public boolean isPassedPreviousItem(TaskQualityFormItem item) { public boolean isPassedPreviousItem(TaskQualityFormItem item) {
Integer previousPosition = item.getPosition() - 1; Integer previousPosition = item.getPosition() - 1;
if ((previousPosition >= 0) if ((previousPosition >= 0)
&& (previousPosition < taskQualityFormItems.size())) { && (previousPosition < taskQualityFormItems.size())) {
return taskQualityFormItems.get(previousPosition).getPassed(); return taskQualityFormItems.get(previousPosition).getPassed();
} }
return true; return true;
} }
public boolean isLaterToPreviousItemDate(TaskQualityFormItem item) { public boolean isLaterToPreviousItemDate(TaskQualityFormItem item) {
Integer previousPosition = item.getPosition() - 1; Integer previousPosition = item.getPosition() - 1;
if ((previousPosition >= 0) if ((previousPosition >= 0) && (previousPosition < taskQualityFormItems.size())) {
&& (previousPosition < taskQualityFormItems.size())) { Date previousDate = taskQualityFormItems.get(previousPosition).getDate();
Date previousDate = taskQualityFormItems.get(previousPosition) return (previousDate != null) && (item.getDate() != null) &&
.getDate(); ((previousDate.before(item.getDate())) || (previousDate.equals(item.getDate())));
return ((previousDate != null) && (item.getDate() != null) && ((previousDate
.before(item.getDate())) || (previousDate.equals(item
.getDate()))));
} }
return true; return true;
} }
public boolean isByItems() { public boolean isByItems() {
if ((this.qualityForm != null) return !((this.qualityForm != null) && (this.qualityForm.getQualityFormType() != null)) ||
&& (this.qualityForm.getQualityFormType() != null)) { (this.qualityForm.getQualityFormType().equals(QualityFormType.BY_ITEMS));
return (this.qualityForm.getQualityFormType()
.equals(QualityFormType.BY_ITEMS));
}
return true;
} }
@NotNull(message = "report progress not specified") @NotNull(message = "report progress not specified")
@ -177,12 +171,11 @@ public class TaskQualityForm extends BaseEntity {
this.reportAdvance = BooleanUtils.toBoolean(reportAdvance); this.reportAdvance = BooleanUtils.toBoolean(reportAdvance);
} }
public static TaskQualityForm copy(TaskQualityForm origin, public static TaskQualityForm copy(TaskQualityForm origin, OrderElement orderElement) {
OrderElement orderElement) { TaskQualityForm copy = TaskQualityForm.create(orderElement, origin.getQualityForm());
TaskQualityForm copy = TaskQualityForm.create(orderElement, origin
.getQualityForm());
copy.setTaskQualityFormItems(origin.getTaskQualityFormItems()); copy.setTaskQualityFormItems(origin.getTaskQualityFormItems());
copy.setReportAdvance(origin.isReportAdvance()); copy.setReportAdvance(origin.isReportAdvance());
return copy; return copy;
} }

View file

@ -54,17 +54,16 @@ public class HoursWorkedPerResourceDTO implements Comparable {
private HoursWorkedPerResourceDTO self; private HoursWorkedPerResourceDTO self;
public HoursWorkedPerResourceDTO(Resource resource, public HoursWorkedPerResourceDTO(Resource resource, WorkReportLine workReportLine) {
WorkReportLine workReportLine) {
this.workerName = resource.getName(); this.workerName = resource.getName();
this.date = workReportLine.getDate(); this.date = workReportLine.getDate();
LocalTime clockStart = workReportLine.getClockStart(); LocalTime clockStart = workReportLine.getClockStart();
this.clockStart = (clockStart != null) ? clockStart.toString("HH:mm") this.clockStart = (clockStart != null) ? clockStart.toString("HH:mm") : "";
: "";
LocalTime clockFinish = workReportLine.getClockFinish(); LocalTime clockFinish = workReportLine.getClockFinish();
this.clockFinish = (clockFinish != null) ? clockFinish this.clockFinish = (clockFinish != null) ? clockFinish.toString("HH:mm") : "";
.toString("HH:mm") : "";
this.effort = workReportLine.getEffort(); this.effort = workReportLine.getEffort();
this.orderElementCode = workReportLine.getOrderElement().getCode(); this.orderElementCode = workReportLine.getOrderElement().getCode();
this.orderElementName = workReportLine.getOrderElement().getName(); this.orderElementName = workReportLine.getOrderElement().getName();
@ -168,8 +167,7 @@ public class HoursWorkedPerResourceDTO implements Comparable {
@Override @Override
public int compareTo(Object o) { public int compareTo(Object o) {
return this.workerName return this.workerName.compareTo(((HoursWorkedPerResourceDTO) o).workerName);
.compareTo(((HoursWorkedPerResourceDTO) o).workerName);
} }
/** /**

View file

@ -27,8 +27,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.libreplan.business.common.daos.IEntitySequenceDAO; import org.libreplan.business.common.daos.IEntitySequenceDAO;
import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.entities.EntityNameEnum;
import org.libreplan.business.resources.daos.ICriterionDAO; import org.libreplan.business.resources.daos.ICriterionDAO;
@ -36,6 +34,7 @@ import org.libreplan.business.resources.daos.ICriterionTypeDAO;
import org.libreplan.business.resources.entities.Criterion; import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.CriterionType; import org.libreplan.business.resources.entities.CriterionType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -47,11 +46,9 @@ import org.springframework.transaction.annotation.Transactional;
* @author Diego Pino García <dpino@igalia.com> * @author Diego Pino García <dpino@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class CriterionsBootstrap implements ICriterionsBootstrap { public class CriterionsBootstrap implements ICriterionsBootstrap {
private static final Log LOG = LogFactory.getLog(CriterionsBootstrap.class);
@Autowired @Autowired
private ICriterionDAO criterionDAO; private ICriterionDAO criterionDAO;
@ -73,8 +70,7 @@ public class CriterionsBootstrap implements ICriterionsBootstrap {
if (criterionTypeDAO.findAll().isEmpty()) { if (criterionTypeDAO.findAll().isEmpty()) {
Map<CriterionType, List<String>> typesWithCriterions = getTypesWithCriterions(); Map<CriterionType, List<String>> typesWithCriterions = getTypesWithCriterions();
// Insert predefined criterions // Insert predefined criterions
for (Entry<CriterionType, List<String>> entry : typesWithCriterions for (Entry<CriterionType, List<String>> entry : typesWithCriterions.entrySet()) {
.entrySet()) {
CriterionType criterionType = retrieveOrCreate(entry.getKey()); CriterionType criterionType = retrieveOrCreate(entry.getKey());
// Create predefined criterions for criterionType // Create predefined criterions for criterionType
for (String criterionName : entry.getValue()) { for (String criterionName : entry.getValue()) {
@ -84,10 +80,9 @@ public class CriterionsBootstrap implements ICriterionsBootstrap {
} }
} }
private void ensureCriterionExists(String criterionName, private void ensureCriterionExists(String criterionName, CriterionType criterionType) {
CriterionType criterionType) { Criterion criterion = Criterion.createPredefined(criterionName, criterionType);
Criterion criterion = Criterion.createPredefined(criterionName,
criterionType);
if (!criterionDAO.existsPredefinedCriterion(criterion)) { if (!criterionDAO.existsPredefinedCriterion(criterion)) {
int numberOfDigits = getNumberOfDigitsCode(); int numberOfDigits = getNumberOfDigitsCode();
criterionType.setGenerateCode(criterion, numberOfDigits); criterionType.setGenerateCode(criterion, numberOfDigits);
@ -104,26 +99,26 @@ public class CriterionsBootstrap implements ICriterionsBootstrap {
criterionTypeDAO.save(criterionType); criterionTypeDAO.save(criterionType);
return criterionType; return criterionType;
} }
return criterionTypeDAO.findPredefined(criterionType); return criterionTypeDAO.findPredefined(criterionType);
} }
private Map<CriterionType, List<String>> getTypesWithCriterions() { private Map<CriterionType, List<String>> getTypesWithCriterions() {
HashMap<CriterionType, List<String>> result = new HashMap<CriterionType, List<String>>(); HashMap<CriterionType, List<String>> result = new HashMap<>();
for (ICriterionTypeProvider provider : providers) { for (ICriterionTypeProvider provider : providers) {
for (Entry<CriterionType, List<String>> entry : provider for (Entry<CriterionType, List<String>> entry : provider.getRequiredCriterions().entrySet()) {
.getRequiredCriterions().entrySet()) {
if (!result.containsKey(entry.getKey())) { if (!result.containsKey(entry.getKey())) {
result.put(entry.getKey(), new ArrayList<String>()); result.put(entry.getKey(), new ArrayList<String>());
} }
result.get(entry.getKey()).addAll(entry.getValue()); result.get(entry.getKey()).addAll(entry.getValue());
} }
} }
return result; return result;
} }
protected Integer getNumberOfDigitsCode() { protected Integer getNumberOfDigitsCode() {
return entitySequenceDAO return entitySequenceDAO.getNumberOfDigitsCode(EntityNameEnum.CRITERION);
.getNumberOfDigitsCode(EntityNameEnum.CRITERION);
} }
} }

View file

@ -27,6 +27,7 @@ import java.util.Map;
import org.libreplan.business.resources.entities.CriterionType; import org.libreplan.business.resources.entities.CriterionType;
import org.libreplan.business.resources.entities.PredefinedCriterionTypes; import org.libreplan.business.resources.entities.PredefinedCriterionTypes;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -37,7 +38,7 @@ import org.springframework.stereotype.Component;
* @author Diego Pino García <dpino@igalia.com> * @author Diego Pino García <dpino@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class PredefinedCriterionTypesProvider implements ICriterionTypeProvider { public class PredefinedCriterionTypesProvider implements ICriterionTypeProvider {
public PredefinedCriterionTypesProvider() { public PredefinedCriterionTypesProvider() {
@ -45,10 +46,12 @@ public class PredefinedCriterionTypesProvider implements ICriterionTypeProvider
@Override @Override
public Map<CriterionType, List<String>> getRequiredCriterions() { public Map<CriterionType, List<String>> getRequiredCriterions() {
Map<CriterionType, List<String>> result = new HashMap<CriterionType, List<String>>(); Map<CriterionType, List<String>> result = new HashMap<>();
for (PredefinedCriterionTypes type : PredefinedCriterionTypes.values()) { for (PredefinedCriterionTypes type : PredefinedCriterionTypes.values()) {
result.put(CriterionType.fromPredefined(type), type.getPredefined()); result.put(CriterionType.fromPredefined(type), type.getPredefined());
} }
return result; return result;
} }
} }

View file

@ -23,9 +23,9 @@ import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.libreplan.business.common.IAdHocTransactionService;
import org.libreplan.business.planner.daos.IDayAssignmentDAO; import org.libreplan.business.planner.daos.IDayAssignmentDAO;
import org.libreplan.business.planner.entities.DayAssignment; import org.libreplan.business.planner.entities.DayAssignment;
import org.libreplan.business.resources.entities.Resource; import org.libreplan.business.resources.entities.Resource;
@ -43,13 +43,11 @@ import org.springframework.transaction.annotation.Transactional;
* {@link IResourceLoadRatiosCalculator} interface. * {@link IResourceLoadRatiosCalculator} interface.
* *
* @author Javier Moran Rua <jmoran@igalia.com> * @author Javier Moran Rua <jmoran@igalia.com>
*
*/ */
@Service @Service
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class ResourceLoadRatiosCalculator implements public class ResourceLoadRatiosCalculator implements IResourceLoadRatiosCalculator {
IResourceLoadRatiosCalculator {
@Autowired @Autowired
private IDayAssignmentDAO dayAssigmentDAO; private IDayAssignmentDAO dayAssigmentDAO;
@ -57,17 +55,14 @@ public class ResourceLoadRatiosCalculator implements
@Autowired @Autowired
private IResourceDAO resourceDAO; private IResourceDAO resourceDAO;
@Autowired private static class LoadRatiosDataType implements IResourceLoadRatiosCalculator.ILoadRatiosDataType {
private IAdHocTransactionService adHocTransactionService;
private static class LoadRatiosDataType implements
IResourceLoadRatiosCalculator.ILoadRatiosDataType {
private EffortDuration load; private EffortDuration load;
private EffortDuration overload; private EffortDuration overload;
private EffortDuration capacity; private EffortDuration capacity;
public LoadRatiosDataType(EffortDuration load, EffortDuration overload, public LoadRatiosDataType(EffortDuration load, EffortDuration overload, EffortDuration capacity) {
EffortDuration capacity) {
this.load = load; this.load = load;
this.overload = overload; this.overload = overload;
this.capacity = capacity; this.capacity = capacity;
@ -94,8 +89,7 @@ public class ResourceLoadRatiosCalculator implements
if (this.load.isZero() && this.overload.isZero()) { if (this.load.isZero() && this.overload.isZero()) {
result = BigDecimal.ZERO; result = BigDecimal.ZERO;
} else { } else {
result = this.overload.dividedByAndResultAsBigDecimal(this.load result = this.overload.dividedByAndResultAsBigDecimal(this.load.plus(this.capacity));
.plus(this.capacity));
} }
return result.setScale(2, BigDecimal.ROUND_HALF_UP); return result.setScale(2, BigDecimal.ROUND_HALF_UP);
@ -104,12 +98,13 @@ public class ResourceLoadRatiosCalculator implements
@Override @Override
public BigDecimal getAvailiabilityRatio() { public BigDecimal getAvailiabilityRatio() {
BigDecimal result; BigDecimal result;
if (this.capacity.isZero()) { if (this.capacity.isZero()) {
result = BigDecimal.ZERO; result = BigDecimal.ZERO;
} else { } else {
result = BigDecimal.ONE.subtract(this.load result = BigDecimal.ONE.subtract(this.load.dividedByAndResultAsBigDecimal(this.capacity));
.dividedByAndResultAsBigDecimal(this.capacity));
if (result.compareTo(BigDecimal.ZERO) < 0) { if (result.compareTo(BigDecimal.ZERO) < 0) {
result = BigDecimal.ZERO; result = BigDecimal.ZERO;
} }
@ -121,35 +116,39 @@ public class ResourceLoadRatiosCalculator implements
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ILoadRatiosDataType calculateLoadRatios(final Resource resource, public ILoadRatiosDataType calculateLoadRatios(final Resource resource,
final LocalDate startDate, final LocalDate endDate, final LocalDate startDate,
final Scenario scenario) { final LocalDate endDate,
final Scenario scenario) {
resourceDAO.reattach(resource); resourceDAO.reattach(resource);
EffortDuration totalLoad = EffortDuration.zero(), totalOverload = EffortDuration EffortDuration
.zero(), totalCapacity = EffortDuration.zero(); totalLoad = EffortDuration.zero(),
totalOverload = EffortDuration.zero(),
totalCapacity;
for (Map.Entry<LocalDate, EffortDuration> each : getAllEffortPerDateFor( Set<Map.Entry<LocalDate, EffortDuration>> efforts =
scenario, startDate, endDate, resource).entrySet()) { getAllEffortPerDateFor(scenario, startDate, endDate, resource).entrySet();
for (Map.Entry<LocalDate, EffortDuration> each : efforts) {
totalLoad = totalLoad.plus(each.getValue()); totalLoad = totalLoad.plus(each.getValue());
totalOverload = addOverload(totalOverload, resource, totalOverload = addOverload(totalOverload, resource, each.getValue(), each.getKey());
each.getValue(), each.getKey());
} }
totalCapacity = calculateTotalCapacity(resource, startDate, endDate); totalCapacity = calculateTotalCapacity(resource, startDate, endDate);
return new LoadRatiosDataType(totalLoad, totalOverload, totalCapacity); return new LoadRatiosDataType(totalLoad, totalOverload, totalCapacity);
} }
private Map<LocalDate, EffortDuration> getAllEffortPerDateFor( private Map<LocalDate, EffortDuration> getAllEffortPerDateFor(
Scenario scenario, LocalDate startDate, LocalDate endDate, Scenario scenario, LocalDate startDate, LocalDate endDate, Resource resource) {
Resource resource) {
HashMap<LocalDate, EffortDuration> result = new HashMap<LocalDate, EffortDuration>(); HashMap<LocalDate, EffortDuration> result;
result = new HashMap<>();
List<DayAssignment> l = dayAssigmentDAO.getAllFor(scenario, startDate, List<DayAssignment> l = dayAssigmentDAO.getAllFor(scenario, startDate, endDate, resource);
endDate, resource);
EffortDuration newValue;
EffortDuration newValue = EffortDuration.zero();
for (DayAssignment each : l) { for (DayAssignment each : l) {
if (result.containsKey(each.getDay())) { if (result.containsKey(each.getDay())) {
newValue = result.get(each.getDay()).plus(each.getDuration()); newValue = result.get(each.getDay()).plus(each.getDuration());
@ -161,15 +160,16 @@ public class ResourceLoadRatiosCalculator implements
return result; return result;
} }
private EffortDuration calculateTotalCapacity(Resource resource, private EffortDuration calculateTotalCapacity(Resource resource, LocalDate startDate, LocalDate endDate) {
LocalDate startDate, LocalDate endDate) {
return resource.getCalendar().getWorkableDuration(startDate, endDate); return resource.getCalendar().getWorkableDuration(startDate, endDate);
} }
private EffortDuration addOverload(EffortDuration currentOverload, private EffortDuration addOverload(
Resource resource, EffortDuration loadAtDate, LocalDate date) { EffortDuration currentOverload, Resource resource, EffortDuration loadAtDate, LocalDate date) {
EffortDuration result; EffortDuration result;
EffortDuration capacityAtDay = getCapacityAtDate(resource, date); EffortDuration capacityAtDay = getCapacityAtDate(resource, date);
if (capacityAtDay.compareTo(loadAtDate) < 0) { if (capacityAtDay.compareTo(loadAtDate) < 0) {
result = currentOverload.plus(loadAtDate.minus(capacityAtDay)); result = currentOverload.plus(loadAtDate.minus(capacityAtDay));
} else { } else {

View file

@ -70,6 +70,7 @@ public class ResourcesSearcher implements IResourcesSearcher {
@Autowired @Autowired
private SessionFactory sessionFactory; private SessionFactory sessionFactory;
@Override
public IResourcesQuery<Machine> searchMachines() { public IResourcesQuery<Machine> searchMachines() {
return new Query<>(Machine.class); return new Query<>(Machine.class);
} }
@ -104,7 +105,6 @@ public class ResourcesSearcher implements IResourcesSearcher {
public IResourcesQuery<T> byCriteria(Collection<? extends Criterion> criteria) { public IResourcesQuery<T> byCriteria(Collection<? extends Criterion> criteria) {
Validate.noNullElements(criteria); Validate.noNullElements(criteria);
this.criteria = new ArrayList<>(criteria); this.criteria = new ArrayList<>(criteria);
return this; return this;
} }
@ -205,13 +205,13 @@ public class ResourcesSearcher implements IResourcesSearcher {
public IResourcesQuery<Resource> searchBoth() { public IResourcesQuery<Resource> searchBoth() {
final IResourcesQuery<Worker> searchWorkers = searchWorkers(); final IResourcesQuery<Worker> searchWorkers = searchWorkers();
final IResourcesQuery<Machine> searchMachines = searchMachines(); final IResourcesQuery<Machine> searchMachines = searchMachines();
return new IResourcesQuery<Resource>() { return new IResourcesQuery<Resource>() {
@Override @Override
public IResourcesQuery<Resource> byName(String name) { public IResourcesQuery<Resource> byName(String name) {
searchWorkers.byName(name); searchWorkers.byName(name);
searchMachines.byName(name); searchMachines.byName(name);
return this; return this;
} }
@ -219,7 +219,6 @@ public class ResourcesSearcher implements IResourcesSearcher {
public IResourcesQuery<Resource> byCriteria(Collection<? extends Criterion> criteria) { public IResourcesQuery<Resource> byCriteria(Collection<? extends Criterion> criteria) {
searchWorkers.byCriteria(criteria); searchWorkers.byCriteria(criteria);
searchMachines.byCriteria(criteria); searchMachines.byCriteria(criteria);
return this; return this;
} }
@ -227,7 +226,6 @@ public class ResourcesSearcher implements IResourcesSearcher {
public IResourcesQuery<Resource> byResourceType(ResourceType type) { public IResourcesQuery<Resource> byResourceType(ResourceType type) {
searchWorkers.byResourceType(type); searchWorkers.byResourceType(type);
searchMachines.byResourceType(type); searchMachines.byResourceType(type);
return this; return this;
} }

View file

@ -31,7 +31,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.commons.collections.ComparatorUtils; import org.apache.commons.collections4.ComparatorUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.EqualsBuilder;
@ -48,7 +48,8 @@ import org.libreplan.business.requirements.entities.CriterionRequirement;
import org.libreplan.business.resources.daos.ICriterionDAO; import org.libreplan.business.resources.daos.ICriterionDAO;
/** /**
* A criterion stored in the database <br /> * A criterion stored in the database.
* <br />
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
*/ */
@ -165,8 +166,7 @@ public class Criterion extends IntegrationEntity implements ICriterion,
return getCaptionFor(ResourceEnum.WORKER, criteria); return getCaptionFor(ResourceEnum.WORKER, criteria);
} }
public static String getCaptionFor( public static String getCaptionFor(GenericResourceAllocation allocation) {
GenericResourceAllocation allocation) {
return getCaptionFor(allocation.getResourceType(), return getCaptionFor(allocation.getResourceType(),
allocation.getCriterions()); allocation.getCriterions());
} }
@ -178,7 +178,7 @@ public class Criterion extends IntegrationEntity implements ICriterion,
* @return * @return
*/ */
public static String getCaptionFor(ResourceEnum resourceType, public static String getCaptionFor(ResourceEnum resourceType,
Collection<? extends Criterion> criteria) { Collection<? extends Criterion> criteria) {
if (criteria.isEmpty()) { if (criteria.isEmpty()) {
return allCaptionFor(resourceType); return allCaptionFor(resourceType);
} }
@ -191,12 +191,12 @@ public class Criterion extends IntegrationEntity implements ICriterion,
private static String allCaptionFor(ResourceEnum resourceType) { private static String allCaptionFor(ResourceEnum resourceType) {
switch (resourceType) { switch (resourceType) {
case WORKER: case WORKER:
return allWorkersCaption(); return allWorkersCaption();
case MACHINE: case MACHINE:
return allMachinesCaption(); return allMachinesCaption();
default: default:
throw new RuntimeException("cant handle " + resourceType); throw new RuntimeException("cant handle " + resourceType);
} }
} }
@ -463,9 +463,7 @@ public class Criterion extends IntegrationEntity implements ICriterion,
} }
@Override @Override
public void setCodeAutogenerated(Boolean codeAutogenerated) { public void setCodeAutogenerated(Boolean codeAutogenerated) { /* Do nothing */ }
// do nothing
}
@Override @Override
public Boolean isCodeAutogenerated() { public Boolean isCodeAutogenerated() {

View file

@ -35,7 +35,9 @@ import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.resources.daos.ICriterionSatisfactionDAO; import org.libreplan.business.resources.daos.ICriterionSatisfactionDAO;
import org.libreplan.business.resources.daos.ICriterionTypeDAO; import org.libreplan.business.resources.daos.ICriterionTypeDAO;
/** /**
* Declares a interval of time in which the criterion is satisfied <br /> * Declares a interval of time in which the criterion is satisfied.
* <br />
*
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
*/ */
@ -45,30 +47,55 @@ public class CriterionSatisfaction extends IntegrationEntity {
static { static {
BY_START_COMPARATOR = new Comparator<CriterionSatisfaction>() { BY_START_COMPARATOR = new Comparator<CriterionSatisfaction>() {
@Override @Override
public int compare(CriterionSatisfaction o1, public int compare(CriterionSatisfaction o1, CriterionSatisfaction o2) {
CriterionSatisfaction o2) {
return o1.getStartDate().compareTo(o2.getStartDate()); return o1.getStartDate().compareTo(o2.getStartDate());
} }
}; };
} }
private LocalDate startDate;
private LocalDate finishDate;
private Criterion criterion;
private Resource resource;
private Boolean isDeleted = false;
/**
* Constructor for hibernate. Do not use!
*/
public CriterionSatisfaction() {}
private CriterionSatisfaction(LocalDate startDate, Criterion criterion, Resource resource) {
Validate.notNull(startDate, "startDate must be not null");
Validate.notNull(criterion, "criterion must be not null");
Validate.notNull(resource, "resource must be not null");
this.startDate = startDate;
this.criterion = criterion;
this.resource = resource;
}
private CriterionSatisfaction(Criterion criterion, Resource resource, Interval interval) {
this(interval.getStart(), criterion, resource);
if (interval.getEnd() != null) {
this.finish(interval.getEnd());
}
}
public static CriterionSatisfaction create() { public static CriterionSatisfaction create() {
return create(new CriterionSatisfaction()); return create(new CriterionSatisfaction());
} }
public static CriterionSatisfaction create(LocalDate startDate, public static CriterionSatisfaction create(LocalDate startDate, Criterion criterion, Resource resource) {
Criterion criterion, Resource resource) { return create(new CriterionSatisfaction(startDate, criterion, resource));
return create(
new CriterionSatisfaction(startDate, criterion, resource));
} }
public static CriterionSatisfaction create(Criterion criterion, public static CriterionSatisfaction create(Criterion criterion, Resource resource, Interval interval) {
Resource resource, Interval interval) {
return create(new CriterionSatisfaction(criterion, resource, interval)); return create(new CriterionSatisfaction(criterion, resource, interval));
} }
/** /**
@ -76,24 +103,22 @@ public class CriterionSatisfaction extends IntegrationEntity {
* not exist * not exist
*/ */
public static CriterionSatisfaction createUnvalidated(String code, public static CriterionSatisfaction createUnvalidated(String code,
String criterionTypeName, String criterionName, Resource resource, String criterionTypeName,
LocalDate startDate, LocalDate finishDate) String criterionName,
throws InstanceNotFoundException { Resource resource,
LocalDate startDate,
LocalDate finishDate) throws InstanceNotFoundException {
ICriterionTypeDAO criterionTypeDAO = ICriterionTypeDAO criterionTypeDAO = Registry.getCriterionTypeDAO();
Registry.getCriterionTypeDAO();
/* Get CriterionType. */ /* Get CriterionType */
CriterionType criterionType = criterionTypeDAO.findUniqueByName( CriterionType criterionType = criterionTypeDAO.findUniqueByName(criterionTypeName);
criterionTypeName);
/* Get Criterion. */ /* Get Criterion */
Criterion criterion = criterionType.getCriterion( Criterion criterion = criterionType.getCriterion(criterionName);
criterionName);
/* Create instance of CriterionSatisfaction. */ /* Create instance of CriterionSatisfaction */
CriterionSatisfaction criterionSatisfaction = CriterionSatisfaction criterionSatisfaction = create(new CriterionSatisfaction(), code);
create(new CriterionSatisfaction(), code);
criterionSatisfaction.criterion = criterion; criterionSatisfaction.criterion = criterion;
criterionSatisfaction.resource = resource; criterionSatisfaction.resource = resource;
@ -109,19 +134,19 @@ public class CriterionSatisfaction extends IntegrationEntity {
* not exist * not exist
*/ */
public void updateUnvalidated(String criterionTypeName, public void updateUnvalidated(String criterionTypeName,
String criterionName, LocalDate startDate, LocalDate finishDate) String criterionName,
throws InstanceNotFoundException { LocalDate startDate,
LocalDate finishDate) throws InstanceNotFoundException {
CriterionType criterionType = null; CriterionType criterionType;
if (StringUtils.isBlank(criterionTypeName)) { if (StringUtils.isBlank(criterionTypeName)) {
criterionType = criterion.getType(); criterionType = criterion.getType();
} else { } else {
criterionType = Registry.getCriterionTypeDAO().findUniqueByName( criterionType = Registry.getCriterionTypeDAO().findUniqueByName(criterionTypeName);
criterionTypeName);
} }
String newCriterionName = null; String newCriterionName;
if (StringUtils.isBlank(criterionName)) { if (StringUtils.isBlank(criterionName)) {
newCriterionName = StringUtils.trim(criterion.getName()); newCriterionName = StringUtils.trim(criterion.getName());
@ -138,44 +163,8 @@ public class CriterionSatisfaction extends IntegrationEntity {
if (finishDate != null) { if (finishDate != null) {
this.finishDate = finishDate; this.finishDate = finishDate;
} }
} }
/**
* Constructor for hibernate. Do not use!
*/
public CriterionSatisfaction() {
}
private CriterionSatisfaction(LocalDate startDate, Criterion criterion,
Resource resource) {
Validate.notNull(startDate, "startDate must be not null");
Validate.notNull(criterion, "criterion must be not null");
Validate.notNull(resource, "resource must be not null");
this.startDate = startDate;
this.criterion = criterion;
this.resource = resource;
}
private CriterionSatisfaction(Criterion criterion, Resource resource,
Interval interval) {
this(interval.getStart(), criterion, resource);
if (interval.getEnd() != null) {
this.finish(interval.getEnd());
}
}
private LocalDate startDate;
private LocalDate finishDate;
private Criterion criterion;
private Resource resource;
private Boolean isDeleted = false;
@Override @Override
public String toString() { public String toString() {
return ToStringBuilder.reflectionToString(this); return ToStringBuilder.reflectionToString(this);
@ -187,6 +176,7 @@ public class CriterionSatisfaction extends IntegrationEntity {
result.finishDate = finishDate; result.finishDate = finishDate;
result.criterion = criterion; result.criterion = criterion;
result.resource = resource; result.resource = resource;
return result; return result;
} }
@ -237,10 +227,11 @@ public class CriterionSatisfaction extends IntegrationEntity {
public void finish(LocalDate finish) { public void finish(LocalDate finish) {
Validate.notNull(finish); Validate.notNull(finish);
Validate.isTrue(getStartDate() == null Validate.isTrue(getStartDate() == null || getStartDate().compareTo(finish) <= 0);
|| getStartDate().compareTo(finish) <= 0);
Validate.isTrue(finishDate == null || isNewObject() Validate.isTrue(
|| getEndDate().equals(finish) || getEndDate().isBefore(finish)); finishDate == null || isNewObject() || getEndDate().equals(finish) || getEndDate().isBefore(finish));
this.finishDate = finish; this.finishDate = finish;
} }
@ -260,10 +251,10 @@ public class CriterionSatisfaction extends IntegrationEntity {
} }
public void setStartDate(LocalDate date) { public void setStartDate(LocalDate date) {
if(date != null){ if(date != null) {
Validate.isTrue(startDate == null || isNewObject()
|| getStartDate().equals(date) Validate.isTrue(
|| getStartDate().isAfter(date)); startDate == null || isNewObject() || getStartDate().equals(date) || getStartDate().isAfter(date));
} }
startDate = date; startDate = date;
} }
@ -297,17 +288,17 @@ public class CriterionSatisfaction extends IntegrationEntity {
@AssertTrue(message = "criterion satisfaction with end date before start") @AssertTrue(message = "criterion satisfaction with end date before start")
public boolean isPositiveTimeInterval() { public boolean isPositiveTimeInterval() {
/* Check if it makes sense to check the constraint .*/ /* Check if it makes sense to check the constraint */
if (!isStartDateSpecified()) { if (!isStartDateSpecified()) {
return true; return true;
} }
/* Check the constraint. */ /* Check the constraint */
if (finishDate == null) { if (finishDate == null) {
return true; return true;
} }
return (finishDate.isAfter(startDate) || startDate.equals(finishDate)); return finishDate.isAfter(startDate) || startDate.equals(finishDate);
} }

View file

@ -30,7 +30,8 @@ import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.Valid; import javax.validation.Valid;
/** /**
* Entity * Represents entity. It is another type of work resource.
*
* @author Javier Moran Rua <jmoran@igalia.com> * @author Javier Moran Rua <jmoran@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
*/ */
@ -42,25 +43,22 @@ public class Machine extends Resource {
private String description; private String description;
private Set<MachineWorkersConfigurationUnit> configurationUnits = new HashSet<MachineWorkersConfigurationUnit>(); private Set<MachineWorkersConfigurationUnit> configurationUnits = new HashSet<>();
@Valid @Valid
public Set<MachineWorkersConfigurationUnit> getConfigurationUnits() { public Set<MachineWorkersConfigurationUnit> getConfigurationUnits() {
return Collections.unmodifiableSet(configurationUnits); return Collections.unmodifiableSet(configurationUnits);
} }
public void addMachineWorkersConfigurationUnit( public void addMachineWorkersConfigurationUnit(MachineWorkersConfigurationUnit unit) {
MachineWorkersConfigurationUnit unit) {
configurationUnits.add(unit); configurationUnits.add(unit);
} }
public void removeMachineWorkersConfigurationUnit( public void removeMachineWorkersConfigurationUnit(MachineWorkersConfigurationUnit unit) {
MachineWorkersConfigurationUnit unit) {
configurationUnits.remove(unit); configurationUnits.remove(unit);
} }
public static Machine createUnvalidated(String code, String name, public static Machine createUnvalidated(String code, String name, String description) {
String description) {
Machine machine = create(new Machine(), code); Machine machine = create(new Machine(), code);
@ -86,9 +84,7 @@ public class Machine extends Resource {
/** /**
* Used by Hibernate. Do not use! * Used by Hibernate. Do not use!
*/ */
protected Machine() { protected Machine() {}
}
public static Machine create() { public static Machine create() {
return create(new Machine()); return create(new Machine());
@ -120,8 +116,7 @@ public class Machine extends Resource {
} }
@Override @Override
protected boolean isCriterionSatisfactionOfCorrectType( protected boolean isCriterionSatisfactionOfCorrectType(CriterionSatisfaction c) {
CriterionSatisfaction c) {
return c.getResourceType().equals(ResourceEnum.MACHINE); return c.getResourceType().equals(ResourceEnum.MACHINE);
} }
@ -139,5 +134,4 @@ public class Machine extends Resource {
public String getHumanId() { public String getHumanId() {
return name; return name;
} }
} }

View file

@ -71,6 +71,7 @@ import org.libreplan.business.workingday.IntraDayDate.PartialDay;
/** /**
* This class acts as the base class for all resources. * This class acts as the base class for all resources.
*
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Jacobo Aragunde Perez <jaragunde@igalia.com> * @author Jacobo Aragunde Perez <jaragunde@igalia.com>
@ -135,7 +136,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
private Map<LocalDate, List<DayAssignment>> assignmentsByDayCached = null; private Map<LocalDate, List<DayAssignment>> assignmentsByDayCached = null;
private Set<ResourcesCostCategoryAssignment> resourcesCostCategoryAssignments = private Set<ResourcesCostCategoryAssignment> resourcesCostCategoryAssignments =
new HashSet<ResourcesCostCategoryAssignment>(); new HashSet<ResourcesCostCategoryAssignment>();
private ResourceType resourceType = ResourceType.NON_LIMITING_RESOURCE; private ResourceType resourceType = ResourceType.NON_LIMITING_RESOURCE;
@ -438,7 +439,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
private static class EnsureSatisfactionIsCorrect { private static class EnsureSatisfactionIsCorrect {
private EnsureSatisfactionIsCorrect(Resource resource, private EnsureSatisfactionIsCorrect(Resource resource,
ICriterionType<?> type, CriterionSatisfaction satisfaction) { ICriterionType<?> type, CriterionSatisfaction satisfaction) {
Validate.notNull(resource); Validate.notNull(resource);
Validate.notNull(satisfaction.getResource()); Validate.notNull(satisfaction.getResource());
Validate.notNull(satisfaction); Validate.notNull(satisfaction);
@ -469,7 +470,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public CriterionSatisfaction addSatisfaction(ICriterionType<?> type, public CriterionSatisfaction addSatisfaction(ICriterionType<?> type,
CriterionSatisfaction satisfaction) { CriterionSatisfaction satisfaction) {
return new EnsureSatisfactionIsCorrect(this, type, satisfaction) return new EnsureSatisfactionIsCorrect(this, type, satisfaction)
.addSatisfaction(); .addSatisfaction();
} }
@ -503,7 +504,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
private CriterionSatisfaction createNewSatisfaction(Interval interval, private CriterionSatisfaction createNewSatisfaction(Interval interval,
Criterion criterion) { Criterion criterion) {
CriterionSatisfaction newSatisfaction = CriterionSatisfaction.create(criterion, this, interval); CriterionSatisfaction newSatisfaction = CriterionSatisfaction.create(criterion, this, interval);
return newSatisfaction; return newSatisfaction;
} }
@ -521,7 +522,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
* </ul> * </ul>
*/ */
private int findPlace(List<CriterionSatisfaction> orderedSatisfactions, private int findPlace(List<CriterionSatisfaction> orderedSatisfactions,
CriterionSatisfaction newSatisfaction) { CriterionSatisfaction newSatisfaction) {
int position = Collections.binarySearch(orderedSatisfactions, int position = Collections.binarySearch(orderedSatisfactions,
newSatisfaction, CriterionSatisfaction.BY_START_COMPARATOR); newSatisfaction, CriterionSatisfaction.BY_START_COMPARATOR);
if (position >= 0) { if (position >= 0) {
@ -538,7 +539,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public List<CriterionSatisfaction> finishEnforcedAt(Criterion criterion, public List<CriterionSatisfaction> finishEnforcedAt(Criterion criterion,
LocalDate date) { LocalDate date) {
ArrayList<CriterionSatisfaction> result = new ArrayList<CriterionSatisfaction>(); ArrayList<CriterionSatisfaction> result = new ArrayList<CriterionSatisfaction>();
for (CriterionSatisfaction criterionSatisfaction : query() for (CriterionSatisfaction criterionSatisfaction : query()
.exactly(criterion).at(date).result()) { .exactly(criterion).at(date).result()) {
@ -549,7 +550,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public void modifySatisfaction(CriterionSatisfaction original, public void modifySatisfaction(CriterionSatisfaction original,
Interval interval){ Interval interval){
/* Create a temporal criterion satisfaction. */ /* Create a temporal criterion satisfaction. */
CriterionType type = original.getCriterion().getType(); CriterionType type = original.getCriterion().getType();
CriterionSatisfaction temporal = createNewSatisfaction(interval, CriterionSatisfaction temporal = createNewSatisfaction(interval,
@ -570,13 +571,13 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
criterionSatisfactions.add(original); criterionSatisfactions.add(original);
if(!canAdd){ if(!canAdd){
throw new IllegalStateException( throw new IllegalStateException(
"This interval "+original.getCriterion().getName()+" not is valid because exists overlap with other criterion satisfaction"); "This interval "+original.getCriterion().getName()+" not is valid because exists overlap with other criterion satisfaction");
} }
}catch(IllegalArgumentException e){ }catch(IllegalArgumentException e){
throw new IllegalArgumentException (original.getCriterion().getName()+" : "+e.getMessage()); throw new IllegalArgumentException (original.getCriterion().getName()+" : "+e.getMessage());
} }
}else{ }else{
throw new IllegalStateException( throw new IllegalStateException(
"The criterion satisfaction "+original.getCriterion().getName()+" not is activated for this resource"); "The criterion satisfaction "+original.getCriterion().getName()+" not is activated for this resource");
} }
} }
@ -596,9 +597,9 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
CriterionSatisfaction previousSameCriterion = getPreviousSameCriterion CriterionSatisfaction previousSameCriterion = getPreviousSameCriterion
(criterion, satisfaction, satisfactions); (criterion, satisfaction, satisfactions);
CriterionSatisfaction posteriorSameCriterion = getNextSameCriterion CriterionSatisfaction posteriorSameCriterion = getNextSameCriterion
(criterion, satisfaction, satisfactions); (criterion, satisfaction, satisfactions);
boolean canAdd = ((previousSameCriterion == null || boolean canAdd = ((previousSameCriterion == null ||
!previousSameCriterion.overlapsWith(interval)) && !previousSameCriterion.overlapsWith(interval)) &&
@ -616,7 +617,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
CriterionSatisfaction posterior = getNext(type, satisfaction, satisfactions); CriterionSatisfaction posterior = getNext(type, satisfaction, satisfactions);
return (previous == null || !previous.overlapsWith(interval)) && return (previous == null || !previous.overlapsWith(interval)) &&
( posterior == null || !posterior.overlapsWith(interval)); ( posterior == null || !posterior.overlapsWith(interval));
} }
public boolean _canAddSatisfaction( public boolean _canAddSatisfaction(
@ -638,7 +639,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
boolean canAdd = ((previousSameCriterion == null || boolean canAdd = ((previousSameCriterion == null ||
!previousSameCriterion.overlapsWith(interval)) && !previousSameCriterion.overlapsWith(interval)) &&
( posteriorSameCriterion == null || ( posteriorSameCriterion == null ||
!posteriorSameCriterion.overlapsWith(interval))); !posteriorSameCriterion.overlapsWith(interval)));
if(!canAdd) { if(!canAdd) {
return false; return false;
@ -657,14 +658,14 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public boolean canAddSatisfaction(ICriterionType<?> type, public boolean canAddSatisfaction(ICriterionType<?> type,
CriterionSatisfaction satisfaction) { CriterionSatisfaction satisfaction) {
EnsureSatisfactionIsCorrect ensureSatisfactionIsCorrect = new EnsureSatisfactionIsCorrect( EnsureSatisfactionIsCorrect ensureSatisfactionIsCorrect = new EnsureSatisfactionIsCorrect(
this, type, satisfaction); this, type, satisfaction);
return ensureSatisfactionIsCorrect.canAddSatisfaction(); return ensureSatisfactionIsCorrect.canAddSatisfaction();
} }
private CriterionSatisfaction getNext(ICriterionType<?> type, private CriterionSatisfaction getNext(ICriterionType<?> type,
CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) { CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) {
List<CriterionSatisfaction> ordered = query().from(type).result(list); List<CriterionSatisfaction> ordered = query().from(type).result(list);
int position = findPlace(ordered, newSatisfaction); int position = findPlace(ordered, newSatisfaction);
CriterionSatisfaction next = position != ordered.size() ? ordered CriterionSatisfaction next = position != ordered.size() ? ordered
@ -673,7 +674,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
private CriterionSatisfaction getPrevious(ICriterionType<?> type, private CriterionSatisfaction getPrevious(ICriterionType<?> type,
CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) { CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) {
List<CriterionSatisfaction> ordered = query().from(type).result(list); List<CriterionSatisfaction> ordered = query().from(type).result(list);
int position = findPlace(ordered, newSatisfaction); int position = findPlace(ordered, newSatisfaction);
CriterionSatisfaction previous = position > 0 ? ordered CriterionSatisfaction previous = position > 0 ? ordered
@ -683,7 +684,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
private CriterionSatisfaction getNextSameCriterion(Criterion criterion, private CriterionSatisfaction getNextSameCriterion(Criterion criterion,
CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) { CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) {
List<CriterionSatisfaction> ordered = query().from(criterion).result(list); List<CriterionSatisfaction> ordered = query().from(criterion).result(list);
int position = findPlace(ordered, newSatisfaction); int position = findPlace(ordered, newSatisfaction);
CriterionSatisfaction next = position != ordered.size() ? ordered CriterionSatisfaction next = position != ordered.size() ? ordered
@ -692,7 +693,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
private CriterionSatisfaction getPreviousSameCriterion(Criterion criterion, private CriterionSatisfaction getPreviousSameCriterion(Criterion criterion,
CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) { CriterionSatisfaction newSatisfaction,Set<CriterionSatisfaction> list) {
List<CriterionSatisfaction> ordered = query().from(criterion).result(list); List<CriterionSatisfaction> ordered = query().from(criterion).result(list);
int position = findPlace(ordered, newSatisfaction); int position = findPlace(ordered, newSatisfaction);
CriterionSatisfaction previous = position > 0 ? ordered CriterionSatisfaction previous = position > 0 ? ordered
@ -753,7 +754,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
* @throws IllegalArgumentException in case of overlapping * @throws IllegalArgumentException in case of overlapping
*/ */
private void checkNotOverlaps(CriterionSatisfaction before, private void checkNotOverlaps(CriterionSatisfaction before,
CriterionSatisfaction after) { CriterionSatisfaction after) {
CriterionType criterionType = before.getCriterion().getType(); CriterionType criterionType = before.getCriterion().getType();
@ -763,10 +764,10 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
* criterion satisfactions per resource). * criterion satisfactions per resource).
*/ */
if (before.getCriterion().equals(after.getCriterion()) && if (before.getCriterion().equals(after.getCriterion()) &&
!before.goesBeforeWithoutOverlapping(after)) { !before.goesBeforeWithoutOverlapping(after)) {
throw new IllegalArgumentException(createOverlapsMessage(before, throw new IllegalArgumentException(createOverlapsMessage(before,
after)); after));
} }
/* /*
* If CriterionType does not allow simultaneous criterion satisfactions * If CriterionType does not allow simultaneous criterion satisfactions
@ -774,7 +775,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
* of they refer to different Criterion objects). * of they refer to different Criterion objects).
*/ */
if (!criterionType.isAllowSimultaneousCriterionsPerResource() && if (!criterionType.isAllowSimultaneousCriterionsPerResource() &&
!before.goesBeforeWithoutOverlapping(after)) { !before.goesBeforeWithoutOverlapping(after)) {
throw new IllegalArgumentException(createOverlapsMessage(before, throw new IllegalArgumentException(createOverlapsMessage(before,
after)); after));
} }
@ -782,7 +783,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
private String createOverlapsMessage(CriterionSatisfaction before, private String createOverlapsMessage(CriterionSatisfaction before,
CriterionSatisfaction after) { CriterionSatisfaction after) {
return new StringBuilder("the satisfaction").append(before).append( return new StringBuilder("the satisfaction").append(before).append(
"overlaps with").append(after).toString(); "overlaps with").append(after).toString();
} }
@ -824,13 +825,13 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public void setResourceCalendar(String calendarCode) public void setResourceCalendar(String calendarCode)
throws InstanceNotFoundException, MultipleInstancesException { throws InstanceNotFoundException, MultipleInstancesException {
ResourceCalendar calendar; ResourceCalendar calendar;
if (StringUtils.isBlank(calendarCode)) { if (StringUtils.isBlank(calendarCode)) {
calendar = Registry.getConfigurationDAO().getConfiguration(). calendar = Registry.getConfigurationDAO().getConfiguration().
getDefaultCalendar().newDerivedResourceCalendar(); getDefaultCalendar().newDerivedResourceCalendar();
} else { } else {
BaseCalendar baseCalendar = Registry.getBaseCalendarDAO() BaseCalendar baseCalendar = Registry.getBaseCalendarDAO()
@ -886,19 +887,19 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public int getTotalWorkHours(LocalDate start, LocalDate endExclusive, public int getTotalWorkHours(LocalDate start, LocalDate endExclusive,
ICriterion criterion) { ICriterion criterion) {
return getTotalEffortFor(IntraDayDate.startOfDay(start), return getTotalEffortFor(IntraDayDate.startOfDay(start),
IntraDayDate.startOfDay(endExclusive), criterion) IntraDayDate.startOfDay(endExclusive), criterion)
.roundToHours(); .roundToHours();
} }
public EffortDuration getTotalEffortFor(IntraDayDate startInclusive, public EffortDuration getTotalEffortFor(IntraDayDate startInclusive,
IntraDayDate endExclusive) { IntraDayDate endExclusive) {
return getTotalEffortFor(startInclusive, endExclusive, null); return getTotalEffortFor(startInclusive, endExclusive, null);
} }
public EffortDuration getTotalEffortFor(IntraDayDate startInclusive, public EffortDuration getTotalEffortFor(IntraDayDate startInclusive,
IntraDayDate endExclusive, ICriterion criterion) { IntraDayDate endExclusive, ICriterion criterion) {
return getTotalEffortFor(getCalendarOrDefault(), startInclusive, return getTotalEffortFor(getCalendarOrDefault(), startInclusive,
endExclusive, criterion); endExclusive, criterion);
} }
@ -909,8 +910,8 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
private EffortDuration getTotalEffortFor(final ICalendar calendar, private EffortDuration getTotalEffortFor(final ICalendar calendar,
IntraDayDate startInclusive, IntraDayDate endExclusive, IntraDayDate startInclusive, IntraDayDate endExclusive,
final ICriterion criterionToSatisfy) { final ICriterion criterionToSatisfy) {
Iterable<PartialDay> daysBetween = startInclusive Iterable<PartialDay> daysBetween = startInclusive
.daysUntil(endExclusive); .daysUntil(endExclusive);
@ -923,7 +924,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
.getCapacityOn(current); .getCapacityOn(current);
if (capacityCurrent != null if (capacityCurrent != null
&& (criterionToSatisfy == null || satisfiesCriterionAt( && (criterionToSatisfy == null || satisfiesCriterionAt(
criterionToSatisfy, current.getDate()))) { criterionToSatisfy, current.getDate()))) {
return capacityCurrent; return capacityCurrent;
} }
return zero(); return zero();
@ -932,12 +933,12 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
private boolean satisfiesCriterionAt(ICriterion criterionToSatisfy, private boolean satisfiesCriterionAt(ICriterion criterionToSatisfy,
LocalDate current) { LocalDate current) {
return criterionToSatisfy.isSatisfiedBy(this, current); return criterionToSatisfy.isSatisfiedBy(this, current);
} }
public void addUnvalidatedSatisfaction(CriterionSatisfaction public void addUnvalidatedSatisfaction(CriterionSatisfaction
criterionSatisfaction) { criterionSatisfaction) {
criterionSatisfactions.add(criterionSatisfaction); criterionSatisfactions.add(criterionSatisfaction);
@ -975,7 +976,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
private void validateSatisfaction(CriterionSatisfaction satisfaction, Set<CriterionSatisfaction> satisfactions) private void validateSatisfaction(CriterionSatisfaction satisfaction, Set<CriterionSatisfaction> satisfactions)
throws ValidationException { throws ValidationException {
if ( !canAddSatisfaction(satisfaction, satisfactions) ) { if ( !canAddSatisfaction(satisfaction, satisfactions) ) {
String message = getReasonForNotAddingSatisfaction(satisfaction.getCriterion().getType()); String message = getReasonForNotAddingSatisfaction(satisfaction.getCriterion().getType());
@ -1004,16 +1005,16 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public ResourcesCostCategoryAssignment public ResourcesCostCategoryAssignment
getResourcesCostCategoryAssignmentByCode(String code) getResourcesCostCategoryAssignmentByCode(String code)
throws InstanceNotFoundException { throws InstanceNotFoundException {
if (StringUtils.isBlank(code)) { if (StringUtils.isBlank(code)) {
throw new InstanceNotFoundException(code, throw new InstanceNotFoundException(code,
ResourcesCostCategoryAssignment.class.getName()); ResourcesCostCategoryAssignment.class.getName());
} }
for (ResourcesCostCategoryAssignment i : for (ResourcesCostCategoryAssignment i :
resourcesCostCategoryAssignments) { resourcesCostCategoryAssignments) {
if (i.getCode().equalsIgnoreCase(StringUtils.trim(code))) { if (i.getCode().equalsIgnoreCase(StringUtils.trim(code))) {
return i; return i;
@ -1022,7 +1023,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
throw new InstanceNotFoundException(code, throw new InstanceNotFoundException(code,
ResourcesCostCategoryAssignment.class.getName()); ResourcesCostCategoryAssignment.class.getName());
} }
@ -1034,7 +1035,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
public void addUnvalidatedResourcesCostCategoryAssignment( public void addUnvalidatedResourcesCostCategoryAssignment(
ResourcesCostCategoryAssignment assignment) { ResourcesCostCategoryAssignment assignment) {
resourcesCostCategoryAssignments.add(assignment); resourcesCostCategoryAssignments.add(assignment);
@ -1093,7 +1094,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
* Check assignment overlapping. * Check assignment overlapping.
*/ */
List<ResourcesCostCategoryAssignment> assignmentsList = List<ResourcesCostCategoryAssignment> assignmentsList =
new ArrayList<ResourcesCostCategoryAssignment>(); new ArrayList<ResourcesCostCategoryAssignment>();
assignmentsList.addAll(getResourcesCostCategoryAssignments()); assignmentsList.addAll(getResourcesCostCategoryAssignments());
try { try {
@ -1112,7 +1113,7 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
@AssertTrue(message="there exist criterion satisfactions referring to " + @AssertTrue(message="there exist criterion satisfactions referring to " +
"criterion types not applicable to this resource") "criterion types not applicable to this resource")
public boolean isCriterionSatisfactionsWithCorrectTypeConstraint() { public boolean isCriterionSatisfactionsWithCorrectTypeConstraint() {
for (CriterionSatisfaction c : getCriterionSatisfactions()) { for (CriterionSatisfaction c : getCriterionSatisfactions()) {
@ -1126,13 +1127,13 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
} }
@AssertTrue(message="criterion satisfaction codes must be unique inside " + @AssertTrue(message="criterion satisfaction codes must be unique inside " +
"a resource") "a resource")
public boolean isNonRepeatedCriterionSatisfactionCodesConstraint() { public boolean isNonRepeatedCriterionSatisfactionCodesConstraint() {
return getFirstRepeatedCode(criterionSatisfactions) == null; return getFirstRepeatedCode(criterionSatisfactions) == null;
} }
@AssertTrue(message="resource cost category assignments codes must be " + @AssertTrue(message="resource cost category assignments codes must be " +
"unique inside a resource") "unique inside a resource")
public boolean isNonRepeatedResourcesCostCategoryAssignmentCodesConstraint() { public boolean isNonRepeatedResourcesCostCategoryAssignmentCodesConstraint() {
return getFirstRepeatedCode(resourcesCostCategoryAssignments) == null; return getFirstRepeatedCode(resourcesCostCategoryAssignments) == null;
} }
@ -1174,30 +1175,30 @@ public abstract class Resource extends IntegrationEntity implements IHumanIdenti
@AssertTrue(message = "You have exceeded the maximum limit of resources") @AssertTrue(message = "You have exceeded the maximum limit of resources")
public boolean isMaxResourcesConstraint() { public boolean isMaxResourcesConstraint() {
return Registry.getTransactionService().runOnAnotherReadOnlyTransaction(new IOnTransaction<Boolean>() { return Registry.getTransactionService().runOnAnotherReadOnlyTransaction(new IOnTransaction<Boolean>() {
@Override @Override
public Boolean execute() { public Boolean execute() {
Configuration configuration = Registry.getConfigurationDAO().getConfiguration(); Configuration configuration = Registry.getConfigurationDAO().getConfiguration();
if ( configuration == null ) { if ( configuration == null ) {
return true; return true;
} }
Integer maxResources = configuration.getMaxResources(); Integer maxResources = configuration.getMaxResources();
if ( maxResources != null && maxResources > 0 ) { if ( maxResources != null && maxResources > 0 ) {
List<Resource> resources = Registry.getResourceDAO().findAll(); List<Resource> resources = Registry.getResourceDAO().findAll();
int resourcesNumber = resources.size(); int resourcesNumber = resources.size();
if ( isNewObject() ) { if ( isNewObject() ) {
resourcesNumber++; resourcesNumber++;
}
if ( resourcesNumber > maxResources ) {
return false;
}
}
return true;
} }
});
if ( resourcesNumber > maxResources ) {
return false;
}
}
return true;
}
});
} }
public boolean isActiveBetween(LocalDate startDate, LocalDate endDate) { public boolean isActiveBetween(LocalDate startDate, LocalDate endDate) {

View file

@ -21,10 +21,7 @@
package org.libreplan.business.resources.entities; package org.libreplan.business.resources.entities;
/** /**
*
* @author Diego Pino Garcia<dpino@igalia.com> * @author Diego Pino Garcia<dpino@igalia.com>
*/ */
public enum ResourceEnum { public enum ResourceEnum {
@ -32,21 +29,22 @@ public enum ResourceEnum {
WORKER(Worker.class, _("WORKER")), WORKER(Worker.class, _("WORKER")),
MACHINE(Machine.class, _("MACHINE")); MACHINE(Machine.class, _("MACHINE"));
private Class<? extends Resource> klass;
private final String displayName;
ResourceEnum(Class<? extends Resource> klass, String displayName) {
this.klass = klass;
this.displayName = displayName;
}
/** /**
* Forces to mark the string as needing translation * Forces to mark the string as needing translation.
*/ */
private static String _(String string) { private static String _(String string) {
return string; return string;
} }
private Class<? extends Resource> klass;
private final String displayName;
private ResourceEnum(Class<? extends Resource> klass, String displayName) {
this.klass = klass;
this.displayName = displayName;
}
public Class<? extends Resource> asClass() { public Class<? extends Resource> asClass() {
return klass; return klass;
} }

View file

@ -52,14 +52,14 @@ public class Worker extends Resource {
} }
public static Worker create(String firstName, String surname, public static Worker create(String firstName, String surname,
String nif) { String nif) {
return create(new Worker(firstName, surname, nif)); return create(new Worker(firstName, surname, nif));
} }
public static Worker createUnvalidated(String code, String firstName, public static Worker createUnvalidated(String code, String firstName,
String surname, String nif) { String surname, String nif) {
Worker worker = create(new Worker(), code); Worker worker = create(new Worker(), code);
@ -110,6 +110,14 @@ public class Worker extends Resource {
this.nif = nif; this.nif = nif;
} }
/**
* This method is needed by autocomplete component on _machineConfigurationUnits.zul
*/
@Override
public String toString () {
return this.getName() + " - " + this.getNif();
}
public String getDescription() { public String getDescription() {
return getSurname() + "," + getFirstName(); return getSurname() + "," + getFirstName();
} }
@ -180,18 +188,18 @@ public class Worker extends Resource {
protected boolean areFirstNameSurnameNifSpecified() { protected boolean areFirstNameSurnameNifSpecified() {
return !StringUtils.isBlank(firstName) && return !StringUtils.isBlank(firstName) &&
!StringUtils.isBlank(surname) && !StringUtils.isBlank(surname) &&
!StringUtils.isBlank(nif); !StringUtils.isBlank(nif);
} }
@Override @Override
protected boolean isCriterionSatisfactionOfCorrectType( protected boolean isCriterionSatisfactionOfCorrectType(
CriterionSatisfaction c) { CriterionSatisfaction c) {
return c.getResourceType().equals(ResourceEnum.WORKER); return c.getResourceType().equals(ResourceEnum.WORKER);
} }
@Override @Override
public ResourceEnum getType() { public ResourceEnum getType() {

View file

@ -36,7 +36,7 @@ public enum PredefinedScenarios {
private final String name; private final String name;
private PredefinedScenarios(String name) { PredefinedScenarios(String name) {
this.name = name; this.name = name;
} }

View file

@ -26,6 +26,7 @@ import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.scenarios.daos.IScenarioDAO; import org.libreplan.business.scenarios.daos.IScenarioDAO;
import org.libreplan.business.scenarios.entities.Scenario; import org.libreplan.business.scenarios.entities.Scenario;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -36,7 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
@Component @Component
@Scope("singleton") @Scope(BeanDefinition.SCOPE_SINGLETON)
public class ScenariosBootstrap implements IScenariosBootstrap { public class ScenariosBootstrap implements IScenariosBootstrap {
@Autowired @Autowired
@ -50,16 +51,16 @@ public class ScenariosBootstrap implements IScenariosBootstrap {
@Override @Override
@Transactional @Transactional
public void loadRequiredData() { public void loadRequiredData() {
for (PredefinedScenarios predefinedScenario : PredefinedScenarios for (PredefinedScenarios predefinedScenario : PredefinedScenarios.values()) {
.values()) { if (!scenarioDAO.existsByNameAnotherTransaction(predefinedScenario.getName())) {
if (!scenarioDAO.existsByNameAnotherTransaction(predefinedScenario
.getName())) {
Scenario scenario = createAtDB(predefinedScenario); Scenario scenario = createAtDB(predefinedScenario);
if (predefinedScenario == PredefinedScenarios.MASTER) { if (predefinedScenario == PredefinedScenarios.MASTER) {
mainScenario = scenario; mainScenario = scenario;
} }
} }
} }
if (mainScenario == null) { if (mainScenario == null) {
mainScenario = PredefinedScenarios.MASTER.getScenario(); mainScenario = PredefinedScenarios.MASTER.getScenario();
} }
@ -67,11 +68,14 @@ public class ScenariosBootstrap implements IScenariosBootstrap {
private Scenario createAtDB(PredefinedScenarios predefinedScenario) { private Scenario createAtDB(PredefinedScenarios predefinedScenario) {
Scenario scenario = predefinedScenario.createScenario(); Scenario scenario = predefinedScenario.createScenario();
for (Order each : orderDAO.getOrders()) { for (Order each : orderDAO.getOrders()) {
scenario.addOrder(each); scenario.addOrder(each);
} }
scenarioDAO.save(scenario); scenarioDAO.save(scenario);
scenario.dontPoseAsTransientObjectAnymore(); scenario.dontPoseAsTransientObjectAnymore();
return scenario; return scenario;
} }

View file

@ -27,7 +27,6 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.GenericDAOHibernate; import org.libreplan.business.common.daos.GenericDAOHibernate;
import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.common.exceptions.InstanceNotFoundException;
@ -49,8 +48,7 @@ import org.springframework.transaction.annotation.Transactional;
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class ScenarioDAO extends GenericDAOHibernate<Scenario, Long> implements public class ScenarioDAO extends GenericDAOHibernate<Scenario, Long> implements IScenarioDAO {
IScenarioDAO {
@Autowired @Autowired
private IOrderVersionDAO orderVersionDAO; private IOrderVersionDAO orderVersionDAO;
@ -70,7 +68,7 @@ public class ScenarioDAO extends GenericDAOHibernate<Scenario, Long> implements
private List<OrderVersion> getNewOrders(Scenario scenario) { private List<OrderVersion> getNewOrders(Scenario scenario) {
Collection<OrderVersion> values = scenario.getOrders().values(); Collection<OrderVersion> values = scenario.getOrders().values();
List<OrderVersion> newOrders = new ArrayList<OrderVersion>(); List<OrderVersion> newOrders = new ArrayList<>();
for (OrderVersion each : values) { for (OrderVersion each : values) {
if (each.isNewObject()) { if (each.isNewObject()) {
newOrders.add(each); newOrders.add(each);
@ -86,9 +84,9 @@ public class ScenarioDAO extends GenericDAOHibernate<Scenario, Long> implements
throw new InstanceNotFoundException(null, Scenario.class.getName()); throw new InstanceNotFoundException(null, Scenario.class.getName());
} }
Scenario scenario = (Scenario) getSession().createCriteria( Scenario scenario = (Scenario) getSession()
Scenario.class).add( .createCriteria(Scenario.class)
Restrictions.eq("name", name.trim()).ignoreCase()) .add(Restrictions.eq("name", name.trim()).ignoreCase())
.uniqueResult(); .uniqueResult();
if (scenario == null) { if (scenario == null) {
@ -132,10 +130,7 @@ public class ScenarioDAO extends GenericDAOHibernate<Scenario, Long> implements
} }
private boolean areDifferentInDB(Scenario one, Scenario other) { private boolean areDifferentInDB(Scenario one, Scenario other) {
if ((one.getId() == null) || (other.getId() == null)) { return (one.getId() == null) || (other.getId() == null) || !one.getId().equals(other.getId());
return true;
}
return !one.getId().equals(other.getId());
} }
@Override @Override
@ -144,14 +139,15 @@ public class ScenarioDAO extends GenericDAOHibernate<Scenario, Long> implements
return Collections.emptyList(); return Collections.emptyList();
} }
Criteria c = getSession().createCriteria(Scenario.class).add( return getSession()
Restrictions.eq("predecessor", scenario)); .createCriteria(Scenario.class)
return (List<Scenario>) c.list(); .add(Restrictions.eq("predecessor", scenario))
.list();
} }
@Override @Override
public List<Scenario> getDerivedScenarios(Scenario scenario) { public List<Scenario> getDerivedScenarios(Scenario scenario) {
List<Scenario> result = new ArrayList<Scenario>(); List<Scenario> result = new ArrayList<>();
List<Scenario> children = findByPredecessor(scenario); List<Scenario> children = findByPredecessor(scenario);
result.addAll(children); result.addAll(children);
@ -165,8 +161,11 @@ public class ScenarioDAO extends GenericDAOHibernate<Scenario, Long> implements
@Override @Override
public void updateDerivedScenariosWithNewVersion( public void updateDerivedScenariosWithNewVersion(
OrderVersion previousOrderVersion, Order order, OrderVersion previousOrderVersion,
Scenario currentScenario, OrderVersion newOrderVersion) { Order order,
Scenario currentScenario,
OrderVersion newOrderVersion) {
for (Scenario each : getDerivedScenarios(currentScenario)) { for (Scenario each : getDerivedScenarios(currentScenario)) {
if (each.usesVersion(previousOrderVersion, order)) { if (each.usesVersion(previousOrderVersion, order)) {
if (newOrderVersion == null) { if (newOrderVersion == null) {

View file

@ -44,8 +44,8 @@ import org.libreplan.business.trees.ITreeParentNode;
public class OrderLineGroupTemplate extends OrderElementTemplate implements public class OrderLineGroupTemplate extends OrderElementTemplate implements
ITreeParentNode<OrderElementTemplate> { ITreeParentNode<OrderElementTemplate> {
private final CriterionRequirementTemplateHandler criterionRequirementTemplateHandler = CriterionRequirementTemplateHandler private final CriterionRequirementTemplateHandler criterionRequirementTemplateHandler =
.getInstance(); CriterionRequirementTemplateHandler.getInstance();
private final class ChildrenManipulator extends private final class ChildrenManipulator extends
TreeNodeOnListWithSchedulingState<OrderElementTemplate> { TreeNodeOnListWithSchedulingState<OrderElementTemplate> {
@ -121,7 +121,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
} }
protected static <T extends OrderLineGroupTemplate> T create(T beingBuilt, protected static <T extends OrderLineGroupTemplate> T create(T beingBuilt,
OrderLineGroup group) { OrderLineGroup group) {
OrderElementTemplate.create(beingBuilt, group); OrderElementTemplate.create(beingBuilt, group);
List<OrderElementTemplate> result = buildChildrenTemplates(beingBuilt, List<OrderElementTemplate> result = buildChildrenTemplates(beingBuilt,
group.getChildren()); group.getChildren());
@ -165,7 +165,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
private static List<OrderElementTemplate> buildChildrenTemplates( private static List<OrderElementTemplate> buildChildrenTemplates(
OrderLineGroupTemplate parent, List<OrderElement> children) { OrderLineGroupTemplate parent, List<OrderElement> children) {
List<OrderElementTemplate> result = new ArrayList<OrderElementTemplate>(); List<OrderElementTemplate> result = new ArrayList<>();
for (OrderElement each : children) { for (OrderElement each : children) {
OrderElementTemplate template = each.createTemplate(); OrderElementTemplate template = each.createTemplate();
template.setParent(parent); template.setParent(parent);
@ -174,7 +174,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
return result; return result;
} }
private List<OrderElementTemplate> children = new ArrayList<OrderElementTemplate>(); private List<OrderElementTemplate> children = new ArrayList<>();
@Override @Override
public List<OrderElementTemplate> getChildrenTemplates() { public List<OrderElementTemplate> getChildrenTemplates() {
@ -207,7 +207,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
@Override @Override
public void replace(OrderElementTemplate previousChild, public void replace(OrderElementTemplate previousChild,
OrderElementTemplate newChild) { OrderElementTemplate newChild) {
getManipulator().replace(previousChild, newChild); getManipulator().replace(previousChild, newChild);
} }

View file

@ -46,23 +46,26 @@ import org.libreplan.business.orders.entities.OrderLineGroup;
public class OrderLineTemplate extends OrderElementTemplate { public class OrderLineTemplate extends OrderElementTemplate {
@Valid @Valid
private Set<HoursGroup> hoursGroups = new HashSet<HoursGroup>(); private Set<HoursGroup> hoursGroups = new HashSet<>();
private Integer lastHoursGroupSequenceCode = 0; private Integer lastHoursGroupSequenceCode = 0;
private BigDecimal budget = BigDecimal.ZERO.setScale(2);
private HoursGroupOrderLineTemplateHandler hoursGroupOrderLineTemplateHandler =
HoursGroupOrderLineTemplateHandler.getInstance();
public static OrderLineTemplate create(OrderLine orderLine) { public static OrderLineTemplate create(OrderLine orderLine) {
OrderLineTemplate beingBuilt = new OrderLineTemplate(); OrderLineTemplate beingBuilt = new OrderLineTemplate();
copyHoursGroup(orderLine.getHoursGroups(), beingBuilt); copyHoursGroup(orderLine.getHoursGroups(), beingBuilt);
beingBuilt.setBudget(orderLine.getBudget()); beingBuilt.setBudget(orderLine.getBudget());
return create(beingBuilt, orderLine); return create(beingBuilt, orderLine);
} }
private static void copyHoursGroup( private static void copyHoursGroup(final Collection<HoursGroup> hoursGroups, OrderLineTemplate orderLineTemplate) {
final Collection<HoursGroup> hoursGroups,
OrderLineTemplate orderLineTemplate) {
for (HoursGroup each: hoursGroups) { for (HoursGroup each: hoursGroups) {
orderLineTemplate.addHoursGroup(HoursGroup.copyFrom(each, orderLineTemplate.addHoursGroup(HoursGroup.copyFrom(each, orderLineTemplate));
orderLineTemplate));
} }
} }
@ -70,17 +73,16 @@ public class OrderLineTemplate extends OrderElementTemplate {
return createNew(new OrderLineTemplate()); return createNew(new OrderLineTemplate());
} }
private BigDecimal budget = BigDecimal.ZERO.setScale(2);
protected <T extends OrderElement> T setupElementParts(T orderElement) { protected <T extends OrderElement> T setupElementParts(T orderElement) {
super.setupElementParts(orderElement); super.setupElementParts(orderElement);
setupHoursGroups((OrderLine) orderElement); setupHoursGroups((OrderLine) orderElement);
setupBudget((OrderLine) orderElement); setupBudget((OrderLine) orderElement);
return orderElement; return orderElement;
} }
private void setupHoursGroups(OrderLine orderLine) { private void setupHoursGroups(OrderLine orderLine) {
Set<HoursGroup> result = new HashSet<HoursGroup>(); Set<HoursGroup> result = new HashSet<>();
for (HoursGroup each: getHoursGroups()) { for (HoursGroup each: getHoursGroups()) {
result.add(HoursGroup.copyFrom(each, orderLine)); result.add(HoursGroup.copyFrom(each, orderLine));
} }
@ -105,12 +107,13 @@ public class OrderLineTemplate extends OrderElementTemplate {
public OrderLineGroupTemplate toContainer() { public OrderLineGroupTemplate toContainer() {
OrderLineGroupTemplate result = OrderLineGroupTemplate.createNew(); OrderLineGroupTemplate result = OrderLineGroupTemplate.createNew();
copyTo(result); copyTo(result);
return result; return result;
} }
@Override @Override
public List<OrderElementTemplate> getChildren() { public List<OrderElementTemplate> getChildren() {
return new ArrayList<OrderElementTemplate>(); return new ArrayList<>();
} }
@Override @Override
@ -123,18 +126,23 @@ public class OrderLineTemplate extends OrderElementTemplate {
if (getWorkHours() != 0) { if (getWorkHours() != 0) {
return false; return false;
} }
if (!getDirectCriterionRequirements().isEmpty()) { if (!getDirectCriterionRequirements().isEmpty()) {
return false; return false;
} }
if (!getAdvanceAssignmentTemplates().isEmpty()) { if (!getAdvanceAssignmentTemplates().isEmpty()) {
return false; return false;
} }
if (!getQualityForms().isEmpty()) { if (!getQualityForms().isEmpty()) {
return false; return false;
} }
if (!getLabels().isEmpty()) { if (!getLabels().isEmpty()) {
return false; return false;
} }
if (!getMaterialAssignments().isEmpty()) { if (!getMaterialAssignments().isEmpty()) {
return false; return false;
} }
@ -144,10 +152,12 @@ public class OrderLineTemplate extends OrderElementTemplate {
@Override @Override
public OrderElement createElement(OrderLineGroup parent) { public OrderElement createElement(OrderLineGroup parent) {
OrderLine line = setupSchedulingStateType(setupVersioningInfo(parent, OrderLine line = setupSchedulingStateType(
OrderLine.createOrderLineWithUnfixedPercentage(getWorkHours()))); setupVersioningInfo(parent, OrderLine.createOrderLineWithUnfixedPercentage(getWorkHours())));
line.initializeTemplate(this); line.initializeTemplate(this);
parent.add(line); parent.add(line);
return setupElementParts(line); return setupElementParts(line);
} }
@ -161,7 +171,7 @@ public class OrderLineTemplate extends OrderElementTemplate {
} }
public void incrementLastHoursGroupSequenceCode() { public void incrementLastHoursGroupSequenceCode() {
if(lastHoursGroupSequenceCode==null){ if (lastHoursGroupSequenceCode == null) {
lastHoursGroupSequenceCode = 0; lastHoursGroupSequenceCode = 0;
} }
lastHoursGroupSequenceCode++; lastHoursGroupSequenceCode++;
@ -178,7 +188,7 @@ public class OrderLineTemplate extends OrderElementTemplate {
@Override @Override
public List<HoursGroup> getHoursGroups() { public List<HoursGroup> getHoursGroups() {
return new ArrayList<HoursGroup>(hoursGroups); return new ArrayList<>(hoursGroups);
} }
public Set<HoursGroup> myHoursGroups() { public Set<HoursGroup> myHoursGroups() {
@ -206,9 +216,6 @@ public class OrderLineTemplate extends OrderElementTemplate {
recalculateHoursGroups(); recalculateHoursGroups();
} }
private HoursGroupOrderLineTemplateHandler hoursGroupOrderLineTemplateHandler = HoursGroupOrderLineTemplateHandler
.getInstance();
public void setWorkHours(Integer workHours) throws IllegalArgumentException { public void setWorkHours(Integer workHours) throws IllegalArgumentException {
hoursGroupOrderLineTemplateHandler.setWorkHours(this, workHours); hoursGroupOrderLineTemplateHandler.setWorkHours(this, workHours);
} }
@ -226,8 +233,7 @@ public class OrderLineTemplate extends OrderElementTemplate {
} }
public void setBudget(BigDecimal budget) { public void setBudget(BigDecimal budget) {
Validate.isTrue(budget.compareTo(BigDecimal.ZERO) >= 0, Validate.isTrue(budget.compareTo(BigDecimal.ZERO) >= 0, "budget cannot be negative");
"budget cannot be negative");
this.budget = budget.setScale(2); this.budget = budget.setScale(2);
} }

View file

@ -36,14 +36,15 @@ import org.libreplan.business.scenarios.entities.Scenario;
*/ */
public class OrderTemplate extends OrderLineGroupTemplate { public class OrderTemplate extends OrderLineGroupTemplate {
private BaseCalendar calendar;
public static OrderTemplate create(Order order) { public static OrderTemplate create(Order order) {
OrderTemplate beingBuilt = new OrderTemplate(); OrderTemplate beingBuilt = new OrderTemplate();
beingBuilt.calendar = order.getCalendar(); beingBuilt.calendar = order.getCalendar();
return create(beingBuilt, order); return create(beingBuilt, order);
} }
private BaseCalendar calendar;
@Override @Override
public OrderElement createElement(OrderLineGroup parent) { public OrderElement createElement(OrderLineGroup parent) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@ -51,11 +52,11 @@ public class OrderTemplate extends OrderLineGroupTemplate {
public Order createOrder(Scenario currentScenario) { public Order createOrder(Scenario currentScenario) {
Order order = Order.create(); Order order = Order.create();
order.setVersionForScenario(currentScenario, OrderVersion order.setVersionForScenario(currentScenario, OrderVersion.createInitialVersion(currentScenario));
.createInitialVersion(currentScenario));
order.useSchedulingDataFor(currentScenario); order.useSchedulingDataFor(currentScenario);
order.setCalendar(calendar); order.setCalendar(calendar);
order.initializeTemplate(this); order.initializeTemplate(this);
return setupGroupParts(setupSchedulingStateType(order)); return setupGroupParts(setupSchedulingStateType(order));
} }

View file

@ -31,7 +31,7 @@ import static org.libreplan.business.users.entities.UserRole.*;
* Profiles} * Profiles}
* *
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public enum PredefinedProfiles { public enum PredefinedProfiles {

Some files were not shown because too many files have changed in this diff Show more