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