Duration Auto calculating issue

I am trying to add JSON data into an MPP file using the Aspose API. My data contains start date, end date, and a given duration value. However, when I insert it into the MPP file, the API automatically recalculates the duration based on the start and end dates.
I want the given duration from my JSON to remain unchanged. How can I stop the auto-calculation and keep my provided duration value?

@NaveenVenkatesh

To prevent the Aspose API from automatically recalculating the duration when you insert your JSON data into an MPP file, you can set the calculation mode of the project to manual. This ensures that the API respects the duration value you provide in your JSON data.

Cause: By default, the Aspose API recalculates task durations based on the start and end dates, which can lead to unintended changes in your specified duration.

Solution: To maintain your specified duration, you need to set the calculation mode to manual before inserting your data.

Next Steps: Follow these steps to implement the solution:

  1. Load your MPP file: Start by loading your existing MPP file into a Project object.
  2. Set Calculation Mode: Change the calculation mode of the project to manual using the CalculationMode property.
  3. Insert your data: Add your tasks with the specified start date, end date, and duration.
  4. Save the project: Finally, save the project back to the MPP format.

Here’s a code snippet to illustrate this:

using Aspose.Tasks;

public void AddTaskWithFixedDuration(string mppFilePath, string taskName, DateTime startDate, DateTime endDate, TimeSpan duration)
{
    // Load the project
    Project project = new Project(mppFilePath);

    // Set calculation mode to manual
    project.CalculationMode = CalculationMode.Manual;

    // Create a new task
    Task task = project.RootTask.Children.Add(taskName);
    task.Set(Tsk.Start, startDate);
    task.Set(Tsk.Finish, endDate);
    task.Set(Tsk.Duration, duration);

    // Save the project
    project.Save(mppFilePath, SaveFileFormat.MPP);
}

By setting the calculation mode to manual, the API will not recalculate the duration based on the start and end dates, allowing you to maintain the duration you specified in your JSON data.

If you have any further questions or need additional assistance, feel free to ask!

What version of aspose.tasks should be use?

See the orignal mpp ages >>

[image]

Generated mpp >>

[image]

This is the code below we used>

Input json data is like this >>>

{

“task_id”: “1.4”,

“progress”: “”,

“description”: “Workstream Details - Dispatch”,

“duration”: “63.0d”,

“start_date”: “03/17/2025”,

“end_date”: “06/13/2025”,

“dependencies”: “4SS”,

“successors”: “”,

“stakeholder_id”: “”,

“outline_number”: “1.4”,

“numeric_id”: “60”

},

//Creating the mpp from json code below (Python)

def create_corrected_mpp_from_json(json_data, output_path):

“”“Create MPP file using correct Aspose.Tasks API methods”“”

try:

# Create new project

project = at.Project()

project.name = “Customer Transition Plan”

print(f":white_check_mark: Created project: {project.name}")

# Track tasks by outline number for hierarchy and dependency linking

tasks_by_outline = {}

tasks_by_numeric_id = {}

tasks_by_task_id = {} # Add mapping by task_id

# First pass: create all tasks

for i, task_data in enumerate(json_data):

try:

# Get task details

description = task_data.get(‘description’, ‘’)

outline_number = task_data.get(‘outline_number’, ‘’)

task_id = task_data.get(‘task_id’, ‘’)

numeric_id = task_data.get(‘numeric_id’, i)

if not description or not outline_number:

print(f":warning: Skipping task with missing description or outline: {task_id}")

continue

# Create task

if outline_number == ‘0’ or outline_number == ‘1’:

# Top-level task

task = project.root_task.children.add(description)

else:

# Find parent task

parent_outline = ‘.’.join(outline_number.split(‘.’)[:-1])

if parent_outline in tasks_by_outline:

parent_task = tasks_by_outline[parent_outline]

task = parent_task.children.add(description)

else:

# Fallback to root level

task = project.root_task.children.add(description)

