From a7a0a310c6187ad05c2faea79d4238ccdb938fd2 Mon Sep 17 00:00:00 2001 From: Jon Iles Date: Tue, 29 Oct 2024 16:18:29 +0000 Subject: [PATCH] Add Activity Percent Complete Attribute (#765) --- mkdocs/docs/field-guide.md | 1 + mkdocs/docs/mpp-field-guide.md | 1 + src/changes/changes.xml | 1 + src/main/java/net/sf/mpxj/LocaleData.java | 1 + src/main/java/net/sf/mpxj/Task.java | 40 +++++++++++++++++++++++ src/main/java/net/sf/mpxj/TaskField.java | 3 +- 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/mkdocs/docs/field-guide.md b/mkdocs/docs/field-guide.md index ad4bda1195..b512d37bc8 100644 --- a/mkdocs/docs/field-guide.md +++ b/mkdocs/docs/field-guide.md @@ -190,6 +190,7 @@ ACWP| | | | | | | |✓| | |✓| | | | | | | | | | | | |  Active|✓|✓|✓|✓|✓|✓|✓| |✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓ Activity Codes|✓|✓|✓|✓|✓|✓|✓| |✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓|✓ Activity ID|✓| |✓| | | | | | | | |✓|✓| |✓|✓|✓| | |✓| |✓|✓|  +Activity Percent Complete|✓|✓| |✓|✓|✓| | |✓|✓|✓|✓|✓|✓|✓|✓|✓| | |✓| |✓|✓|  Activity Status| | | | | | | | | | | | | | |✓|✓|✓| | | | | | |  Activity Type|✓| |✓| | | | | | | | | |✓| |✓|✓|✓| | | | | | |  Actual Cost| | | | | | | |✓|✓|✓|✓| | | |✓|✓|✓| | |✓| | | |  diff --git a/mkdocs/docs/mpp-field-guide.md b/mkdocs/docs/mpp-field-guide.md index d09d76427e..e4321bf827 100644 --- a/mkdocs/docs/mpp-field-guide.md +++ b/mkdocs/docs/mpp-field-guide.md @@ -149,6 +149,7 @@ Field|MPP8|MPP9|MPP12|MPP14 % Work Complete|✓|✓|✓|✓ Active|✓|✓|✓|✓ Activity Codes|✓|✓|✓|✓ +Activity Percent Complete|✓|✓|✓|✓ Actual Cost|✓|✓|✓|✓ Actual Duration|✓|✓|✓|✓ Actual Duration Units| |✓|✓|✓ diff --git a/src/changes/changes.xml b/src/changes/changes.xml index cdacb13bb2..ac9e3f71fd 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -7,6 +7,7 @@ Added the `Task.getBaselineTask()` methods. For applications where a separate baseline schedule is present or a baseline has been manually added to the `ProjectFile` instance, these methods will allow you to access the underlying baseline task instance from the current task instance. + Added the Activity Percent Complete attribute to the `Task` class. The value of this attribute will be the Duration, Physical or Units percent complete value, based on the Percent Complete Type setting. This attribute is provided as a convenience to match the Activity Percent Complete type value shown in P6. Fix CVE-2024-49771: Potential Path Traversal Vulnerability diff --git a/src/main/java/net/sf/mpxj/LocaleData.java b/src/main/java/net/sf/mpxj/LocaleData.java index cedebfae44..6b6a86c0c8 100644 --- a/src/main/java/net/sf/mpxj/LocaleData.java +++ b/src/main/java/net/sf/mpxj/LocaleData.java @@ -1058,6 +1058,7 @@ public static final String[] getStringArray(Locale locale, String key) TASK_COLUMNS_ARRAY[TaskField.SHOW_START_TEXT.getValue()] = "Show Start Text"; TASK_COLUMNS_ARRAY[TaskField.SHOW_FINISH_TEXT.getValue()] = "Show Finish Text"; TASK_COLUMNS_ARRAY[TaskField.SHOW_DURATION_TEXT.getValue()] = "Show Duration Text"; + TASK_COLUMNS_ARRAY[TaskField.ACTIVITY_PERCENT_COMPLETE.getValue()] = "Activity Percent Complete"; RESOURCE_COLUMNS_ARRAY[ResourceField.ID.getValue()] = "ID"; RESOURCE_COLUMNS_ARRAY[ResourceField.NAME.getValue()] = "Name"; diff --git a/src/main/java/net/sf/mpxj/Task.java b/src/main/java/net/sf/mpxj/Task.java index 8f77225d51..1934deca08 100644 --- a/src/main/java/net/sf/mpxj/Task.java +++ b/src/main/java/net/sf/mpxj/Task.java @@ -5484,6 +5484,17 @@ public boolean getShowDurationText() return (BooleanHelper.getBoolean((Boolean) get(TaskField.SHOW_DURATION_TEXT))); } + /** + * This accessor method returns the percent complete value for this task + * as defined by the Percent Complete Type attribute. + * + * @return activity percent complete + */ + public Number getActivityPercentComplete() + { + return (Number) get(TaskField.ACTIVITY_PERCENT_COMPLETE); + } + /** * Retrieve the effective calendar for this task. If the task does not have * a specific calendar associated with it, fall back to using the default calendar @@ -5879,6 +5890,33 @@ private List calculateSuccessors() return getParentFile().getRelations().getSuccessors(this); } + private Number calculateActivityPercentComplete() + { + PercentCompleteType type = getPercentCompleteType(); + if (type == null) + { + return getPercentageComplete(); + } + + switch(type) + { + case UNITS: + { + return getPercentageWorkComplete(); + } + + case PHYSICAL: + { + return getPhysicalPercentComplete(); + } + + default: + { + return getPercentageComplete(); + } + } + } + /** * Supply a default value for constraint type. * @@ -5982,6 +6020,7 @@ private Boolean defaultExpanded() CALCULATED_FIELD_MAP.put(TaskField.EXTERNAL_PROJECT, Task::calculateExternalProject); CALCULATED_FIELD_MAP.put(TaskField.PREDECESSORS, Task::calculatePredecessors); CALCULATED_FIELD_MAP.put(TaskField.SUCCESSORS, Task::calculateSuccessors); + CALCULATED_FIELD_MAP.put(TaskField.ACTIVITY_PERCENT_COMPLETE, Task::calculateActivityPercentComplete); CALCULATED_FIELD_MAP.put(TaskField.CONSTRAINT_TYPE, Task::defaultConstraintType); CALCULATED_FIELD_MAP.put(TaskField.ACTIVE, Task::defaultActive); CALCULATED_FIELD_MAP.put(TaskField.TYPE, Task::defaultType); @@ -6010,5 +6049,6 @@ private Boolean defaultExpanded() dependencies.calculatedField(TaskField.CRITICAL).dependsOn(TaskField.TOTAL_SLACK, TaskField.ACTUAL_FINISH); dependencies.calculatedField(TaskField.COMPLETE_THROUGH).dependsOn(TaskField.DURATION, TaskField.ACTUAL_START, TaskField.PERCENT_COMPLETE); dependencies.calculatedField(TaskField.EXTERNAL_PROJECT).dependsOn(TaskField.SUBPROJECT_FILE, TaskField.EXTERNAL_TASK); + dependencies.calculatedField(TaskField.ACTIVITY_PERCENT_COMPLETE).dependsOn(TaskField.PERCENT_COMPLETE_TYPE, TaskField.PERCENT_COMPLETE, TaskField.PERCENT_WORK_COMPLETE, TaskField.PHYSICAL_PERCENT_COMPLETE); } } diff --git a/src/main/java/net/sf/mpxj/TaskField.java b/src/main/java/net/sf/mpxj/TaskField.java index 25adba0c15..b43d51f246 100644 --- a/src/main/java/net/sf/mpxj/TaskField.java +++ b/src/main/java/net/sf/mpxj/TaskField.java @@ -1037,7 +1037,8 @@ public enum TaskField implements FieldType REMAINING_WORK_NONLABOR(DataType.DURATION), SHOW_START_TEXT(DataType.BOOLEAN), SHOW_FINISH_TEXT(DataType.BOOLEAN), - SHOW_DURATION_TEXT(DataType.BOOLEAN); + SHOW_DURATION_TEXT(DataType.BOOLEAN), + ACTIVITY_PERCENT_COMPLETE(DataType.PERCENTAGE); /** * Constructor.