Merge pull request #44 from dgray16/master

Update MPXJ library + changes to Project Import.
This commit is contained in:
Jeroen Baten 2016-02-23 15:58:00 +01:00
commit f853d889ca
17 changed files with 270 additions and 321 deletions

View file

@ -120,7 +120,7 @@ Instructions depending on the distribution:
Microsoft Windows Microsoft Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In development...
RPM Packages RPM Packages
~~~~~~~~~~~~ ~~~~~~~~~~~~

View file

@ -206,8 +206,7 @@ public class FunctionalityExposedForExtensions<T> implements IContext<T> {
* @param parent * @param parent
* @return * @return
*/ */
private Task buildAndRegister(Position position, private Task buildAndRegister(Position position, List<DomainDependency<T>> accumulatedDependencies, T data) {
List<DomainDependency<T>> accumulatedDependencies, T data) {
accumulatedDependencies.addAll(adapter.getOutcomingDependencies(data)); accumulatedDependencies.addAll(adapter.getOutcomingDependencies(data));
accumulatedDependencies.addAll(adapter.getIncomingDependencies(data)); accumulatedDependencies.addAll(adapter.getIncomingDependencies(data));
@ -236,13 +235,12 @@ public class FunctionalityExposedForExtensions<T> implements IContext<T> {
private Task build(T data) { private Task build(T data) {
ITaskFundamentalProperties adapted = adapter.adapt(data); ITaskFundamentalProperties adapted = adapter.adapt(data);
if (navigator.isMilestone(data)) { if ( navigator.isMilestone(data) ) {
return new Milestone(adapted); return new Milestone(adapted);
} else if (navigator.isLeaf(data)) { } else if ( navigator.isLeaf(data) ) {
return new TaskLeaf(adapted); return new TaskLeaf(adapted);
} else { } else {
return new TaskContainer(adapted, return new TaskContainer(adapted, planner.areContainersExpandedByDefault());
planner.areContainersExpandedByDefault());
} }
} }

View file

@ -69,7 +69,9 @@ public class LeftTasksTree extends HtmlMacroComponent {
public void render(final Treeitem item, Object data) throws Exception { public void render(final Treeitem item, Object data) throws Exception {
Task task = (Task) data; Task task = (Task) data;
item.setOpen(isOpened(task)); item.setOpen(isOpened(task));
if (task instanceof TaskContainer) {
if ( task instanceof TaskContainer ) {
final TaskContainer container = (TaskContainer) task; final TaskContainer container = (TaskContainer) task;
IExpandListener expandListener = new IExpandListener() { IExpandListener expandListener = new IExpandListener() {
@ -82,14 +84,13 @@ public class LeftTasksTree extends HtmlMacroComponent {
container.addExpandListener(expandListener); container.addExpandListener(expandListener);
} }
LeftTasksTreeRow leftTasksTreeRow = LeftTasksTreeRow.create( LeftTasksTreeRow leftTasksTreeRow = LeftTasksTreeRow
disabilityConfiguration, task, new TreeNavigator( .create(disabilityConfiguration, task, new TreeNavigator(tasksTreeModel, task), planner);
tasksTreeModel, task), planner); if ( task.isContainer() ) {
if (task.isContainer()) {
expandWhenOpened((TaskContainer) task, item); expandWhenOpened((TaskContainer) task, item);
} }
Component row; Component row;
if (disabilityConfiguration.isTreeEditable()) { if ( disabilityConfiguration.isTreeEditable() ) {
row = Executions.getCurrent().createComponents( row = Executions.getCurrent().createComponents(
"~./ganttz/zul/leftTasksTreeRow.zul", item, null); "~./ganttz/zul/leftTasksTreeRow.zul", item, null);
} else { } else {
@ -97,15 +98,11 @@ public class LeftTasksTree extends HtmlMacroComponent {
"~./ganttz/zul/leftTasksTreeRowLabels.zul", item, null); "~./ganttz/zul/leftTasksTreeRowLabels.zul", item, null);
} }
leftTasksTreeRow.doAfterCompose(row); leftTasksTreeRow.doAfterCompose(row);
List<Object> rowChildren = row.getChildren();
List<Treecell> treeCells = ComponentsFinder.findComponentsOfType(
Treecell.class, rowChildren);
detailsForBeans.put(task, leftTasksTreeRow); detailsForBeans.put(task, leftTasksTreeRow);
deferredFiller.isBeingRendered(task, item); deferredFiller.isBeingRendered(task, item);
} }
private void expandWhenOpened(final TaskContainer taskBean, private void expandWhenOpened(final TaskContainer taskBean, Treeitem item) {
Treeitem item) {
item.addEventListener("onOpen", new EventListener() { item.addEventListener("onOpen", new EventListener() {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {

View file

@ -251,14 +251,13 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
findComponents((Treerow) component); findComponents((Treerow) component);
registerTextboxesListeners(); registerTextboxesListeners();
updateComponents(); updateComponents();
task task.addFundamentalPropertiesChangeListener(new PropertyChangeListener() {
.addFundamentalPropertiesChangeListener(new PropertyChangeListener() { @Override
public void propertyChange(PropertyChangeEvent evt) {
updateComponents();
}
});
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateComponents();
}
});
} }
private void registerTextboxesListeners() { private void registerTextboxesListeners() {
@ -274,9 +273,6 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
} }
} }
public void registerDateboxListeners(Datebox datebox) {
}
private void findComponents(Treerow row) { private void findComponents(Treerow row) {
List<Object> rowChildren = row.getChildren(); List<Object> rowChildren = row.getChildren();
List<Treecell> treeCells = ComponentsFinder.findComponentsOfType(Treecell.class, List<Treecell> treeCells = ComponentsFinder.findComponentsOfType(Treecell.class,

View file

@ -63,8 +63,7 @@ import org.zkoss.ganttz.util.ReentranceGuard.IReentranceCases;
* dependencies and in the duration of the tasks using listeners. <br/> * dependencies and in the duration of the tasks using listeners. <br/>
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*/ */
public class GanttDiagramGraph<V, D extends IDependency<V>> implements public class GanttDiagramGraph<V, D extends IDependency<V>> implements ICriticalPathCalculable<V> {
ICriticalPathCalculable<V> {
private static final Log LOG = LogFactory.getLog(GanttDiagramGraph.class); private static final Log LOG = LogFactory.getLog(GanttDiagramGraph.class);
@ -582,8 +581,8 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
* <p> * <p>
* For example imagine a Gantt with three tasks: T1 -> T2 -> T3. Imagine * For example imagine a Gantt with three tasks: T1 -> T2 -> T3. Imagine
* that T1 position is modified due to being moved by the user. In that case * that T1 position is modified due to being moved by the user. In that case
* the scheduling algorithm triggers and the {@link Recalculation * the scheduling algorithm triggers and the {@link Recalculation}
* recalculations} needed are done. T2 position would be recalculated and T3 * recalculations needed are done. T2 position would be recalculated and T3
* position too. When the recalculation happens their dates are modified, * position too. When the recalculation happens their dates are modified,
* but in that case we don't want to trigger the dependencies enforcement * but in that case we don't want to trigger the dependencies enforcement
* algorithm again. What we want is to record the changes that have happened * algorithm again. What we want is to record the changes that have happened
@ -931,7 +930,7 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
} }
void enforceRestrictionsOn(final List<Recalculation> recalculations, void enforceRestrictionsOn(final List<Recalculation> recalculations,
final Collection<? extends V> initiallyModified) { final Collection<? extends V> initiallyModified) {
executeWithPreAndPostActionsOnlyIfNewEntrance(new IAction() { executeWithPreAndPostActionsOnlyIfNewEntrance(new IAction() {
@Override @Override
public void doAction() { public void doAction() {
@ -1027,12 +1026,12 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
} }
private void doRecalculations(List<Recalculation> recalculationsNeeded, private void doRecalculations(List<Recalculation> recalculationsNeeded,
Collection<? extends V> initiallyModified) { Collection<? extends V> initiallyModified) {
Set<V> allModified = new HashSet<V>(); Set<V> allModified = new HashSet<V>();
allModified.addAll(initiallyModified); allModified.addAll(initiallyModified);
for (Recalculation each : recalculationsNeeded) { for (Recalculation each : recalculationsNeeded) {
boolean modified = each.doRecalculation(); boolean modified = each.doRecalculation();
if (modified) { if ( modified ) {
allModified.add(each.taskPoint.task); allModified.add(each.taskPoint.task);
} }
} }
@ -1163,15 +1162,13 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
while (!pendingOfVisit.isEmpty()) { while (!pendingOfVisit.isEmpty()) {
Recalculation current = pendingOfVisit.poll(); Recalculation current = pendingOfVisit.poll();
for (TaskPoint each : current.taskPoint.getImmediateSuccessors()) { for (TaskPoint each : current.taskPoint.getImmediateSuccessors()) {
if (each.isImmediatelyDerivedFrom(current.taskPoint)) { if ( each.isImmediatelyDerivedFrom(current.taskPoint) ) {
continue; continue;
} }
Recalculation recalculationToAdd = getRecalcualtionToAdd(each, Recalculation recalculationToAdd = getRecalcualtionToAdd(each, alreadyVisited);
alreadyVisited);
recalculationToAdd.comesFromPredecessor(current); recalculationToAdd.comesFromPredecessor(current);
if (!alreadyVisited.containsKey(recalculationToAdd)) { if ( !alreadyVisited.containsKey(recalculationToAdd) ) {
result.addAll(getParentsRecalculations( result.addAll(getParentsRecalculations(parentRecalculationsAlreadyDone, each));
parentRecalculationsAlreadyDone, each));
result.add(recalculationToAdd); result.add(recalculationToAdd);
pendingOfVisit.offer(recalculationToAdd); pendingOfVisit.offer(recalculationToAdd);
alreadyVisited.put(recalculationToAdd, recalculationToAdd); alreadyVisited.put(recalculationToAdd, recalculationToAdd);
@ -1275,8 +1272,7 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
boolean doRecalculation() { boolean doRecalculation() {
recalculationCalled = true; recalculationCalled = true;
dataPointModified = haveToDoCalculation() dataPointModified = haveToDoCalculation() && taskChangesPosition();
&& taskChangesPosition();
return dataPointModified; return dataPointModified;
} }
@ -1287,12 +1283,11 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
private boolean predecessorsHaveBeenModified() { private boolean predecessorsHaveBeenModified() {
for (Recalculation each : recalculationsCouldAffectThis) { for (Recalculation each : recalculationsCouldAffectThis) {
if (!each.recalculationCalled) { if ( !each.recalculationCalled ) {
throw new RuntimeException( // FIXME this need to be not commented, but some imported projects not working with it
"the predecessor must be called first"); //throw new RuntimeException("the predecessor must be called first");
} }
if (each.dataPointModified if ( each.dataPointModified || each.couldHaveBeenModifiedBeforehand ) {
|| each.couldHaveBeenModifiedBeforehand) {
return true; return true;
} }
} }

View file

@ -45,8 +45,7 @@ import org.libreplan.business.util.deepcopy.Strategy;
*/ */
public class TaskSource extends BaseEntity { public class TaskSource extends BaseEntity {
public static TaskSource create(SchedulingDataForVersion schedulingState, public static TaskSource create(SchedulingDataForVersion schedulingState, List<HoursGroup> hoursGroups) {
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<HoursGroup>(hoursGroups));
return result; return result;
@ -336,8 +335,7 @@ public class TaskSource extends BaseEntity {
return create(new TaskSource(schedulingState)); return create(new TaskSource(schedulingState));
} }
public static TaskSource createForGroup( public static TaskSource createForGroup(SchedulingDataForVersion schedulingState) {
SchedulingDataForVersion schedulingState) {
return create(new TaskSource(schedulingState)); return create(new TaskSource(schedulingState));
} }

View file

@ -123,8 +123,8 @@ public class TaskGroup extends TaskElement {
setIntraDayEndDate(newPossibleEndDate); setIntraDayEndDate(newPossibleEndDate);
} }
IntraDayDate newPossibleStart = task.getIntraDayStartDate(); IntraDayDate newPossibleStart = task.getIntraDayStartDate();
if (getIntraDayStartDate() == null if ( getIntraDayStartDate() == null
|| getIntraDayStartDate().compareTo(newPossibleStart) > 0) { || getIntraDayStartDate().compareTo(newPossibleStart) > 0 ) {
setIntraDayStartDate(newPossibleStart); setIntraDayStartDate(newPossibleStart);
} }
} }

View file

@ -498,7 +498,7 @@
<!-- MPXJ Library --> <!-- MPXJ Library -->
<dependency> <dependency>
<groupId>net.sourceforge</groupId> <groupId>net.sf.mpxj</groupId>
<artifactId>mpxj</artifactId> <artifactId>mpxj</artifactId>
</dependency> </dependency>

View file

@ -96,7 +96,7 @@ public class CalendarImporterMPXJ implements ICalendarImporter {
// In case that orders are imported too // In case that orders are imported too
projectFile = reader.read(file); projectFile = reader.read(file);
return MPXJProjectFileConversor.convertCalendars(projectFile); return MPXJProjectFileConverter.convertCalendars(projectFile);
} catch (Exception e) { } catch (Exception e) {
@ -119,7 +119,7 @@ public class CalendarImporterMPXJ implements ICalendarImporter {
public OrderDTO getOrderDTO(String filename) { public OrderDTO getOrderDTO(String filename) {
try { try {
return MPXJProjectFileConversor.convert(projectFile, filename); return MPXJProjectFileConverter.convert(projectFile, filename);
} catch (Exception e) { } catch (Exception e) {

View file

@ -36,12 +36,13 @@ import net.sf.mpxj.ProjectCalendarDateRanges;
import net.sf.mpxj.ProjectCalendarException; import net.sf.mpxj.ProjectCalendarException;
import net.sf.mpxj.ProjectCalendarWeek; import net.sf.mpxj.ProjectCalendarWeek;
import net.sf.mpxj.ProjectFile; import net.sf.mpxj.ProjectFile;
import net.sf.mpxj.ProjectHeader; import net.sf.mpxj.ProjectProperties;
import net.sf.mpxj.Relation; import net.sf.mpxj.Relation;
import net.sf.mpxj.RelationType; import net.sf.mpxj.RelationType;
import net.sf.mpxj.Task; import net.sf.mpxj.Task;
import net.sf.mpxj.TimeUnit; import net.sf.mpxj.TimeUnit;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Period; import org.joda.time.Period;
@ -50,16 +51,15 @@ import org.libreplan.importers.CalendarDayHoursDTO.CalendarTypeDayDTO;
import org.libreplan.importers.DependencyDTO.TypeOfDependencyDTO; import org.libreplan.importers.DependencyDTO.TypeOfDependencyDTO;
/** /**
* Class that is a conversor from the MPXJ format File to {@link OrderDTO}. * Class that is a converter from the MPXJ format File to {@link OrderDTO}.
*
* At these moment it only converts the tasks and its subtasks with the dates.
* *
* @author Alba Carro Pérez <alba.carro@gmail.com> * @author Alba Carro Pérez <alba.carro@gmail.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* @todo It last relationships. resources, calendars, hours, etc. * @todo It last relationships. resources, calendars, hours, etc.
*/ */
public class MPXJProjectFileConversor { public class MPXJProjectFileConverter {
private static ProjectHeader header; private static ProjectProperties properties;
/** /**
* Map between the MPXJ Task and the OrderElemenDTO or MilestoneDTO that represent it. * Map between the MPXJ Task and the OrderElemenDTO or MilestoneDTO that represent it.
@ -79,19 +79,12 @@ public class MPXJProjectFileConversor {
*/ */
public static OrderDTO convert(ProjectFile file, String filename) { public static OrderDTO convert(ProjectFile file, String filename) {
OrderDTO importData; OrderDTO importData = null;
switch (file.getMppFileType()) { if ( FilenameUtils.getExtension(filename).equals("planner") )
case 0:
importData = getImportDataFromPlanner(file, filename); importData = getImportDataFromPlanner(file, filename);
break; else if ( FilenameUtils.getExtension(filename).equals("mpp") )
default:
importData = getImportDataFromMPP(file, filename); importData = getImportDataFromMPP(file, filename);
break;
}
return importData; return importData;
} }
@ -106,8 +99,8 @@ public class MPXJProjectFileConversor {
List<CalendarDTO> calendarDTOs = new ArrayList<CalendarDTO>(); List<CalendarDTO> calendarDTOs = new ArrayList<CalendarDTO>();
for (ProjectCalendar projectCalendar : file.getBaseCalendars()) { for (ProjectCalendar projectCalendar : file.getCalendars()) {
if (StringUtils.isBlank(projectCalendar.getName())) { if ( StringUtils.isBlank(projectCalendar.getName()) ) {
String name = "calendar-" + UUID.randomUUID(); String name = "calendar-" + UUID.randomUUID();
projectCalendar.setName(name); projectCalendar.setName(name);
} }
@ -137,9 +130,8 @@ public class MPXJProjectFileConversor {
if (projectCalendar.getName() != null if (projectCalendar.getName() != null
&& projectCalendar.getName().length() != 0) { && projectCalendar.getName().length() != 0) {
calendarDTOs.add(toCalendarDTO(projectCalendar)); calendarDTOs.add(toCalendarDTO(projectCalendar));
calendarDTOs.addAll(getDerivedCalendars(projectCalendar calendarDTOs.addAll(getDerivedCalendars(projectCalendar.getDerivedCalendars()));
.getDerivedCalendars()));
} }
} }
} }
@ -291,9 +283,7 @@ public class MPXJProjectFileConversor {
* boolean to express it is a working exception or not * boolean to express it is a working exception or not
* @return CalendarExceptionDTO with the calendar exceptions that we want to import. * @return CalendarExceptionDTO with the calendar exceptions that we want to import.
*/ */
private static CalendarExceptionDTO toCalendarExceptionDTO(Date fromDate, private static CalendarExceptionDTO toCalendarExceptionDTO(Date fromDate, int hours, int minutes, boolean working) {
int hours,
int minutes, boolean working) {
CalendarExceptionDTO calendarExceptionDTO = new CalendarExceptionDTO(); CalendarExceptionDTO calendarExceptionDTO = new CalendarExceptionDTO();
@ -330,10 +320,8 @@ public class MPXJProjectFileConversor {
Date endCalendarDate; Date endCalendarDate;
if (projectCalendar.getDateRange() == null) { if (projectCalendar.getDateRange() == null) {
startCalendarDate = projectCalendar.getParentFile() startCalendarDate = projectCalendar.getParentFile().getProjectProperties().getStartDate();
.getProjectHeader().getStartDate(); endCalendarDate = projectCalendar.getParentFile().getProjectProperties().getFinishDate();
endCalendarDate = projectCalendar.getParentFile()
.getProjectHeader().getFinishDate();
} else { } else {
startCalendarDate = projectCalendar.getDateRange().getStart(); startCalendarDate = projectCalendar.getDateRange().getStart();
@ -427,9 +415,8 @@ public class MPXJProjectFileConversor {
* ProjectCalendarWeek to extract data from. * ProjectCalendarWeek to extract data from.
* @return CalendarDataDTO with the calendar data that we want to import. * @return CalendarDataDTO with the calendar data that we want to import.
*/ */
private static CalendarWeekDTO toCalendarWeekDTO( private static CalendarWeekDTO toCalendarWeekDTO(Date parentStartDate, Date parentEndDate,
Date parentStartDate, ProjectCalendarWeek projectCalendarWeek) {
Date parentEndDate, ProjectCalendarWeek projectCalendarWeek) {
CalendarWeekDTO calendarDataDTO = new CalendarWeekDTO(); CalendarWeekDTO calendarDataDTO = new CalendarWeekDTO();
@ -489,21 +476,21 @@ Date parentStartDate,
private static CalendarTypeDayDTO toCalendarTypeDayDTO(DayType dayType) { private static CalendarTypeDayDTO toCalendarTypeDayDTO(DayType dayType) {
switch (dayType) { switch (dayType) {
case DEFAULT: case DEFAULT:
return CalendarTypeDayDTO.DEFAULT; return CalendarTypeDayDTO.DEFAULT;
case NON_WORKING: case NON_WORKING:
return CalendarTypeDayDTO.NOT_WORKING; return CalendarTypeDayDTO.NOT_WORKING;
case WORKING: case WORKING:
return CalendarTypeDayDTO.WORKING; return CalendarTypeDayDTO.WORKING;
default: default:
return null; return null;
} }
@ -568,8 +555,7 @@ Date parentStartDate,
* ProjectFile to extract data from. * ProjectFile to extract data from.
* @return ImportData with the data that we want to import. * @return ImportData with the data that we want to import.
*/ */
private static OrderDTO getImportDataFromPlanner(ProjectFile file, private static OrderDTO getImportDataFromPlanner(ProjectFile file, String filename) {
String filename) {
OrderDTO importData = new OrderDTO(); OrderDTO importData = new OrderDTO();
@ -578,9 +564,9 @@ Date parentStartDate,
importData.name = filename importData.name = filename
.substring(0, filename.length() - 8/* ".planner" */); .substring(0, filename.length() - 8/* ".planner" */);
header = file.getProjectHeader(); properties = file.getProjectProperties();
importData.startDate = header.getStartDate(); importData.startDate = properties.getStartDate();
importData.tasks = getImportTasks(file.getChildTasks()); importData.tasks = getImportTasks(file.getChildTasks());
@ -588,11 +574,11 @@ Date parentStartDate,
// MPXJ don't provide a deadline for the project so we take the finish // MPXJ don't provide a deadline for the project so we take the finish
// date // date
importData.deadline = header.getFinishDate(); importData.deadline = properties.getFinishDate();
importData.dependencies = createDependencies(); importData.dependencies = createDependencies();
importData.calendarName = file.getCalendar().getName(); importData.calendarName = file.getBaselineCalendar().getName();
return importData; return importData;
@ -630,8 +616,7 @@ Date parentStartDate,
dependencyDTO.origin = mapEntry.getValue(); dependencyDTO.origin = mapEntry.getValue();
dependencyDTO.destination = mapTask.get(successor dependencyDTO.destination = mapTask.get(successor.getTargetTask());
.getTargetTask());
dependencyDTO.type = toDependencyDTOType(successor dependencyDTO.type = toDependencyDTOType(successor
.getType()); .getType());
@ -663,25 +648,25 @@ Date parentStartDate,
switch (type) { switch (type) {
case FINISH_FINISH: case FINISH_FINISH:
return TypeOfDependencyDTO.END_END; return TypeOfDependencyDTO.END_END;
case FINISH_START: case FINISH_START:
return TypeOfDependencyDTO.END_START; return TypeOfDependencyDTO.END_START;
case START_FINISH: case START_FINISH:
return TypeOfDependencyDTO.START_END; return TypeOfDependencyDTO.START_END;
case START_START: case START_START:
return TypeOfDependencyDTO.START_START; return TypeOfDependencyDTO.START_START;
default: default:
return null; return null;
} }
} }
@ -696,31 +681,30 @@ Date parentStartDate,
* ProjectFile to extract data from. * ProjectFile to extract data from.
* @return ImportData with the data that we want to import. * @return ImportData with the data that we want to import.
*/ */
private static OrderDTO getImportDataFromMPP(ProjectFile file, private static OrderDTO getImportDataFromMPP(ProjectFile file, String filename) {
String filename) {
OrderDTO importData = new OrderDTO(); OrderDTO importData = new OrderDTO();
mapTask = new HashMap<Task, IHasTaskAssociated>(); mapTask = new HashMap<Task, IHasTaskAssociated>();
header = file.getProjectHeader(); properties = file.getProjectProperties();
importData.startDate = header.getStartDate(); importData.startDate = properties.getStartDate();
// MPXJ don't provide a deadline for the project so we take the finish // MPXJ don't provide a deadline for the project so we take the finish
// date // date
importData.deadline = header.getFinishDate(); importData.deadline = properties.getFinishDate();
for (Task task : file.getChildTasks()) { for (Task task : file.getChildTasks()) {
// Projects are represented as a level 0 task with all // Projects are represented as a level 0 task with all
// real task as its children. Ignore all other top level tasks. // real task as its children. Ignore all other top level tasks.
// See // See
// http://mpxj.sourceforge.net/faq.html#extra-tasks-and-resources // http://mpxj.sourceforge.net/faq.html#extra-tasks-and-resources
if (task.getChildTasks().size() != 0) { if ( task.getChildTasks().size() != 0 ) {
String name = task.getName(); String name = task.getName();
if (name != null) { if ( name != null ) {
importData.name = name; importData.name = name;
@ -733,10 +717,9 @@ Date parentStartDate,
importData.tasks = getImportTasks(task.getChildTasks()); importData.tasks = getImportTasks(task.getChildTasks());
importData.milestones = getImportMilestones(task importData.milestones = getImportMilestones(task.getChildTasks());
.getChildTasks());
importData.calendarName = file.getCalendar().getName(); importData.calendarName = file.getDefaultCalendar().getName();
break; break;
} }
@ -762,7 +745,7 @@ Date parentStartDate,
for (Task task : childTasks) { for (Task task : childTasks) {
if (task.getMilestone()) { if ( task.getMilestone() ) {
MilestoneDTO milestone = getMilestoneData(task); MilestoneDTO milestone = getMilestoneData(task);
@ -771,7 +754,6 @@ Date parentStartDate,
milestones.add(milestone); milestones.add(milestone);
} }
} }
return milestones; return milestones;
@ -810,15 +792,15 @@ Date parentStartDate,
* *
* @param duration * @param duration
* Duration to convert. * Duration to convert.
* @param header * @param properties
* ProjectHeader needed to convert * ProjectProperties needed to convert
* @return int Integer with the rounded duration in hours * @return int Integer with the rounded duration in hours
*/ */
private static int durationToIntHours(Duration duration, private static int durationToIntHours(Duration duration,
ProjectHeader header) { ProjectProperties properties) {
Duration durationInHours = duration Duration durationInHours = duration
.convertUnits(TimeUnit.HOURS, header); .convertUnits(TimeUnit.HOURS, properties);
return (int) Math.floor(durationInHours.getDuration()); return (int) Math.floor(durationInHours.getDuration());
} }
@ -837,16 +819,16 @@ Date parentStartDate,
for (Task task : tasks) { for (Task task : tasks) {
if (!task.getMilestone()) {
if ( !task.getMilestone() ) {
OrderElementDTO importTask = getTaskData(task); OrderElementDTO importTask = getTaskData(task);
importTask.children = getImportTasks(task.getChildTasks()); importTask.children = getImportTasks(task.getChildTasks());
importTask.milestones = getImportMilestones(task importTask.milestones = getImportMilestones(task.getChildTasks());
.getChildTasks());
// This is because in MPXJ only MPP9 files have this atribute. // This is because in MPXJ only MPP9 files have this atribute.
if (task.getCalendar() != null) { if ( task.getCalendar() != null ) {
importTask.calendarName = task.getCalendar().getName(); importTask.calendarName = task.getCalendar().getName();
@ -884,7 +866,7 @@ Date parentStartDate,
importTask.endDate = task.getFinish(); importTask.endDate = task.getFinish();
importTask.totalHours = durationToIntHours(task.getDuration(), header); importTask.totalHours = durationToIntHours(task.getDuration(), properties);
importTask.deadline = task.getDeadline(); importTask.deadline = task.getDeadline();
@ -918,70 +900,70 @@ Date parentStartDate,
switch (task.getConstraintType()) { switch (task.getConstraintType()) {
case AS_SOON_AS_POSSIBLE: case AS_SOON_AS_POSSIBLE:
constraint = ConstraintDTO.AS_SOON_AS_POSSIBLE; constraint = ConstraintDTO.AS_SOON_AS_POSSIBLE;
constraintDate = task.getConstraintDate(); constraintDate = task.getConstraintDate();
return; return;
case AS_LATE_AS_POSSIBLE: case AS_LATE_AS_POSSIBLE:
constraint = ConstraintDTO.AS_LATE_AS_POSSIBLE; constraint = ConstraintDTO.AS_LATE_AS_POSSIBLE;
constraintDate = task.getConstraintDate(); constraintDate = task.getConstraintDate();
return; return;
case MUST_START_ON: case MUST_START_ON:
constraint = ConstraintDTO.START_IN_FIXED_DATE; constraint = ConstraintDTO.START_IN_FIXED_DATE;
constraintDate = task.getConstraintDate(); constraintDate = task.getConstraintDate();
return; return;
case MUST_FINISH_ON: case MUST_FINISH_ON:
constraint = ConstraintDTO.START_IN_FIXED_DATE; constraint = ConstraintDTO.START_IN_FIXED_DATE;
constraintDate = recalculateConstraintDateMin(task); constraintDate = recalculateConstraintDateMin(task);
return; return;
case START_NO_EARLIER_THAN: case START_NO_EARLIER_THAN:
constraint = ConstraintDTO.START_NOT_EARLIER_THAN; constraint = ConstraintDTO.START_NOT_EARLIER_THAN;
constraintDate = task.getConstraintDate(); constraintDate = task.getConstraintDate();
return; return;
case START_NO_LATER_THAN: case START_NO_LATER_THAN:
constraint = ConstraintDTO.FINISH_NOT_LATER_THAN; constraint = ConstraintDTO.FINISH_NOT_LATER_THAN;
constraintDate = recalculateConstraintDateSum(task); constraintDate = recalculateConstraintDateSum(task);
return; return;
case FINISH_NO_EARLIER_THAN: case FINISH_NO_EARLIER_THAN:
constraint = ConstraintDTO.START_NOT_EARLIER_THAN; constraint = ConstraintDTO.START_NOT_EARLIER_THAN;
constraintDate = recalculateConstraintDateMin(task); constraintDate = recalculateConstraintDateMin(task);
return; return;
case FINISH_NO_LATER_THAN: case FINISH_NO_LATER_THAN:
constraint = ConstraintDTO.FINISH_NOT_LATER_THAN; constraint = ConstraintDTO.FINISH_NOT_LATER_THAN;
constraintDate = task.getConstraintDate(); constraintDate = task.getConstraintDate();
return; return;
} }
@ -999,9 +981,8 @@ Date parentStartDate,
*/ */
private static Date recalculateConstraintDateSum(Task task) { private static Date recalculateConstraintDateSum(Task task) {
return new Date( return new Date(task.getConstraintDate().getTime()
task.getConstraintDate().getTime() + (durationToIntHours(task.getDuration(), properties) * 60 * 60 * 1000));
+ (durationToIntHours(task.getDuration(), header) * 60 * 60 * 1000));
} }
/** /**
@ -1016,8 +997,7 @@ Date parentStartDate,
*/ */
private static Date recalculateConstraintDateMin(Task task) { private static Date recalculateConstraintDateMin(Task task) {
return new Date( return new Date(task.getConstraintDate().getTime() -
task.getConstraintDate().getTime() (durationToIntHours(task.getDuration(), properties) * 60 * 60 * 1000));
- (durationToIntHours(task.getDuration(), header) * 60 * 60 * 1000));
} }
} }

View file

@ -72,6 +72,7 @@ import org.springframework.transaction.annotation.Transactional;
* into Libreplan using MPXJ. * into Libreplan using MPXJ.
* *
* @author Alba Carro Pérez <alba.carro@gmail.com> * @author Alba Carro Pérez <alba.carro@gmail.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>>
*/ */
@Component @Component
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
@ -92,9 +93,6 @@ public class OrderImporterMPXJ implements IOrderImporter {
@Autowired @Autowired
private IOrderDAO orderDAO; private IOrderDAO orderDAO;
@Autowired
private IOrderElementDAO orderElementDAO;
@Autowired @Autowired
private IDependencyDAO dependencyDAO; private IDependencyDAO dependencyDAO;
@ -124,11 +122,9 @@ public class OrderImporterMPXJ implements IOrderImporter {
public OrderDTO getImportData(InputStream file, String filename) { public OrderDTO getImportData(InputStream file, String filename) {
try { try {
ProjectReader reader = ProjectReaderUtility ProjectReader reader = ProjectReaderUtility.getProjectReader(filename);
.getProjectReader(filename);
return MPXJProjectFileConversor return MPXJProjectFileConverter.convert(reader.read(file), filename);
.convert(reader.read(file), filename);
} catch (Exception e) { } catch (Exception e) {
@ -160,8 +156,7 @@ public class OrderImporterMPXJ implements IOrderImporter {
*/ */
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public Order convertImportDataToOrder(OrderDTO project, public Order convertImportDataToOrder(OrderDTO project, boolean importCalendar) {
boolean importCalendar) {
String code = getCode(EntityNameEnum.ORDER); String code = getCode(EntityNameEnum.ORDER);
@ -184,9 +179,8 @@ public class OrderImporterMPXJ implements IOrderImporter {
BaseCalendar calendar = configurationDAO.getConfiguration() BaseCalendar calendar = configurationDAO.getConfiguration()
.getDefaultCalendar(); .getDefaultCalendar();
if (importCalendar & project.calendarName != null) { if ( importCalendar & project.calendarName != null ) {
((Order) orderElement).setCalendar(findBaseCalendar( ((Order) orderElement).setCalendar(findBaseCalendar(project.calendarName));
project.calendarName));
} else { } else {
((Order) orderElement).setCalendar(calendar); ((Order) orderElement).setCalendar(calendar);
} }
@ -232,25 +226,22 @@ project.calendarName));
* Number of version. * Number of version.
* @return OrderElement OrderElement that represent the data. * @return OrderElement OrderElement that represent the data.
*/ */
private OrderElement convertImportTaskToOrderElement( private OrderElement convertImportTaskToOrderElement(OrderVersion orderVersion, OrderElementDTO task) {
OrderVersion orderVersion, OrderElementDTO task) {
Validate.notNull(orderVersion); Validate.notNull(orderVersion);
OrderElement orderElement; OrderElement orderElement;
if (task.children.size() == 0) { if ( task.children.size() == 0 ) {
orderElement = OrderLine.createUnvalidatedWithUnfixedPercentage( orderElement = OrderLine
UUID.randomUUID().toString(), task.totalHours); .createUnvalidatedWithUnfixedPercentage(UUID.randomUUID().toString(), task.totalHours);
if (!orderElement.getHoursGroups().isEmpty()) { if ( !orderElement.getHoursGroups().isEmpty() ) {
orderElement.getHoursGroups().get(0) orderElement.getHoursGroups().get(0).setCode(UUID.randomUUID().toString());
.setCode(UUID.randomUUID().toString());
} }
} else { } else {
orderElement = OrderLineGroup.createUnvalidated(UUID.randomUUID() orderElement = OrderLineGroup.createUnvalidated(UUID.randomUUID().toString());
.toString());
orderElement.useSchedulingDataFor(orderVersion); orderElement.useSchedulingDataFor(orderVersion);
} }
@ -258,8 +249,7 @@ project.calendarName));
List<OrderElement> children = new ArrayList<OrderElement>(); List<OrderElement> children = new ArrayList<OrderElement>();
for (OrderElementDTO childrenTask : task.children) { for (OrderElementDTO childrenTask : task.children) {
children.add(convertImportTaskToOrderElement(orderVersion, children.add(convertImportTaskToOrderElement(orderVersion, childrenTask));
childrenTask));
} }
for (OrderElement child : children) { for (OrderElement child : children) {
@ -290,14 +280,11 @@ project.calendarName));
Order order = project.order; Order order = project.order;
TaskSource taskSource = TaskSource.createForGroup(order TaskSource taskSource = TaskSource.createForGroup(order.getCurrentSchedulingDataForVersion());
.getCurrentSchedulingDataForVersion());
TaskGroup taskGroup = taskSource TaskGroup taskGroup = taskSource.createTaskGroupWithoutDatesInitializedAndLinkItToTaskSource();
.createTaskGroupWithoutDatesInitializedAndLinkItToTaskSource();
BaseCalendar calendar = configurationDAO.getConfiguration() BaseCalendar calendar = configurationDAO.getConfiguration().getDefaultCalendar();
.getDefaultCalendar();
taskGroup.setCalendar(calendar); taskGroup.setCalendar(calendar);
@ -367,12 +354,10 @@ project.calendarName));
if (task.children.size() == 0) { if (task.children.size() == 0) {
taskSource = TaskSource.create( taskSource = TaskSource
orderElement.getCurrentSchedulingDataForVersion(), .create(orderElement.getCurrentSchedulingDataForVersion(), orderElement.getHoursGroups());
orderElement.getHoursGroups());
taskElement = taskSource taskElement = taskSource.createTaskWithoutDatesInitializedAndLinkItToTaskSource();
.createTaskWithoutDatesInitializedAndLinkItToTaskSource();
if (importCalendar && task.calendarName != null) { if (importCalendar && task.calendarName != null) {
taskElement.setCalendar(findBaseCalendar(task.calendarName)); taskElement.setCalendar(findBaseCalendar(task.calendarName));
@ -396,11 +381,12 @@ project.calendarName));
} }
for (MilestoneDTO milestone : task.milestones) { if ( task.milestones != null )
for (MilestoneDTO milestone : task.milestones) {
taskElements.add(createTaskMilestone(milestone)); taskElements.add(createTaskMilestone(milestone));
} }
for (TaskElement childTaskElement : taskElements) { for (TaskElement childTaskElement : taskElements) {
((TaskGroup) taskElement).addTaskElement(childTaskElement); ((TaskGroup) taskElement).addTaskElement(childTaskElement);
@ -430,41 +416,41 @@ project.calendarName));
switch (importTask.constraint) { switch (importTask.constraint) {
case AS_SOON_AS_POSSIBLE: case AS_SOON_AS_POSSIBLE:
task.getPositionConstraint().asSoonAsPossible(); task.getPositionConstraint().asSoonAsPossible();
return; return;
case AS_LATE_AS_POSSIBLE: case AS_LATE_AS_POSSIBLE:
task.getPositionConstraint().asLateAsPossible(); task.getPositionConstraint().asLateAsPossible();
return; return;
case START_IN_FIXED_DATE: case START_IN_FIXED_DATE:
task.setIntraDayStartDate(IntraDayDate.startOfDay(LocalDate task.setIntraDayStartDate(IntraDayDate.startOfDay(LocalDate
.fromDateFields(importTask.constraintDate))); .fromDateFields(importTask.constraintDate)));
Task.convertOnStartInFixedDate(task); Task.convertOnStartInFixedDate(task);
return; return;
case START_NOT_EARLIER_THAN: case START_NOT_EARLIER_THAN:
task.getPositionConstraint().notEarlierThan( task.getPositionConstraint().notEarlierThan(
IntraDayDate.startOfDay(LocalDate IntraDayDate.startOfDay(LocalDate
.fromDateFields(importTask.constraintDate))); .fromDateFields(importTask.constraintDate)));
return; return;
case FINISH_NOT_LATER_THAN: case FINISH_NOT_LATER_THAN:
task.getPositionConstraint().finishNotLaterThan( task.getPositionConstraint().finishNotLaterThan(
IntraDayDate.startOfDay(LocalDate IntraDayDate.startOfDay(LocalDate
.fromDateFields(importTask.constraintDate))); .fromDateFields(importTask.constraintDate)));
return; return;
} }
} }
@ -483,40 +469,40 @@ project.calendarName));
switch (milestone.constraint) { switch (milestone.constraint) {
case AS_SOON_AS_POSSIBLE: case AS_SOON_AS_POSSIBLE:
taskMilestone.getPositionConstraint().asSoonAsPossible(); taskMilestone.getPositionConstraint().asSoonAsPossible();
return; return;
case AS_LATE_AS_POSSIBLE: case AS_LATE_AS_POSSIBLE:
taskMilestone.getPositionConstraint().asLateAsPossible(); taskMilestone.getPositionConstraint().asLateAsPossible();
return; return;
case START_IN_FIXED_DATE: case START_IN_FIXED_DATE:
taskMilestone.getPositionConstraint().notEarlierThan( taskMilestone.getPositionConstraint().notEarlierThan(
IntraDayDate.startOfDay(LocalDate IntraDayDate.startOfDay(LocalDate
.fromDateFields(milestone.constraintDate))); .fromDateFields(milestone.constraintDate)));
return; return;
case START_NOT_EARLIER_THAN: case START_NOT_EARLIER_THAN:
taskMilestone.getPositionConstraint().notEarlierThan( taskMilestone.getPositionConstraint().notEarlierThan(
IntraDayDate.startOfDay(LocalDate IntraDayDate.startOfDay(LocalDate
.fromDateFields(milestone.constraintDate))); .fromDateFields(milestone.constraintDate)));
return; return;
case FINISH_NOT_LATER_THAN: case FINISH_NOT_LATER_THAN:
taskMilestone.getPositionConstraint().finishNotLaterThan( taskMilestone.getPositionConstraint().finishNotLaterThan(
IntraDayDate.startOfDay(LocalDate IntraDayDate.startOfDay(LocalDate
.fromDateFields(milestone.constraintDate))); .fromDateFields(milestone.constraintDate)));
return; return;
} }
} }
@ -534,8 +520,7 @@ project.calendarName));
*/ */
@Override @Override
@Transactional @Transactional
public void storeOrder(final Order order, final TaskGroup taskGroup, public void storeOrder(final Order order, final TaskGroup taskGroup, final List<Dependency> dependencies) {
final List<Dependency> dependencies) {
final List<TaskSource> taskSources = new ArrayList<TaskSource>(); final List<TaskSource> taskSources = new ArrayList<TaskSource>();
@ -543,7 +528,7 @@ project.calendarName));
for (TaskElement taskElement : taskGroup.getAllChildren()) { for (TaskElement taskElement : taskGroup.getAllChildren()) {
if (!taskElement.isMilestone()) { if ( !taskElement.isMilestone() ) {
taskSources.add(taskElement.getTaskSource()); taskSources.add(taskElement.getTaskSource());
@ -585,13 +570,18 @@ project.calendarName));
for(DependencyDTO dependencyDTO: importData.dependencies){ for(DependencyDTO dependencyDTO: importData.dependencies){
TaskElement origin = dependencyDTO.origin.getTaskAssociated(); TaskElement origin = null;
TaskElement destination = null;
TaskElement destination = dependencyDTO.destination if ( dependencyDTO.origin != null && dependencyDTO.origin.getTaskAssociated() != null )
.getTaskAssociated(); origin = dependencyDTO.origin.getTaskAssociated();
dependencies.add(Dependency.create(origin, destination, if ( dependencyDTO.destination != null && dependencyDTO.destination.getTaskAssociated() != null )
toLPType(dependencyDTO.type))); destination = dependencyDTO.destination.getTaskAssociated();
if ( origin != null && destination != null ){
dependencies.add(Dependency.create(origin, destination, toLPType(dependencyDTO.type)));
}
} }
return dependencies; return dependencies;
@ -610,25 +600,23 @@ project.calendarName));
switch (type) { switch (type) {
case END_START: case END_START:
return Type.END_START; return Type.END_START;
case START_START: case START_START:
return Type.START_START; return Type.START_START;
case END_END: case END_END:
return Type.END_END; return Type.END_END;
case START_END: case START_END:
//TODO LP doesn't support START_END dependency at this moment. Fix this when it does. return Type.START_END;
//Returns a END_START instead.
return Type.END_START;
default: default:
return null; return null;
} }
} }
@ -649,7 +637,7 @@ project.calendarName));
BaseCalendar calendar = null; BaseCalendar calendar = null;
for (BaseCalendar baseCalendar : baseCalendars) { for (BaseCalendar baseCalendar : baseCalendars) {
if (baseCalendar.getName().equals(name)) { if ( baseCalendar.getName().equals(name) ) {
calendar = baseCalendar; calendar = baseCalendar;
return calendar; return calendar;

View file

@ -82,7 +82,6 @@ public class ProjectImportController extends GenericForwardComposer {
} }
} else if (importTasks.isChecked()) { } else if (importTasks.isChecked()) {
importProject(media.getStreamData(), file); importProject(media.getStreamData(), file);
messages.showMessage(Level.INFO, _(file messages.showMessage(Level.INFO, _(file
@ -107,7 +106,7 @@ public class ProjectImportController extends GenericForwardComposer {
} else { } else {
messages.showMessage(Level.ERROR, messages.showMessage(Level.ERROR,
_("The only current suported formats are mpp and planner.")); _("The only current supported formats are mpp and planner."));
} }
} }
@ -121,8 +120,7 @@ public class ProjectImportController extends GenericForwardComposer {
* Name of the file that we want to import. * Name of the file that we want to import.
*/ */
@Transactional @Transactional
private void importAll(InputStream streamData, String file) private void importAll(InputStream streamData, String file) throws InstanceNotFoundException, ValidationException {
throws InstanceNotFoundException, ValidationException {
List<CalendarDTO> calendarDTOs = calendarImporterMPXJ.getCalendarDTOs( List<CalendarDTO> calendarDTOs = calendarImporterMPXJ.getCalendarDTOs(
streamData, file); streamData, file);
@ -139,8 +137,7 @@ public class ProjectImportController extends GenericForwardComposer {
TaskGroup taskGroup = orderImporterMPXJ.createTask(importData, true); TaskGroup taskGroup = orderImporterMPXJ.createTask(importData, true);
List<Dependency> dependencies = orderImporterMPXJ List<Dependency> dependencies = orderImporterMPXJ.createDependencies(importData);
.createDependencies(importData);
orderImporterMPXJ.storeOrder(order, taskGroup, dependencies); orderImporterMPXJ.storeOrder(order, taskGroup, dependencies);
@ -155,8 +152,7 @@ public class ProjectImportController extends GenericForwardComposer {
* Name of the file that we want to import. * Name of the file that we want to import.
*/ */
@Transactional @Transactional
private void importCalendar(InputStream streamData, String file) private void importCalendar(InputStream streamData, String file) throws InstanceNotFoundException, ValidationException {
throws InstanceNotFoundException, ValidationException {
List<CalendarDTO> calendarDTOs = calendarImporterMPXJ.getCalendarDTOs( List<CalendarDTO> calendarDTOs = calendarImporterMPXJ.getCalendarDTOs(
streamData, file); streamData, file);
@ -181,13 +177,11 @@ public class ProjectImportController extends GenericForwardComposer {
OrderDTO importData = orderImporterMPXJ.getImportData(streamData, file); OrderDTO importData = orderImporterMPXJ.getImportData(streamData, file);
Order order = orderImporterMPXJ.convertImportDataToOrder(importData, Order order = orderImporterMPXJ.convertImportDataToOrder(importData, false);
false);
TaskGroup taskGroup = orderImporterMPXJ.createTask(importData, false); TaskGroup taskGroup = orderImporterMPXJ.createTask(importData, false);
List<Dependency> dependencies = orderImporterMPXJ List<Dependency> dependencies = orderImporterMPXJ.createDependencies(importData);
.createDependencies(importData);
orderImporterMPXJ.storeOrder(order, taskGroup, dependencies); orderImporterMPXJ.storeOrder(order, taskGroup, dependencies);

View file

@ -383,17 +383,14 @@ public final class OrderElementConverter {
checkOrderElementDTOCode(orderElementDTO, "OrderLineDTO"); checkOrderElementDTOCode(orderElementDTO, "OrderLineDTO");
if ((configuration.isHoursGroups()) if ((configuration.isHoursGroups())
&& (!((OrderLineDTO) orderElementDTO).hoursGroups.isEmpty())) { && (!((OrderLineDTO) orderElementDTO).hoursGroups.isEmpty())) {
orderElement = OrderLine orderElement = OrderLine.createUnvalidated(orderElementDTO.code);
.createUnvalidated(orderElementDTO.code);
for (HoursGroupDTO hoursGroupDTO : ((OrderLineDTO) orderElementDTO).hoursGroups) { for (HoursGroupDTO hoursGroupDTO : ((OrderLineDTO) orderElementDTO).hoursGroups) {
HoursGroup hoursGroup = toEntity(hoursGroupDTO, HoursGroup hoursGroup = toEntity(hoursGroupDTO,
configuration); configuration);
((OrderLine) orderElement).addHoursGroup(hoursGroup); ((OrderLine) orderElement).addHoursGroup(hoursGroup);
} }
} else { } else {
orderElement = OrderLine orderElement = OrderLine.createUnvalidatedWithUnfixedPercentage(orderElementDTO.code, 0);
.createUnvalidatedWithUnfixedPercentage(
orderElementDTO.code, 0);
if (!orderElement.getHoursGroups().isEmpty()) { if (!orderElement.getHoursGroups().isEmpty()) {
orderElement.getHoursGroups().get(0).setCode( orderElement.getHoursGroups().get(0).setCode(
UUID.randomUUID().toString()); UUID.randomUUID().toString());
@ -572,15 +569,11 @@ public final class OrderElementConverter {
if (configuration.isHoursGroups()) { if (configuration.isHoursGroups()) {
for (HoursGroupDTO hoursGroupDTO : ((OrderLineDTO) orderElementDTO).hoursGroups) { for (HoursGroupDTO hoursGroupDTO : ((OrderLineDTO) orderElementDTO).hoursGroups) {
if (((OrderLine) orderElement) if ( ((OrderLine) orderElement).containsHoursGroup(hoursGroupDTO.code) ) {
.containsHoursGroup(hoursGroupDTO.code)) { update( ((OrderLine) orderElement)
update(((OrderLine) orderElement) .getHoursGroup(hoursGroupDTO.code), hoursGroupDTO, configuration);
.getHoursGroup(hoursGroupDTO.code),
hoursGroupDTO, configuration);
} else { } else {
((OrderLine) orderElement) ((OrderLine) orderElement).addHoursGroup(toEntity(hoursGroupDTO, configuration));
.addHoursGroup(toEntity(
hoursGroupDTO, configuration));
} }
} }
} }

View file

@ -9360,3 +9360,7 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/common/configuration.zul:240 #: libreplan-webapp/src/main/webapp/common/configuration.zul:240
msgid "Local document repository location" msgid "Local document repository location"
msgstr "" msgstr ""
#: libreplan-webapp/src/main/webapp/orders/imports/projectImport.zul:42
msgid "Your project could only partially be imported"
msgstr ""

View file

@ -29,29 +29,37 @@
<zk> <zk>
<window id="importProject" self="@{define(content)}" <window id="importProject" self="@{define(content)}"
apply="org.libreplan.web.importers.ProjectImportController" apply="org.libreplan.web.importers.ProjectImportController"
title="${i18n:_('Import Project')}"> title="${i18n:_('Import Project')}">
<vbox id="messagesContainer" /> <vbox id="messagesContainer" />
<label value="${i18n:_('The formats supported for import are MPP and PLANNER files.')}"/> <label value="${i18n:_('The formats supported for import are MPP and PLANNER files.')}"/>
<label value="${i18n:_('The imported data are Gantt projects with their tasks, constraints, dependencies and milestones and there is also the option to upload calendars.')}"/> <label value="${i18n:_('The imported data are Gantt projects with their tasks, constraints,
dependencies and milestones and there is also the option to upload calendars.')}"/>
<hbox>
<label style="font-weight: bold;" value="${i18n:_('Your project could only partially be imported.')}"/>
</hbox>
<groupbox closable="false" style="padding:10px; margin:10px;">
<caption label="Options" />
<label value="${i18n:_('Select the elements to import into LibrePlan')}:"/>
<vbox style="padding:10px;" align="pack"> <groupbox closable="false" style="padding:10px; margin:10px;">
<radiogroup> <caption label="Options" />
<radio id="importCalendars" label="${i18n:_('Calendars')}"/> <label value="${i18n:_('Select the elements to import into LibrePlan')}:"/>
<radio id="importTasks" label="${i18n:_('Gantt charts')}" /> <vbox style="padding:10px;" align="pack">
<radio id="importAll" label="${i18n:_('Both calendars and gantt charts')}" selected="true"/> <radiogroup>
</radiogroup> <radio id="importCalendars" label="${i18n:_('Calendars')}"/>
</vbox> <radio id="importTasks" label="${i18n:_('Gantt charts')}" />
</groupbox> <radio id="importAll" label="${i18n:_('Both calendars and gantt charts')}" selected="true"/>
</radiogroup>
</vbox>
</groupbox>
<hbox> <hbox>
<button id="btnImportProject" label="${i18n:_('Upload Project')}" upload="true,maxsize=4000" onUpload="projectImportController.importProject(event.getMedia())" class="create-button global-action"/> <button id="btnImportProject" label="${i18n:_('Upload Project')}" upload="true,maxsize=9000"
onUpload="projectImportController.importProject(event.getMedia())" class="create-button global-action"/>
</hbox> </hbox>
</window> </window>
</zk> </zk>

View file

@ -33,8 +33,6 @@ import java.io.InputStream;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.libreplan.importers.IOrderImporter;
import org.libreplan.importers.OrderDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

View file

@ -612,9 +612,9 @@
<!-- MPXJ Library --> <!-- MPXJ Library -->
<dependency> <dependency>
<groupId>net.sourceforge</groupId> <groupId>net.sf.mpxj</groupId>
<artifactId>mpxj</artifactId> <artifactId>mpxj</artifactId>
<version>4.3.0</version> <version>5.2.1</version>
</dependency> </dependency>
<!-- ZK fileupload --> <!-- ZK fileupload -->
@ -625,7 +625,7 @@
</dependency> </dependency>
<!-- Quartz framework --> <!-- Quartz framework -->
<dependency> <dependency>
<groupId>org.quartz-scheduler</groupId> <groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId> <artifactId>quartz</artifactId>
<version>1.8.6</version> <version>1.8.6</version>
@ -639,7 +639,7 @@
<artifactId>slf4j-log4j12</artifactId> <artifactId>slf4j-log4j12</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>