# Set basic task properties using ONLY methods that exist

# Start date

if task_data.get(‘start_date’):

start_date = parse_date(task_data.get(‘start_date’))

if start_date:

try:

task.start = start_date

except Exception as e:

print(f":warning: Could not set start date for task ‘{description}’: {e}")

# End date

if task_data.get(‘end_date’):

end_date = parse_date(task_data.get(‘end_date’))

if end_date:

try:

task.finish = end_date

except Exception as e:

print(f":warning: Could not set finish date for task ‘{description}’: {e}")

# Duration (only for non-summary tasks)

duration = task_data.get(‘duration’)

if duration and duration != ‘0d’ and duration != 0:

duration_days = parse_duration(duration)

if duration_days > 0:

try:

# Use duration_text which should exist

task.duration_text = f"{duration_days}d"

except Exception as e:

print(f":warning: Could not set duration for task ‘{description}’: {e}")

# Progress

progress = task_data.get(‘progress’)

if progress and progress != ‘’:

try:

task.percent_complete = parse_float(progress)

except Exception as e:

print(f":warning: Could not set progress for task ‘{description}’: {e}")

# Store task for hierarchy and dependency linking

tasks_by_outline[outline_number] = task

if numeric_id is not None:

tasks_by_numeric_id[str(numeric_id)] = task # Convert to string for consistent lookup

if task_id: # Store by task_id for dependency linking

tasks_by_task_id[task_id] = task

if i % 20 == 0:

print(f":white_check_mark: Created task {i+1}/{len(json_data)}: {description[:50]}…")

except Exception as e:

print(f":x: Error creating task {task_data.get(‘task_id’, ‘unknown’)}: {e}")

continue

print(f":white_check_mark: Project created with {len(tasks_by_outline)} tasks")

# Second pass: set dependencies (using correct API)

print(f":arrows_counterclockwise: Setting dependencies…")

for i, task_data in enumerate(json_data):

try:

outline_number = task_data.get(‘outline_number’, ‘’)

if outline_number not in tasks_by_outline:

continue

task = tasks_by_outline[outline_number]

description = task_data.get(‘description’, ‘’)

# Set dependencies (predecessors) - using correct API

dependencies = task_data.get(‘dependencies’, ‘’)

if dependencies:

try:

# Parse dependency string (e.g., “2FS”, “3FS”, “23SS”, “3FS,24FS”)

dep_parts = dependencies.split(‘,’)

for dep_part in dep_parts:

dep_part = dep_part.strip()

if dep_part:

# Extract task ID and relationship type from dependency

# Format: “2FS” = Task ID 2, Finish-to-Start

# Format: “23SS” = Task ID 23, Start-to-Start

