Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resource timephased #650

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions mkdocs/docs/field-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,28 @@ Baseline Budget Cost| | | | | | | |✓| | | | | | | | | | | |
Baseline Budget Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Baseline Cost| | | | | | | |✓|✓|✓| | | | | | | | | | | | | 
Baseline Work| | | | | | |✓|✓|✓|✓| | | | | | | | | | | | | 
Timephased Baseline1 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline1 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline2 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline2 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline3 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline3 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline4 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline4 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline5 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline5 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline6 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline6 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline7 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline7 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline8 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline8 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline9 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline9 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline10 Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline10 Work| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline Cost| | | | | | | |✓| | | | | | | | | | | | | | | 
Timephased Baseline Work| | | | | | | |✓| | | | | | | | | | | | | | | 

### Custom Fields
Field|Asta (PP)|ConceptDraw PROJECT (CDP)|FastTrack (FTS)|GanttDesigner (GNT)|GanttProject (GAN)|Merlin (SQLITE)|Microsoft (MPD)|Microsoft (MPP)|Microsoft (MPX)|Microsoft (MSPDI)|P3 (BTRIEVE)|Phoenix (PPX)|Planner (XML)|Primavera (PMXML)|Primavera (SQLITE)|Primavera (XER)|Project Commander (PC)|ProjectLibre (POD)|SDEF (SDEF)|Sage (SCHEDULE_GRID)|SureTrak (STW)|Synchro (SP)|TurboProject (PEP)
Expand Down
22 changes: 22 additions & 0 deletions mkdocs/docs/mpp-field-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,28 @@ Baseline Budget Cost| | | |✓
Baseline Budget Work| | | |✓
Baseline Cost| |✓|✓|✓
Baseline Work|✓|✓|✓|✓
Timephased Baseline1 Cost| |✓|✓|✓
Timephased Baseline1 Work| |✓|✓|✓
Timephased Baseline2 Cost| |✓| |✓
Timephased Baseline2 Work| |✓| |✓
Timephased Baseline3 Cost| |✓| |✓
Timephased Baseline3 Work| |✓| |✓
Timephased Baseline4 Cost| |✓| |✓
Timephased Baseline4 Work| |✓| |✓
Timephased Baseline5 Cost| |✓| |✓
Timephased Baseline5 Work| |✓| |✓
Timephased Baseline6 Cost| |✓| |✓
Timephased Baseline6 Work| |✓| |✓
Timephased Baseline7 Cost| |✓| |✓
Timephased Baseline7 Work| |✓| |✓
Timephased Baseline8 Cost| |✓| |✓
Timephased Baseline8 Work| |✓| |✓
Timephased Baseline9 Cost| |✓| |✓
Timephased Baseline9 Work| |✓| |✓
Timephased Baseline10 Cost| | |✓|✓
Timephased Baseline10 Work| | |✓|✓
Timephased Baseline Cost| |✓|✓|✓
Timephased Baseline Work| |✓|✓|✓

### Custom Fields
Field|MPP8|MPP9|MPP12|MPP14
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/net/sf/mpxj/LocaleData.java
Original file line number Diff line number Diff line change
Expand Up @@ -1605,6 +1605,28 @@ public static final String[] getStringArray(Locale locale, String key)
RESOURCE_COLUMNS_ARRAY[ResourceField.LOCATION_UNIQUE_ID.getValue()] = "Location Unique ID";
RESOURCE_COLUMNS_ARRAY[ResourceField.UNIT_OF_MEASURE_UNIQUE_ID.getValue()] = "Unit of Measure Unique ID";
RESOURCE_COLUMNS_ARRAY[ResourceField.DEFAULT_UNITS.getValue()] = "Default Units";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE_WORK.getValue()] = "Timephased Baseline Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE1_WORK.getValue()] = "Timephased Baseline1 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE2_WORK.getValue()] = "Timephased Baseline2 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE3_WORK.getValue()] = "Timephased Baseline3 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE4_WORK.getValue()] = "Timephased Baseline4 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE5_WORK.getValue()] = "Timephased Baseline5 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE6_WORK.getValue()] = "Timephased Baseline6 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE7_WORK.getValue()] = "Timephased Baseline7 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE8_WORK.getValue()] = "Timephased Baseline8 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE9_WORK.getValue()] = "Timephased Baseline9 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE10_WORK.getValue()] = "Timephased Baseline10 Work";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE_COST.getValue()] = "Timephased Baseline Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE1_COST.getValue()] = "Timephased Baseline1 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE2_COST.getValue()] = "Timephased Baseline2 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE3_COST.getValue()] = "Timephased Baseline3 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE4_COST.getValue()] = "Timephased Baseline4 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE5_COST.getValue()] = "Timephased Baseline5 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE6_COST.getValue()] = "Timephased Baseline6 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE7_COST.getValue()] = "Timephased Baseline7 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE8_COST.getValue()] = "Timephased Baseline8 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE9_COST.getValue()] = "Timephased Baseline9 Cost";
RESOURCE_COLUMNS_ARRAY[ResourceField.TIMEPHASED_BASELINE10_COST.getValue()] = "Timephased Baseline10 Cost";

