AssignmentUpdate#

An edit to one existing assignment of a live project. It goes in the update list of SchedulingChanges.assignments, which Project#apply and Project#preview take. Create it with new AssignmentUpdate(id) and set the fields to change with the withX setters.

Declaration#

package org.dhtmlx.plen;

public class AssignmentUpdate extends ValueRecord implements DeepCloneable<AssignmentUpdate>

Constructors#

AssignmentUpdate(Id)#

public AssignmentUpdate(Id id)

Creates an update for the assignment with the given id. Every other field is Patch.missing(), so the update changes nothing until a field is set.

Name Type Description
id Id Id of the assignment to edit. Build it with Id.num(...) or Id.str(...).

Fields#

Every field except id is a Patch<T>. Patch.missing() (the default) keeps the stored value, Patch.of(value) sets it, and Patch.nullValue() clears it. The On nullValue() column shows what clearing does. For the meaning of each value, see the field of the same name on AssignmentData.

Field Type On nullValue() Description
id Id - Id of the assignment to edit.
task Patch<Id> rejected Moves the assignment to another task.
resource Patch<Id> rejected Gives the assignment to another resource.
value Patch<Double> rejected New utilization rate.
offset Patch<Double> null New start of the slice. null books from the task start.
duration Patch<Double> null New length of the slice. null books up to the task end.

Don't use Patch.of(null) on task, resource or value. It throws NullPointerException when the change is applied. Use Patch.nullValue() to clear offset or duration.

The edited assignment must still pass the AssignmentData checks: value and duration finite and greater than 0, offset finite and 0 or greater, and task and resource naming existing records.

Effect on dates#

  • offset, duration and value change resource load only. They never move a task.
  • task and resource move dates only when the task then works on a different set of calendars, for example when the new resource has its own calendar in CalendarMode.RESOURCE.
  • An assignment moved to an unscheduled task stays in the project but books no load. Its id is listed in ChangeEffects.droppedAssignments.

Methods#

withId, withTask, withResource, withValue, withOffset, withDuration#

public AssignmentUpdate withId(Id value)
public AssignmentUpdate withTask(Patch<Id> value)
public AssignmentUpdate withResource(Patch<Id> value)
public AssignmentUpdate withValue(Patch<Double> value)
public AssignmentUpdate withOffset(Patch<Double> value)
public AssignmentUpdate withDuration(Patch<Double> value)

Each sets the field of the same name and returns this instance for chaining.

deepClone#

public AssignmentUpdate deepClone()

Returns a new AssignmentUpdate with the same field values. Id and Patch values are immutable, so the copy is fully independent.

copy#

public AssignmentUpdate copy()

Returns a shallow copy. Because every field holds an immutable value, it behaves like deepClone().

equals, hashCode, toString#

Inherited from ValueRecord. Two updates are equal when all six fields are equal. toString() lists the fields, for logging; each patch prints only its kind, e.g. Patch{kind=VALUE}.

Errors#

An update is one operation, at path assignments.update[i]. A failing update goes into ApplyReport.rejected as a RejectedOperation; it isn't thrown. Project#apply describes what a rejection does to the project.

Message When it occurs
unknown assignment id No assignment has id.
required field cannot be null task, resource or value is Patch.nullValue().
a validation message The edited assignment fails an AssignmentData check, for example an unknown resource or a value of 0.

Example#

Hand Ben's review to Cara and narrow it to the last day of the task.

import java.util.List;
import org.dhtmlx.plen.*;

public class AssignmentUpdateExample {
  public static void main(String[] args) throws Exception {
    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.num(1))
                .withStartDate(Moment.fromYmdHm(2026, 4, 6, 8, 0))
                .withDuration(5.0)))
        .withResources(List.of(
            new ResourceData().withId(Id.str("ben")),
            new ResourceData().withId(Id.str("cara"))))
        .withAssignments(List.of(
            new AssignmentData()
                .withId(Id.str("review"))
                .withTask(Id.num(1))
                .withResource(Id.str("ben"))
                .withValue(0.5)));

    Project project = new Project();
    project.solve(data, new SolveOptions());

    SchedulingChanges changes = new SchedulingChanges();
    changes.assignments.update.add(new AssignmentUpdate(Id.str("review"))
        .withResource(Patch.of(Id.str("cara")))
        .withOffset(Patch.of(4.0))
        .withDuration(Patch.of(1.0)));

    ApplyReport report = project.apply(changes);
    for (RejectedOperation rejected : report.rejected) {
      System.out.println(rejected.path + ": " + rejected.message);
    }
  }
}