dep_match = re.match(r’(\d+)([A-Z]+)', dep_part)

if dep_match:

dep_row_number = int(dep_match.group(1)) # Row number from MPP (1, 2, 3…)

dep_type = dep_match.group(2) # Relationship type (e.g., “FS”, “SS”)

# Convert row number to numeric_id by subtracting 1

# Original MPP: Row 1, 2, 3, 4… maps to numeric_id: 0, 1, 2, 3…

dep_numeric_id = str(dep_row_number - 1)

# Find the predecessor task by numeric_id (which is what dependencies reference)

if dep_numeric_id in tasks_by_numeric_id:

predecessor = tasks_by_numeric_id[dep_numeric_id]

# Determine link type based on dependency type

link_type = at.TaskLinkType.FINISH_TO_START # Default

if dep_type == “SS”:

link_type = at.TaskLinkType.START_TO_START

elif dep_type == “FF”:

link_type = at.TaskLinkType.FINISH_TO_FINISH

elif dep_type == “SF”:

link_type = at.TaskLinkType.START_TO_FINISH

# Create task link using correct API

try:

link = project.task_links.add(predecessor, task)

link.link_type = link_type

print(f":white_check_mark: Added dependency: Row {dep_row_number} ({dep_numeric_id}){dep_type} → {description[:30]}…")

except Exception as e:

print(f":warning: Could not create dependency link: {e}")

else:

print(f":warning: Predecessor task Row {dep_row_number} (numeric_id {dep_numeric_id}) not found for task ‘{description[:30]}…’")

else:

print(f":warning: Could not parse dependency format: ‘{dep_part}’ for task ‘{description[:30]}…’")

except Exception as e:

print(f":warning: Could not process dependencies for task ‘{description}’: {e}")

except Exception as e:

print(f":x: Error setting dependencies for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")

continue

# Third pass: try to set resources using correct API

print(f":arrows_counterclockwise: Setting resources…")

for i, task_data in enumerate(json_data):

try:

outline_number = task_data.get(‘outline_number’, ‘’)

if outline_number not in tasks_by_outline:

continue

task = tasks_by_outline[outline_number]

description = task_data.get(‘description’, ‘’)

stakeholder_id = task_data.get(‘stakeholder_id’, ‘’)

if stakeholder_id:

try:

# Create resource if it doesn’t exist

resource_name = str(stakeholder_id).strip()

if resource_name:

# Try to find existing resource or create new one

resource = None

for existing_resource in project.resources:

if existing_resource.name == resource_name:

resource = existing_resource

break

if not resource:

resource = project.resources.add(resource_name)

# Try different methods to assign resource to task

try:

# Method 1: Try direct assignment

task.resources.add(resource)

print(f":white_check_mark: Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’")

except AttributeError:

try:

# Method 2: Try using resource assignment collection

assignment = project.resource_assignments.add(task, resource)

print(f":white_check_mark: Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’ (via assignment)")

except Exception as e2:

print(f":warning: Could not assign resource using any method: {e2}")

except Exception as e:

print(f":warning: Could not process resource for task ‘{description}’: {e}")

except Exception as e:

print(f":x: Error setting resources for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")

continue

# Save the project

print(f":arrows_counterclockwise: Saving project to: {output_path}")

try:

# Try to save as MPP first

project.save(output_path, at.saving.SaveFileFormat.MPP)

print(f":white_check_mark: MPP file saved successfully!")

return True

except Exception as e:

print(f":warning: Could not save as MPP: {e}")

# Fallback: try to save as XML

xml_path = output_path.replace(‘.mpp’, ‘.xml’)

try:

project.save(xml_path, at.saving.SaveFileFormat.XML)

print(f":white_check_mark: XML file saved successfully: {xml_path}")

print(f":bulb: You can open this XML file in Microsoft Project")

return True

except Exception as e2:

print(f":x: Could not save as XML either: {e2}")

return False

except Exception as e:

print(f":x: Error creating project: {e}")

import traceback

traceback.print_exc()

return False


From: Naveen Venkatesh Naveen@coworked.ai
Sent: Wednesday, August 13, 2025 2:49 PM
To: Ravi Linganuri ravi@coworked.ai; Selva Senthamaraikannan Selva@coworked.ai
Subject: Fw: [Free Support Forum - aspose.com] [Aspose.Note Product Family] Duration Auto calculating issue


From: Admin Containerize via Free Support Forum - aspose.com forum@aspose.com
Sent: 13 August 2025 14:47
To: Naveen Venkatesh naveen@coworked.ai
Subject: [Free Support Forum - aspose.com] [Aspose.Note Product Family] Duration Auto calculating issue

You don’t often get email from forum@aspose.com. Learn why this is important

45x45 Professionalize.Discourse
August 13

@NaveenVenkatesh

To prevent the Aspose API from automatically recalculating the duration when you insert your JSON data into an MPP file, you can set the calculation mode of the project to manual. This ensures that the API respects the duration value you provide in your JSON data.

Cause: By default, the Aspose API recalculates task durations based on the start and end dates, which can lead to unintended changes in your specified duration.

Solution: To maintain your specified duration, you need to set the calculation mode to manual before inserting your data.

Next Steps: Follow these steps to implement the solution:

  1. Load your MPP file: Start by loading your existing MPP file into a Project object.
  2. Set Calculation Mode: Change the calculation mode of the project to manual using the CalculationMode property.
  3. Insert your data: Add your tasks with the specified start date, end date, and duration.
  4. Save the project: Finally, save the project back to the MPP format.

Here’s a code snippet to illustrate this:

using Aspose.Tasks;

public void AddTaskWithFixedDuration(string mppFilePath, string taskName, DateTime startDate, DateTime endDate, TimeSpan duration)
{
    // Load the project
    Project project = new Project(mppFilePath);

    // Set calculation mode to manual
    project.CalculationMode = CalculationMode.Manual;

    // Create a new task
    Task task = project.RootTask.Children.Add(taskName);
    task.Set(Tsk.Start, startDate);
    task.Set(Tsk.Finish, endDate);
    task.Set(Tsk.Duration, duration);

    // Save the project
    project.Save(mppFilePath, SaveFileFormat.MPP);
}

By setting the calculation mode to manual, the API will not recalculate the duration based on the start and end dates, allowing you to maintain the duration you specified in your JSON data.

If you have any further questions or need additional assistance, feel free to ask!

but still that calculation happens need this working with python and not C+.

def create_corrected_mpp_from_json(json_data, output_path):

“”“Create MPP file using correct Aspose.Tasks API methods”“”

try:

# Create new project

project = at.Project()

project.name = “Customer Transition Plan”

# CRITICAL: Set calculation mode to Manual as recommended by Aspose team

try:

project.calculation_mode = at.CalculationMode.MANUAL

print(“:white_check_mark: Set calculation mode to MANUAL - Aspose will respect our values”)

except Exception as e:

print(f":warning: Could not set calculation mode to MANUAL: {e}")

print(" Duration values may be recalculated automatically")

print(f":white_check_mark: Created project: {project.name}")

# Track tasks by outline number for hierarchy and dependency linking

tasks_by_outline = {}

tasks_by_numeric_id = {}

tasks_by_task_id = {} # Add mapping by task_id

# First pass: create all tasks

for i, task_data in enumerate(json_data):

try:

# Get task details

description = task_data.get(‘description’, ‘’)

outline_number = task_data.get(‘outline_number’, ‘’)

task_id = task_data.get(‘task_id’, ‘’)

numeric_id = task_data.get(‘numeric_id’, i)

if not description or not outline_number:

print(f":warning: Skipping task with missing description or outline: {task_id}")

continue

# Create task

if outline_number == ‘0’ or outline_number == ‘1’:

# Top-level task

task = project.root_task.children.add(description)

else:

# Find parent task

parent_outline = ‘.’.join(outline_number.split(‘.’)[:-1])

if parent_outline in tasks_by_outline:

parent_task = tasks_by_outline[parent_outline]

task = parent_task.children.add(description)

else:

# Fallback to root level

task = project.root_task.children.add(description)

# Set basic task properties using correct Python API syntax

# Direct property assignment, not .set() method

# Start date - set directly on task property

if task_data.get(‘start_date’):

start_date = parse_date(task_data.get(‘start_date’))

if start_date:

try:

task.start = start_date

except Exception as e:

print(f":warning: Could not set start date for task ‘{description}’: {e}")

# End date - set directly on task property

if task_data.get(‘end_date’):

end_date = parse_date(task_data.get(‘end_date’))

if end_date:

try:

task.finish = end_date

except Exception as e:

print(f":warning: Could not set finish date for task ‘{description}’: {e}")

# Duration - try different approaches since Duration.from_days() doesn’t exist

duration = task_data.get(‘duration’)

if duration and duration != ‘0d’ and duration != 0:

duration_days = parse_duration(duration)

if duration_days > 0:

try:

# Try using duration_text property first

task.duration_text = f"{duration_days}d"

print(f":white_check_mark: Set duration_text: {duration_days}d for task ‘{description[:30]}…’")

except Exception as e:

print(f":warning: duration_text failed: {e}")

try:

# Try creating Duration object with different approaches

from datetime import timedelta

duration_timedelta = timedelta(days=duration_days)

# Try different Duration creation methods

try:

# Method 1: Try Duration constructor with timedelta

duration_obj = at.Duration(duration_timedelta)

task.duration = duration_obj

print(f":white_check_mark: Set duration using Duration(timedelta) for task ‘{description[:30]}…’")

except:

try:

# Method 2: Try Duration constructor with string

duration_obj = at.Duration(f"{duration_days}d")

task.duration = duration_obj

print(f":white_check_mark: Set duration using Duration(‘{duration_days}d’) for task ‘{description[:30]}…’")

except:

# Method 3: Try Duration constructor with integer days

duration_obj = at.Duration(duration_days)

task.duration = duration_obj

print(f":white_check_mark: Set duration using Duration({duration_days}) for task ‘{description[:30]}…’")

except Exception as e2:

print(f":warning: All duration methods failed for task ‘{description}’: {e2}")

print(f" Duration value: {duration_days}d")

# Progress

progress = task_data.get(‘progress’)

if progress and progress != ‘’:

try:

task.percent_complete = parse_float(progress)

except Exception as e:

print(f":warning: Could not set progress for task ‘{description}’: {e}")

# Store task for hierarchy and dependency linking

tasks_by_outline[outline_number] = task

if numeric_id is not None:

tasks_by_numeric_id[str(numeric_id)] = task # Convert to string for consistent lookup

if task_id: # Store by task_id for dependency linking

tasks_by_task_id[task_id] = task

if i % 20 == 0:

print(f":white_check_mark: Created task {i+1}/{len(json_data)}: {description[:50]}…")

except Exception as e:

print(f":x: Error creating task {task_data.get(‘task_id’, ‘unknown’)}: {e}")

continue

print(f":white_check_mark: Project created with {len(tasks_by_outline)} tasks")

print(“:white_check_mark: All durations, start dates, and end dates set using correct Python API syntax”)

# Second pass: set dependencies (using correct API)

print(f":arrows_counterclockwise: Setting dependencies…")

for i, task_data in enumerate(json_data):

try:

outline_number = task_data.get(‘outline_number’, ‘’)

if outline_number not in tasks_by_outline:

continue

task = tasks_by_outline[outline_number]

description = task_data.get(‘description’, ‘’)

# Set dependencies (predecessors) - using correct API

dependencies = task_data.get(‘dependencies’, ‘’)

if dependencies:

try:

# Parse dependency string (e.g., “2FS”, “3FS”, “23SS”, “3FS,24FS”)

dep_parts = dependencies.split(‘,’)

for dep_part in dep_parts:

dep_part = dep_part.strip()

if dep_part:

# Extract task ID and relationship type from dependency

# Format: “2FS” = Task ID 2, Finish-to-Start

# Format: “23SS” = Task ID 23, Start-to-Start

dep_match = re.match(r’(\d+)([A-Z]+)', dep_part)

if dep_match:

dep_row_number = int(dep_match.group(1)) # Row number from MPP (1, 2, 3…)

dep_type = dep_match.group(2) # Relationship type (e.g., “FS”, “SS”)

# Convert row number to numeric_id by subtracting 1

# Original MPP: Row 1, 2, 3, 4… maps to numeric_id: 0, 1, 2, 3…

dep_numeric_id = str(dep_row_number - 1)

# Find the predecessor task by numeric_id (which is what dependencies reference)

if dep_numeric_id in tasks_by_numeric_id:

predecessor = tasks_by_numeric_id[dep_numeric_id]

# Determine link type based on dependency type

link_type = at.TaskLinkType.FINISH_TO_START # Default

if dep_type == “SS”:

link_type = at.TaskLinkType.START_TO_START

elif dep_type == “FF”:

link_type = at.TaskLinkType.FINISH_TO_FINISH

elif dep_type == “SF”:

link_type = at.TaskLinkType.START_TO_FINISH

# Create task link using correct API

try:

link = project.task_links.add(predecessor, task)

link.link_type = link_type

print(f":white_check_mark: Added dependency: Row {dep_row_number} ({dep_numeric_id}){dep_type} → {description[:30]}…")

except Exception as e:

print(f":warning: Could not create dependency link: {e}")

else:

print(f":warning: Predecessor task Row {dep_row_number} (numeric_id {dep_numeric_id}) not found for task ‘{description[:30]}…’")

else:

print(f":warning: Could not parse dependency format: ‘{dep_part}’ for task ‘{description[:30]}…’")

except Exception as e:

print(f":warning: Could not process dependencies for task ‘{description}’: {e}")

except Exception as e:

print(f":x: Error setting dependencies for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")

continue

# Third pass: try to set resources using correct API

print(f":arrows_counterclockwise: Setting resources…")

for i, task_data in enumerate(json_data):

try:

outline_number = task_data.get(‘outline_number’, ‘’)

if outline_number not in tasks_by_outline:

continue

task = tasks_by_outline[outline_number]

description = task_data.get(‘description’, ‘’)

stakeholder_id = task_data.get(‘stakeholder_id’, ‘’)

if stakeholder_id:

try:

# Create resource if it doesn’t exist

resource_name = str(stakeholder_id).strip()

if resource_name:

# Try to find existing resource or create new one

resource = None

for existing_resource in project.resources:

if existing_resource.name == resource_name:

resource = existing_resource

break

if not resource:

resource = project.resources.add(resource_name)

# Try different methods to assign resource to task

try:

# Method 1: Try direct assignment

task.resources.add(resource)

print(f":white_check_mark: Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’")

except AttributeError:

try:

# Method 2: Try using resource assignment collection

assignment = project.resource_assignments.add(task, resource)

print(f":white_check_mark: Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’ (via assignment)")

except Exception as e2:

print(f":warning: Could not assign resource using any method: {e2}")

except Exception as e:

print(f":warning: Could not process resource for task ‘{description}’: {e}")

except Exception as e:

print(f":x: Error setting resources for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")

continue

# Save the project

print(f":arrows_counterclockwise: Saving project to: {output_path}")

print(“:bulb: Using correct Python API: MANUAL mode + direct properties + Duration with timedelta”)

try:

# Try to save as MPP first

project.save(output_path, at.saving.SaveFileFormat.MPP)

print(f":white_check_mark: MPP file saved successfully!")

print(“:white_check_mark: All durations, dependencies, and dates preserved using correct Python API”)

return True

except Exception as e:

print(f":warning: Could not save as MPP: {e}")

# Fallback: try to save as XML

xml_path = output_path.replace(‘.mpp’, ‘.xml’)

try:

project.save(xml_path, at.saving.SaveFileFormat.XML)

print(f":white_check_mark: XML file saved successfully: {xml_path}")

print(f":bulb: You can open this XML file in Microsoft Project")

return True

except Exception as e2:

print(f":x: Could not save as XML either: {e2}")

return False

except Exception as e:

print(f":x: Error creating project: {e}")

import traceback

traceback.print_exc()

return False

see this code which version will work for stop auto calculating

@NaveenVenkatesh,

Apologies for any inconvenience caused. I am transferring your thread to the appropriate category, where a member of the Aspose.Tasks team will review your issue and provide assistance soon.

@NaveenVenkatesh ,
when CalculationMode.MANUAL is used, only important calculations are performed.

To turn off all calculations, CalculationMode.NONE should be used:

project.calculation_mode = at.CalculationMode.NONE