ASSIGNMENT_COLUMNS_ARRAY[AssignmentField.START.getValue()] = "Start";
ASSIGNMENT_COLUMNS_ARRAY[AssignmentField.ASSIGNMENT_UNITS.getValue()] = "Assignment Units";
Expand Down
53 changes: 52 additions & 1 deletion src/main/java/net/sf/mpxj/Resource.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
/**
* This class represents a resource used in a project.
*/
public final class Resource extends AbstractFieldContainer<Resource> implements Comparable<Resource>, ProjectEntityWithID, ChildResourceContainer
public final class Resource extends AbstractFieldContainer<Resource> implements Comparable<Resource>, ProjectEntityWithID, ChildResourceContainer, TimePeriodEntity
{
/**
* Default constructor.
Expand Down Expand Up @@ -2625,6 +2625,54 @@ public void setUnitOfMeasure(UnitOfMeasure unitOfMeasure)
setUnitOfMeasureUniqueID(unitOfMeasure == null ? null : unitOfMeasure.getUniqueID());
}

/**
* Set timephased baseline work. Note that index 0 represents "Baseline",
* index 1 represents "Baseline1" and so on.
*
* @param index baseline index
* @param data timephased data
*/
public void setTimephasedBaselineWork(int index, TimephasedWorkContainer data)
{
m_timephasedBaselineWork[index] = data;
}

/**
* Set timephased baseline cost. Note that index 0 represents "Baseline",
* index 1 represents "Baseline1" and so on.
*
* @param index baseline index
* @param data timephased data
*/
public void setTimephasedBaselineCost(int index, TimephasedCostContainer data)
{
m_timephasedBaselineCost[index] = data;
}

/**
* Retrieve timephased baseline work. Note that index 0 represents "Baseline",
* index 1 represents "Baseline1" and so on.
*
* @param index baseline index
* @return timephased work, or null if no baseline is present
*/
public List<TimephasedWork> getTimephasedBaselineWork(int index)
{
return m_timephasedBaselineWork[index] == null ? null : m_timephasedBaselineWork[index].getData();
}

/**
* Retrieve timephased baseline cost. Note that index 0 represents "Baseline",
* index 1 represents "Baseline1" and so on.
*
* @param index baseline index
* @return timephased work, or null if no baseline is present
*/
public List<TimephasedCost> getTimephasedBaselineCost(int index)
{
return m_timephasedBaselineCost[index] == null ? null : m_timephasedBaselineCost[index].getData();
}

/**
* Maps a field index to a ResourceField instance.
*
Expand Down Expand Up @@ -2903,6 +2951,9 @@ private LocalDateTime calculateAvailableTo()
private final CostRateTable[] m_costRateTables;
private final AvailabilityTable m_availability = new AvailabilityTable();

private final TimephasedWorkContainer[] m_timephasedBaselineWork = new TimephasedWorkContainer[11];
private final TimephasedCostContainer[] m_timephasedBaselineCost = new TimephasedCostContainer[11];

private static final Set<FieldType> ALWAYS_CALCULATED_FIELDS = new HashSet<>(Arrays.asList(ResourceField.STANDARD_RATE, ResourceField.OVERTIME_RATE, ResourceField.COST_PER_USE, ResourceField.START, ResourceField.FINISH, ResourceField.MAX_UNITS, ResourceField.AVAILABLE_FROM, ResourceField.AVAILABLE_TO));

private static final Map<FieldType, Function<Resource, Object>> CALCULATED_FIELD_MAP = new HashMap<>();
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/net/sf/mpxj/ResourceAssignment.java
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ private TimephasedCostContainer getTimephasedCostSingleRate(List<TimephasedWork>
//just return an empty list if there is no timephased work passed in
if (standardWorkList == null)
{
return new DefaultTimephasedCostContainer(this, null, Collections.emptyList(), false);
return new DefaultTimephasedCostContainer(getEffectiveCalendar(), this, null, Collections.emptyList(), false);
}

List<TimephasedCost> result = new ArrayList<>();
Expand Down Expand Up @@ -892,7 +892,7 @@ private TimephasedCostContainer getTimephasedCostSingleRate(List<TimephasedWork>

}

return new DefaultTimephasedCostContainer(this, null, result, false);
return new DefaultTimephasedCostContainer(getEffectiveCalendar(), this, null, result, false);
}

/**
Expand Down Expand Up @@ -1010,7 +1010,7 @@ private TimephasedCostContainer getTimephasedCostFixedAmount()
}
}

return new DefaultTimephasedCostContainer(this, null, result, false);
return new DefaultTimephasedCostContainer(getEffectiveCalendar(), this, null, result, false);
}

/**
Expand Down Expand Up @@ -1048,7 +1048,7 @@ private TimephasedCostContainer getTimephasedActualCostFixedAmount()
}
}

return new DefaultTimephasedCostContainer(this, null, result, false);
return new DefaultTimephasedCostContainer(getEffectiveCalendar(), this, null, result, false);
}

/**
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/net/sf/mpxj/ResourceField.java
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,28 @@ public enum ResourceField implements FieldType
ENTERPRISE_DATA(DataType.BINARY),
OVERTIME_RATE_UNITS(DataType.RATE_UNITS),
STANDARD_RATE_UNITS(DataType.RATE_UNITS),
TIMEPHASED_BASELINE_WORK(DataType.BINARY),
TIMEPHASED_BASELINE1_WORK(DataType.BINARY),
TIMEPHASED_BASELINE2_WORK(DataType.BINARY),
TIMEPHASED_BASELINE3_WORK(DataType.BINARY),
TIMEPHASED_BASELINE4_WORK(DataType.BINARY),
TIMEPHASED_BASELINE5_WORK(DataType.BINARY),
TIMEPHASED_BASELINE6_WORK(DataType.BINARY),
TIMEPHASED_BASELINE7_WORK(DataType.BINARY),
TIMEPHASED_BASELINE8_WORK(DataType.BINARY),
TIMEPHASED_BASELINE9_WORK(DataType.BINARY),
TIMEPHASED_BASELINE10_WORK(DataType.BINARY),
TIMEPHASED_BASELINE_COST(DataType.BINARY),
TIMEPHASED_BASELINE1_COST(DataType.BINARY),
TIMEPHASED_BASELINE2_COST(DataType.BINARY),
TIMEPHASED_BASELINE3_COST(DataType.BINARY),
TIMEPHASED_BASELINE4_COST(DataType.BINARY),
TIMEPHASED_BASELINE5_COST(DataType.BINARY),
TIMEPHASED_BASELINE6_COST(DataType.BINARY),
TIMEPHASED_BASELINE7_COST(DataType.BINARY),
TIMEPHASED_BASELINE8_COST(DataType.BINARY),
TIMEPHASED_BASELINE9_COST(DataType.BINARY),
TIMEPHASED_BASELINE10_COST(DataType.BINARY),

INDEX(DataType.INTEGER),
HYPERLINK_SCREEN_TIP(DataType.STRING),
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/sf/mpxj/TimephasedItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void setFinish(LocalDateTime finish)

@Override public String toString()
{
return "[TimephasedItem start=" + m_start + " totalAmount=" + m_totalAmount + " finish=" + m_finish + " amountPerDay=" + m_amountPerDay + " modified=" + m_modified + "]";
return "[TimephasedItem start=" + m_start + " finish=" + m_finish + " totalAmount=" + m_totalAmount + "]";
}

@SuppressWarnings("unchecked") @Override public boolean equals(Object o)
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/net/sf/mpxj/common/AssignmentFieldLists.java
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,36 @@ public final class AssignmentFieldLists
AssignmentField.ENTERPRISE_RESOURCE_OUTLINE_CODE29
};

public static final AssignmentField[] TIMEPHASED_BASELINE_WORK =
{
AssignmentField.TIMEPHASED_BASELINE_WORK,
AssignmentField.TIMEPHASED_BASELINE1_WORK,
AssignmentField.TIMEPHASED_BASELINE2_WORK,
AssignmentField.TIMEPHASED_BASELINE3_WORK,
AssignmentField.TIMEPHASED_BASELINE4_WORK,
AssignmentField.TIMEPHASED_BASELINE5_WORK,
AssignmentField.TIMEPHASED_BASELINE6_WORK,
AssignmentField.TIMEPHASED_BASELINE7_WORK,
AssignmentField.TIMEPHASED_BASELINE8_WORK,
AssignmentField.TIMEPHASED_BASELINE9_WORK,
AssignmentField.TIMEPHASED_BASELINE10_WORK
};

public static final AssignmentField[] TIMEPHASED_BASELINE_COST =
{
AssignmentField.TIMEPHASED_BASELINE_COST,
AssignmentField.TIMEPHASED_BASELINE1_COST,
AssignmentField.TIMEPHASED_BASELINE2_COST,
AssignmentField.TIMEPHASED_BASELINE3_COST,
AssignmentField.TIMEPHASED_BASELINE4_COST,
AssignmentField.TIMEPHASED_BASELINE5_COST,
AssignmentField.TIMEPHASED_BASELINE6_COST,
AssignmentField.TIMEPHASED_BASELINE7_COST,
AssignmentField.TIMEPHASED_BASELINE8_COST,
AssignmentField.TIMEPHASED_BASELINE9_COST,
AssignmentField.TIMEPHASED_BASELINE10_COST
};

public static final List<AssignmentField> CUSTOM_FIELDS = new ArrayList<>();
static
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

import java.util.List;

import net.sf.mpxj.ResourceAssignment;
import net.sf.mpxj.ProjectCalendar;
import net.sf.mpxj.TimePeriodEntity;
import net.sf.mpxj.TimephasedCost;
import net.sf.mpxj.TimephasedCostContainer;

Expand All @@ -37,16 +38,17 @@ public class DefaultTimephasedCostContainer implements TimephasedCostContainer
/**
* Constructor.
*
* @param assignment resource assignment to which the timephased data relates
* @param parent entity to which the timephased data relates
* @param normaliser normaliser used to process this data
* @param data timephased data
* @param raw flag indicating if this data is raw
*/
public DefaultTimephasedCostContainer(ResourceAssignment assignment, TimephasedNormaliser<TimephasedCost> normaliser, List<TimephasedCost> data, boolean raw)
public DefaultTimephasedCostContainer(ProjectCalendar calendar, TimePeriodEntity parent, TimephasedNormaliser<TimephasedCost> normaliser, List<TimephasedCost> data, boolean raw)
{
m_calendar = calendar;
m_data = data;
m_raw = raw;
m_assignment = assignment;
m_parent = parent;
m_normaliser = normaliser;
}

Expand All @@ -57,7 +59,7 @@ public DefaultTimephasedCostContainer(ResourceAssignment assignment, TimephasedN
{
if (m_raw)
{
m_normaliser.normalise(m_assignment.getEffectiveCalendar(), m_assignment, m_data);
m_normaliser.normalise(m_calendar, m_parent, m_data);
m_raw = false;
}
return m_data;
Expand All @@ -73,8 +75,9 @@ public DefaultTimephasedCostContainer(ResourceAssignment assignment, TimephasedN
return !m_data.isEmpty();
}

private final ProjectCalendar m_calendar;
private final List<TimephasedCost> m_data;
private boolean m_raw;
private final TimephasedNormaliser<TimephasedCost> m_normaliser;
private final ResourceAssignment m_assignment;
private final TimePeriodEntity m_parent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
import java.util.ArrayList;
import java.util.List;

import net.sf.mpxj.ResourceAssignment;
import net.sf.mpxj.ProjectCalendar;
import net.sf.mpxj.TimePeriodEntity;
import net.sf.mpxj.TimephasedWork;
import net.sf.mpxj.TimephasedWorkContainer;

Expand All @@ -38,16 +39,17 @@ public class DefaultTimephasedWorkContainer implements TimephasedWorkContainer
/**
* Constructor.
*
* @param assignment resource assignment to which the timephased data relates
* @param parent entity to which the timephased data relates
* @param normaliser normaliser used to process this data
* @param data timephased data
* @param raw flag indicating if this data is raw
*/
public DefaultTimephasedWorkContainer(ResourceAssignment assignment, TimephasedNormaliser<TimephasedWork> normaliser, List<TimephasedWork> data, boolean raw)
public DefaultTimephasedWorkContainer(ProjectCalendar calendar, TimePeriodEntity parent, TimephasedNormaliser<TimephasedWork> normaliser, List<TimephasedWork> data, boolean raw)
{
m_calendar = calendar;
m_data = data;
m_raw = raw;
m_assignment = assignment;
m_parent = parent;
m_normaliser = normaliser;
}

Expand All @@ -63,7 +65,7 @@ private DefaultTimephasedWorkContainer(DefaultTimephasedWorkContainer source, do
{
m_data = new ArrayList<>();
m_raw = source.m_raw;
m_assignment = source.m_assignment;
m_parent = source.m_parent;
m_normaliser = source.m_normaliser;

for (TimephasedWork sourceItem : source.m_data)
Expand All @@ -79,7 +81,7 @@ private DefaultTimephasedWorkContainer(DefaultTimephasedWorkContainer source, do
{
if (m_raw)
{
m_normaliser.normalise(m_assignment.getEffectiveCalendar(), m_assignment, m_data);
m_normaliser.normalise(m_calendar, m_parent, m_data);
m_raw = false;
}
return m_data;
Expand All @@ -100,8 +102,9 @@ private DefaultTimephasedWorkContainer(DefaultTimephasedWorkContainer source, do
return new DefaultTimephasedWorkContainer(this, perDayFactor, totalFactor);
}

private ProjectCalendar m_calendar;
private final List<TimephasedWork> m_data;
private boolean m_raw;
private final TimephasedNormaliser<TimephasedWork> m_normaliser;
private final ResourceAssignment m_assignment;
private final TimePeriodEntity m_parent;
}
Loading