001package com.box.sdk;
002
003import com.eclipsesource.json.Json;
004import com.eclipsesource.json.JsonObject;
005import com.eclipsesource.json.JsonValue;
006import java.net.URL;
007import java.util.Date;
008
009/**
010 * Represents a task assignment on Box, which can be used to assign a task to a single user. There
011 * can be multiple assignments on a single task.
012 */
013@BoxResourceType("task_assignment")
014public class BoxTaskAssignment extends BoxResource {
015
016  /** Task Assignment URL Template. */
017  public static final URLTemplate TASK_ASSIGNMENT_URL_TEMPLATE =
018      new URLTemplate("task_assignments/%s");
019
020  /**
021   * Constructs a BoxTaskAssignment for a task assignment with a given ID.
022   *
023   * @param api the API connection to be used by the resource.
024   * @param id the ID of the task assignment.
025   */
026  public BoxTaskAssignment(BoxAPIConnection api, String id) {
027    super(api, id);
028  }
029
030  /** Deletes this task assignment. */
031  public void delete() {
032    URL url = TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
033    BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
034    request.send().close();
035  }
036
037  /**
038   * Gets information about this task assignment.
039   *
040   * @return info about this task assignment.
041   */
042  public Info getInfo() {
043    URL url = TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
044    BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
045    try (BoxJSONResponse response = request.send()) {
046      JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
047      return new Info(responseJSON);
048    }
049  }
050
051  /**
052   * Gets information about this task assignment.
053   *
054   * @param fields the fields to retrieve.
055   * @return info about this task assignment.
056   */
057  public Info getInfo(String... fields) {
058    QueryStringBuilder builder = new QueryStringBuilder();
059    if (fields.length > 0) {
060      builder.appendParam("fields", fields);
061    }
062    URL url =
063        TASK_ASSIGNMENT_URL_TEMPLATE.buildWithQuery(
064            this.getAPI().getBaseURL(), builder.toString(), this.getID());
065    BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
066    try (BoxJSONResponse response = request.send()) {
067      JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
068      return new Info(responseJSON);
069    }
070  }
071
072  /**
073   * Updates the information about this task assignment with any info fields that have been modified
074   * locally.
075   *
076   * <p>The only fields that will be updated are the ones that have been modified locally. For
077   * example, the following code won't update any information (or even send a network request) since
078   * none of the info's fields were changed:
079   *
080   * <pre>BoxTaskAssignment taskAssignment = new BoxTaskAssignment(api, id);
081   * BoxTaskAssignment.Info info = taskAssignment.getInfo();
082   * taskAssignment.updateInfo(info);</pre>
083   *
084   * @param info the updated info.
085   */
086  public void updateInfo(BoxTaskAssignment.Info info) {
087    URL url = TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
088    BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
089    request.setBody(info.getPendingChanges());
090    try (BoxJSONResponse response = request.send()) {
091      JsonObject jsonObject = Json.parse(response.getJSON()).asObject();
092      info.update(jsonObject);
093    }
094  }
095
096  /** Enumerates the possible resolution states that a task assignment can have. */
097  public enum ResolutionState {
098    /** The task assignment has been completed. */
099    COMPLETED("completed"),
100
101    /** The task assignment is incomplete. */
102    INCOMPLETE("incomplete"),
103
104    /** The task assignment has been approved. */
105    APPROVED("approved"),
106
107    /** The task assignment has been rejected. */
108    REJECTED("rejected");
109
110    private final String jsonValue;
111
112    ResolutionState(String jsonValue) {
113      this.jsonValue = jsonValue;
114    }
115
116    static ResolutionState fromJSONString(String jsonValue) {
117      if (jsonValue.equals("completed")) {
118        return COMPLETED;
119      } else if (jsonValue.equals("incomplete")) {
120        return INCOMPLETE;
121      } else if (jsonValue.equals("approved")) {
122        return APPROVED;
123      } else if (jsonValue.equals("rejected")) {
124        return REJECTED;
125      } else {
126        throw new IllegalArgumentException(
127            "The provided JSON value isn't a valid ResolutionState.");
128      }
129    }
130
131    String toJSONString() {
132      return this.jsonValue;
133    }
134  }
135
136  /** Contains information about a task assignment. */
137  public class Info extends BoxResource.Info {
138    private BoxItem.Info item;
139    private BoxUser.Info assignedTo;
140    private String message;
141    private Date completedAt;
142    private Date assignedAt;
143    private Date remindedAt;
144    private ResolutionState resolutionState;
145    private String status;
146    private BoxUser.Info assignedBy;
147
148    /** Constructs an empty Info object. */
149    public Info() {
150      super();
151    }
152
153    /**
154     * Constructs an Info object by parsing information from a JSON string.
155     *
156     * @param json the JSON string to parse.
157     */
158    public Info(String json) {
159      super(json);
160    }
161
162    /**
163     * Constructs an Info object using an already parsed JSON object.
164     *
165     * @param jsonObject the parsed JSON object.
166     */
167    Info(JsonObject jsonObject) {
168      super(jsonObject);
169    }
170
171    @Override
172    public BoxResource getResource() {
173      return BoxTaskAssignment.this;
174    }
175
176    /**
177     * Gets the item associated with this task.
178     *
179     * @return the item associated with this task.
180     */
181    public BoxItem.Info getItem() {
182      return this.item;
183    }
184
185    /**
186     * Gets the user the assignment is assigned to.
187     *
188     * @return the user assigned to this assignment.
189     */
190    public BoxUser.Info getAssignedTo() {
191      return this.assignedTo;
192    }
193
194    /**
195     * Gets the message that will be included with this task assignment.
196     *
197     * @return the message that will be included with this task assignment.
198     */
199    public String getMessage() {
200      return this.message;
201    }
202
203    /**
204     * Sets the message for the assignment.
205     *
206     * @param message the message to be set on the assignment.
207     */
208    public void setMessage(String message) {
209      this.message = message;
210      this.addPendingChange("message", message);
211    }
212
213    /**
214     * Gets the date the assignment is to be completed at.
215     *
216     * @return the date the assignment is to be completed at.
217     */
218    public Date getCompletedAt() {
219      return this.completedAt;
220    }
221
222    /**
223     * Gets the date the assignment was assigned at.
224     *
225     * @return the date the assignment was assigned at.
226     */
227    public Date getAssignedAt() {
228      return this.assignedAt;
229    }
230
231    /**
232     * Gets the date the assignee is to be reminded at.
233     *
234     * @return the date the assignee is to be reminded at.
235     */
236    public Date getRemindedAt() {
237      return this.remindedAt;
238    }
239
240    /**
241     * Gets the current resolution state of the assignment.
242     *
243     * @return the current resolution state of the assignment.
244     */
245    public ResolutionState getResolutionState() {
246      return this.resolutionState;
247    }
248
249    /**
250     * Sets the resolution state for the assignment.
251     *
252     * @param resolutionState the resolution state to be set on the assignment.
253     */
254    public void setResolutionState(ResolutionState resolutionState) {
255      this.resolutionState = resolutionState;
256      this.addPendingChange("resolution_state", resolutionState.toJSONString());
257    }
258
259    /**
260     * Gets the current status of the assignment.
261     *
262     * @return the current status of the assignment.
263     */
264    public String getStatus() {
265      return this.status;
266    }
267
268    /**
269     * Sets the status for the assignment.
270     *
271     * @param status the status to be set on the assignment.
272     */
273    public void setStatus(String status) {
274      this.status = status;
275      this.addPendingChange("status", status);
276    }
277
278    /**
279     * Gets the user that assigned the assignment.
280     *
281     * @return the user that assigned the assignment.
282     */
283    public BoxUser.Info getAssignedBy() {
284      return this.assignedBy;
285    }
286
287    @Override
288    void parseJSONMember(JsonObject.Member member) {
289      super.parseJSONMember(member);
290
291      String memberName = member.getName();
292      JsonValue value = member.getValue();
293      try {
294        if (memberName.equals("item")) {
295          JsonObject itemJSON = value.asObject();
296          String itemID = itemJSON.get("id").asString();
297          BoxFile file = new BoxFile(getAPI(), itemID);
298          this.item = file.new Info(itemJSON);
299        } else if (memberName.equals("assigned_to")) {
300          JsonObject userJSON = value.asObject();
301          String userID = userJSON.get("id").asString();
302          BoxUser user = new BoxUser(getAPI(), userID);
303          this.assignedTo = user.new Info(userJSON);
304        } else if (memberName.equals("message")) {
305          this.message = value.asString();
306        } else if (memberName.equals("completed_at")) {
307          this.completedAt = BoxDateFormat.parse(value.asString());
308        } else if (memberName.equals("assigned_at")) {
309          this.assignedAt = BoxDateFormat.parse(value.asString());
310        } else if (memberName.equals("reminded_at")) {
311          this.remindedAt = BoxDateFormat.parse(value.asString());
312        } else if (memberName.equals("resolution_state")) {
313          this.resolutionState = ResolutionState.fromJSONString(value.asString());
314        } else if (memberName.equals("status")) {
315          this.status = value.asString();
316        } else if (memberName.equals("assigned_by")) {
317          JsonObject userJSON = value.asObject();
318          String userID = userJSON.get("id").asString();
319          BoxUser user = new BoxUser(getAPI(), userID);
320          this.assignedBy = user.new Info(userJSON);
321        }
322      } catch (Exception e) {
323        throw new BoxDeserializationException(memberName, value.toString(), e);
324      }
325    }
326  }
327}