[Canonical page](<https://docs.dhtmlx.com/planning-engine/rust/api/core/changes/task-update/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# TaskUpdate

An edit to one existing task of a live project. It goes in [`SchedulingChanges::tasks`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/changes/scheduling-changes.md>)`.update`, which [`Project::apply`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#apply>) and [`Project::preview`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#preview>) take. Create it with [`TaskUpdate::new`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/changes/task-update.md#new>), then set the fields to change.

## Declaration

```rust
#[derive(Clone, Debug)]
pub struct TaskUpdate {
    pub id: Id,
    pub parent: Patch<Id>,
    pub start_date: Patch<DateTime>,
    pub end_date: Patch<DateTime>,
    pub duration: Patch<f64>,
    pub constraint_type: Patch<ConstraintType>,
    pub constraint_date: Patch<DateTime>,
    pub auto_scheduling: Patch<bool>,
    pub unscheduled: Patch<bool>,
    pub progress: Patch<f64>,
    pub calendar_id: Patch<Id>,
    pub priority: Patch<u16>,
    pub leveling_delay: Patch<f64>,
    pub pauses: Patch<Vec<Pause>>,
}
```

## Constructors

### new

```rust
pub fn new(id: impl Into<Id>) -> TaskUpdate
```

Creates an update for the task with the given id. Accepts anything that converts into an [`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>).

**Returns** an update with every field except `id` at [`Patch::Missing`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/changes/patch.md>), so it changes nothing until a field is set.

## Fields

Every field except `id` is a [`Patch`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/changes/patch.md>): `Missing` leaves the stored value, `Value` sets it, `Null` clears it. The **On `Null`** column shows what `Null` leaves behind. For the meaning of each value, see the field of the same name on [`TaskData`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-data.md#fields>).

| Field | Type | On `Null` | Description |
|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>) | required | Id of the task to edit. |
| `parent` | `Patch<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>` | top level | Moves the task under another parent. A value equal to [`SchedulingConfig::root_id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/scheduling-config.md#root_id>) is read as `Null`. |
| `start_date` | `Patch<`[`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>)`>` | `None` | New start, for example after a drag. |
| `end_date` | `Patch<`[`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>)`>` | `None` | New end. |
| `duration` | `Patch<f64>` | `None` | New working time in the task's `duration_unit`, for example after a resize. |
| `constraint_type` | `Patch<`[`ConstraintType`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/constraint-type.md>)`>` | `None` | New date constraint. |
| `constraint_date` | `Patch<`[`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>)`>` | `None` | New constraint date. |
| `auto_scheduling` | `Patch<bool>` | `true` | `false` fixes the task. |
| `unscheduled` | `Patch<bool>` | `false` | `true` takes the task out of scheduling. |
| `progress` | `Patch<f64>` | `0.0` | New completed share. |
| `calendar_id` | `Patch<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>` | `None` | New working calendar. |
| `priority` | `Patch<u16>` | `500` | New leveling priority. |
| `leveling_delay` | `Patch<f64>` | `0.0` | New leveling delay, elapsed time in the task's `duration_unit`. |
| `pauses` | `Patch<Vec<`[`Pause`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/pause.md>)`>>` | empty | Replaces the whole pause list. |

## Dates after an update

An update starts from the task's current scheduled start, end and duration. On a plain task ([`TaskType::Task`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-type.md>)), the fields set in the update decide which of the three is kept and which is derived again:

| Set in the update | Kept | Derived again |
|---|---|---|
| `start_date`, no `end_date` | start, duration | end |
| `end_date` only | end, start | duration |
| `duration`, no `end_date` | start, duration | end |
| `start_date` + `end_date`, no `duration` | start, end | duration |
| `calendar_id`, or `parent` under [`CalendarMode::TaskInherited`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/calendar-mode.md>), no date field | start, duration | end |
| `pauses` or `leveling_delay`, no date field | start, duration | end |

- A `leveling_delay` update with neither `start_date` nor `end_date` also moves the stored dates by the change in delay (elapsed time) and snaps them onto working time.
- When a task works on several calendars in a project with [`schedule_from_end`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/scheduling-config.md>), a `pauses` or `leveling_delay` update without dates keeps the end and derives the start instead.
- Under `CalendarMode::TaskInherited`, a `calendar_id` or `parent` update also re-derives the end of each descendant plain task that has no `calendar_id` of its own. Its start and duration stay.
- An explicit start on non-working time stays unsnapped when the task has no predecessor.

To write a result entry back as an update, see [`Mutation`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md#writing-back>).

## Errors

An update is rejected as a single operation, at path `tasks.update[i]`. [`Project::apply`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#apply>) and [`Project::preview`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#preview>) describe how a rejection is reported.

| Message | When it occurs |
|---|---|
| `unknown task id` | no task has `id` |
| a validation message | the edited task breaks a [`TaskData` rule](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-data.md#errors>) or a [`ProjectData` rule](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/project-data.md#validation>), for example an unknown `calendar_id` or `parent` |

## Example

Move a task to a new start and push its finish out by a day:

```rust
use plen_core::{
    DateTime, Patch, Project, ProjectData, ProjectOptions, SchedulingChanges, SolveOptions,
    TaskData, TaskUpdate,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let monday = DateTime::from_ymd_hm(2026, 4, 6, 8, 0).ok_or("invalid date")?;
    let wednesday = DateTime::from_ymd_hm(2026, 4, 8, 8, 0).ok_or("invalid date")?;

    let data = ProjectData {
        tasks: vec![TaskData {
            start_date: Some(monday),
            duration: Some(2.0),
            ..TaskData::new("design")
        }],
        ..Default::default()
    };

    let mut project = Project::new(ProjectOptions::default());
    let options = SolveOptions::default();
    project.solve(Some(data), &options)?;

    let mut update = TaskUpdate::new("design");
    update.start_date = Patch::Value(wednesday);
    update.duration = Patch::Value(3.0);

    let mut changes = SchedulingChanges::default();
    changes.tasks.update.push(update);

    let report = project.apply(&changes)?;
    if report.rejected.is_empty() {
        let result = project.solve(None, &options)?;
        println!("{:?}", result.updates);
    }
    Ok(())
}
```

## Related

- [`TaskData`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-data.md>) - the record an update edits
- [`ApplyReport`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/changes/apply-report.md>) - reports whether the update was applied
- [`Mutation`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>) - a result entry that can be written back as an update
- [Data Updates](<https://docs.dhtmlx.com/planning-engine/rust/live-projects/editing-a-project.md>) - shows task updates and which dates they keep
