[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/changes/apply-report/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# ApplyReport

The result of one [`Project#apply`](<https://docs.dhtmlx.com/planning-engine/java/api/project-apply.md>) call. It lists which operations of the [`SchedulingChanges`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/scheduling-changes.md>) were applied and which were rejected. It also lists the records the edit removed, generated or dropped as a side effect, and gives the project's revision afterwards. `apply` returns a new instance on every call.

## Declaration

```java
public class ApplyReport extends ValueRecord implements DeepCloneable<ApplyReport>
```

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `applied` | [`Vec`](<https://docs.dhtmlx.com/planning-engine/java/api/support/vec.md>)`<`[`AppliedOperation`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/apply-report.md#appliedoperation>)`>` | empty | Operations that were applied, in the order they ran. |
| `rejected` | `Vec<`[`RejectedOperation`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/rejected-operation.md>)`>` | empty | Operations that were rejected, in the order they ran. Empty when everything was applied. |
| `effects` | [`ChangeEffects`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/apply-report.md#changeeffects>) | `new ChangeEffects()` | Records removed, generated or dropped by the applied operations. |
| `needsResync` | `boolean` | `false` | `true` when `rejected` isn't empty. |
| `revision` | `long` | `0L` | The project's revision counter after this call. |

### applied

```java
public Vec<AppliedOperation> applied = new Vec<AppliedOperation>();
```

One entry per applied operation. Each entry's `path` names the operation in the change set.

### rejected

```java
public Vec<RejectedOperation> rejected = new Vec<RejectedOperation>();
```

One entry per rejected operation, with its path and the reason. A rejected operation leaves no partial edit, and the operations after it still run.

### effects

```java
public ChangeEffects effects = new ChangeEffects();
```

Side effects of the applied operations only. A rejected operation adds nothing here.

### needsResync

```java
public boolean needsResync = false;
```

`true` exactly when at least one operation was rejected. From then on, `apply`, `solve(null, …)` and [`level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>) throw [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/java/api/errors/project-exception.md>) with `code == ProjectError.NEEDS_RESYNC` until a full [`solve(data, …)`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>). See [Recover from rejected changes](<https://docs.dhtmlx.com/planning-engine/java/how-to/recover-from-rejected-changes.md>).

### revision

```java
public long revision = 0L;
```

The project's revision counter after the apply. Every `apply` raises it, so a higher value means a later state of the same project.

## Methods

### withApplied, withRejected, withEffects, withNeedsResync, withRevision

```java
public ApplyReport withApplied(Vec<AppliedOperation> value)
public ApplyReport withApplied(java.util.Collection<? extends AppliedOperation> value)
public ApplyReport withRejected(Vec<RejectedOperation> value)
public ApplyReport withRejected(java.util.Collection<? extends RejectedOperation> value)
public ApplyReport withEffects(ChangeEffects value)
public ApplyReport withNeedsResync(boolean value)
public ApplyReport withRevision(long value)
```

Each setter assigns its field and returns this instance for chaining. The `Collection` overloads copy the elements into a new `Vec`, and a `null` collection sets the field to `null`.

**Returns**: this `ApplyReport`.

### deepClone

```java
public ApplyReport deepClone()
```

Returns a copy that shares no list or nested record with this instance.

**Returns**: a new `ApplyReport` with the same values.

### copy

```java
public ApplyReport copy()
```

Returns a shallow copy. The copy shares the `applied` and `rejected` lists and the `effects` record with this instance.

**Returns**: a new `ApplyReport` with the same field values.

### equals, hashCode, toString

```java
public boolean equals(Object other)
public int hashCode()
public String toString()
```

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). Two reports are equal when their public fields are equal: the lists element by element, `effects` by value. `toString()` lists the fields.

## AppliedOperation

One applied operation, identified by its position in the change set.

```java
public class AppliedOperation extends ValueRecord implements DeepCloneable<AppliedOperation> {
  public String path = null;

  public AppliedOperation withPath(String value);
  public AppliedOperation deepClone();
  public AppliedOperation copy();
}
```

| Field | Type | Default | Description |
|---|---|---|---|
| `path` | `String` | `null` | The operation's group, list and index in the change set, in the form `{group}.{list}[{index}]`, for example `tasks.update[0]`, `links.add[2]` or `assignments.remove[1]`. Groups: `tasks`, `links`, `resources`, `assignments`. Lists: `add`, `update`, `remove`. Always set in a report. |

`withPath` sets the field and returns this instance. `equals`, `hashCode` and `toString` come from `ValueRecord`.

## ChangeEffects

The records an apply removed, generated or dropped beyond the ones the change set names directly. Use it to keep a client-side copy of the project in sync.

```java
public class ChangeEffects extends ValueRecord implements DeepCloneable<ChangeEffects> {
  public Vec<Id> removedTasks = new Vec<Id>();
  public Vec<Id> removedLinks = new Vec<Id>();
  public Vec<Id> generatedLinks = new Vec<Id>();
  public Vec<Id> droppedLinks = new Vec<Id>();
  public Vec<Id> removedAssignments = new Vec<Id>();
  public Vec<Id> generatedAssignments = new Vec<Id>();
  public Vec<Id> droppedAssignments = new Vec<Id>();

  public ChangeEffects deepClone();
  public ChangeEffects copy();
}
```

Every list holds [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) values and is empty when nothing of that kind happened.

| Field | Type | Description |
|---|---|---|
| `removedTasks` | `Vec<Id>` | Tasks deleted by `tasks.remove`, including every descendant of a removed task. |
| `removedLinks` | `Vec<Id>` | Links deleted by `links.remove`, plus links whose source or target was a removed task. |
| `generatedLinks` | `Vec<Id>` | Ids created for `links.add` entries without an `id`, in the form `$generated_link_{n}`. |
| `droppedLinks` | `Vec<Id>` | Links that stay in the data but were taken out of scheduling by this apply, for example because an endpoint became unscheduled. See [Links that get dropped](<https://docs.dhtmlx.com/planning-engine/java/scheduling/links-constraints-summaries.md#links-that-get-dropped>). |
| `removedAssignments` | `Vec<Id>` | Assignments deleted by `assignments.remove`, plus assignments of removed tasks and removed resources. Cascaded assignments without an id aren't listed. |
| `generatedAssignments` | `Vec<Id>` | Ids created for `assignments.add` entries without an `id`, in the form `$generated_assignment_{n}`. |
| `droppedAssignments` | `Vec<Id>` | Assignments that stay in the data but were taken out of scheduling by this apply because their task became unscheduled. They come back when the task is scheduled again. |

Each field has a fluent setter in two forms, `withRemovedTasks(Vec<Id>)` and `withRemovedTasks(Collection<? extends Id>)`, and the same for the other six lists. `deepClone()` copies every list. `copy()` returns a shallow copy that shares the lists. `equals` compares the seven lists element by element.

## Example

Remove a task that has a link and an assignment, and add a link without an id.

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

public class ApplyReportExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 8, 10, 8, 0);
    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("a")).withStartDate(monday).withDuration(1.0),
            new TaskData(Id.str("b")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("c")).withStartDate(monday).withDuration(1.0)))
        .withLinks(List.of(new LinkData()
            .withId(Id.str("ab")).withSource(Id.str("a")).withTarget(Id.str("b"))))
        .withResources(List.of(new ResourceData().withId(Id.str("dev"))))
        .withAssignments(List.of(new AssignmentData()
            .withId(Id.str("as1")).withTask(Id.str("b")).withResource(Id.str("dev")).withValue(1.0)));

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

    SchedulingChanges changes = new SchedulingChanges();
    changes.tasks.remove.add(Id.str("b"));
    changes.links.add.add(new LinkAdd().withSource(Id.str("a")).withTarget(Id.str("c")));

    ApplyReport report = project.apply(changes);

    for (AppliedOperation op : report.applied) {
      System.out.println("applied " + op.path);              // tasks.remove[0], links.add[0]
    }

    ChangeEffects effects = report.effects;
    System.out.println(effects.removedTasks);                // [b]
    System.out.println(effects.removedLinks);                // [ab]
    System.out.println(effects.removedAssignments);          // [as1]
    System.out.println(effects.generatedLinks);              // [$generated_link_1]
  }
}
```

## Related

- [`Project#apply`](<https://docs.dhtmlx.com/planning-engine/java/api/project-apply.md>) - the call that returns the report
- [`RejectedOperation`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/rejected-operation.md>) - one entry of `rejected`
- [`SchedulingChanges`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/scheduling-changes.md>) - the change set the report describes
- [Recover from rejected changes](<https://docs.dhtmlx.com/planning-engine/java/how-to/recover-from-rejected-changes.md>) - resyncing after `needsResync`
- [Data Updates](<https://docs.dhtmlx.com/planning-engine/java/live-projects/editing-a-project.md#rejections-and-resync>) - applying change sets and reading the report
