001package com.box.sdk;
002
003import static java.lang.String.format;
004
005import com.box.sdk.internal.utils.JsonUtils;
006import com.eclipsesource.json.JsonObject;
007import com.eclipsesource.json.JsonValue;
008import java.util.ArrayList;
009import java.util.Date;
010import java.util.List;
011
012/**
013 * Represents a signer in BoxSignRequest.
014 */
015public class BoxSignRequestSigner extends BoxJSONObject {
016    private String email;
017    private BoxSignRequestSignerRole role;
018    private Boolean isInPerson;
019    private Integer order;
020    private String embedUrlExternalUserId;
021    private Boolean hasViewedEmail;
022    private Boolean hasViewedDocument;
023    private BoxSignerDecision signerDecision;
024    private List<BoxSignerInput> inputs;
025    private String embedUrl;
026    private String redirectUrl;
027    private String declinedRedirectUrl;
028    private BoxAPIConnection api;
029
030    /**
031     * Constructs a BoxSignRequestSigner with an email.
032     *
033     * @param email of signer.
034     */
035    public BoxSignRequestSigner(String email) {
036        this.email = email;
037    }
038
039    /**
040     * Construct a BoxSignRequestSigner.
041     *
042     * @param jsonObject the parsed JSON object.
043     * @param api        the API connection to be used to fetch interacted item
044     */
045    public BoxSignRequestSigner(JsonObject jsonObject, BoxAPIConnection api) {
046        super(jsonObject);
047        this.api = api;
048    }
049
050    /**
051     * Gets the email address of the signer.
052     *
053     * @return email address of the signer.
054     */
055    public String getEmail() {
056        return this.email;
057    }
058
059    /**
060     * Sets the email address of the signer.
061     *
062     * @param email address of the signer.
063     * @return this BoxSignRequestSigner object for chaining.
064     */
065    public BoxSignRequestSigner setEmail(String email) {
066        this.email = email;
067        return this;
068    }
069
070    /**
071     * Gets the role of the signer.
072     *
073     * @return role of the signer.
074     */
075    public BoxSignRequestSignerRole getRole() {
076        return this.role;
077    }
078
079    /**
080     * Sets the role of the signer. If role is not set it's FinalCopyReader by default.
081     *
082     * @param role of the signer.
083     * @return this BoxSignRequestSigner object for chaining.
084     */
085    public BoxSignRequestSigner setRole(BoxSignRequestSignerRole role) {
086        this.role = role;
087        return this;
088    }
089
090    /**
091     * Gets the flag that when used in combination with an embed url on the sender. After the sender signs,
092     * they will be redirected to the next InPerson signer.
093     *
094     * @return true if is in person signer, otherwise false.
095     */
096    public boolean getIsInPerson() {
097        return this.isInPerson;
098    }
099
100    /**
101     * Gets the order of signer.
102     *
103     * @return order of signer.
104     */
105    public int getOrder() {
106        return this.order;
107    }
108
109    /**
110     * Sets the order of signer.
111     *
112     * @param order of signer.
113     * @return this BoxSignRequestSigner object for chaining.
114     */
115    public BoxSignRequestSigner setOrder(Integer order) {
116        this.order = order;
117        return this;
118    }
119
120    /**
121     * Gets the user id for this signer in external application responsible
122     * for authentication when accessing the embed url.
123     *
124     * @return embed url external user id.
125     */
126    public String getEmbedUrlExternalUserId() {
127        return this.embedUrlExternalUserId;
128    }
129
130    /**
131     * Sets the user id for this signer in external application responsible
132     * for authentication when accessing the embed url.
133     *
134     * @param embedUrlExternalUserId for this signer in external application responsible
135     *                               for authentication when accessing the embed url.
136     * @return this BoxSignRequestSigner object for chaining.
137     */
138    public BoxSignRequestSigner setEmbedUrlExternalUserId(String embedUrlExternalUserId) {
139        this.embedUrlExternalUserId = embedUrlExternalUserId;
140        return this;
141    }
142
143    /**
144     * Gets the flag indicating if signer has viewed the sign request email.
145     *
146     * @return true if the signer has viewed the sign request email, otherwise false.
147     */
148    public boolean getHasViewedEmail() {
149        return this.hasViewedEmail;
150    }
151
152    /**
153     * Gets the flag indicating if signer has viewed the document.
154     *
155     * @return true if the signer has viewed the document, otherwise false.
156     */
157    public boolean getHasViewedDocument() {
158        return this.hasViewedDocument;
159    }
160
161    /**
162     * Gets the final decision made by signer.
163     *
164     * @return final decision made by signer.
165     */
166    public BoxSignerDecision getSignerDecision() {
167        return this.signerDecision;
168    }
169
170    /**
171     * Gets the inputs created by a signer on a sign request.
172     *
173     * @return list of inputs created by a signer on a sign request.
174     */
175    public List<BoxSignerInput> getInputs() {
176        return this.inputs;
177    }
178
179    /**
180     * Gets the url to direct signer to for signing.
181     *
182     * @return url to direct signer to for signing.
183     */
184    public String getEmbedUrl() {
185        return this.embedUrl;
186    }
187
188    /**
189     * Gets the flag that is used in combination with an embed url for a the sender. After the sender signs,
190     * they will be redirected to the next InPerson signer.
191     *
192     * @return true if is in person signer, otherwise false.
193     */
194    public Boolean getInPerson() {
195        return this.isInPerson;
196    }
197
198    /**
199     * Sets the flag that is used in combination with an embed url for a the sender. After the sender signs,
200     * they will be redirected to the next InPerson signer.
201     *
202     * @param isInPerson flag.
203     * @return this BoxSignRequestSigner object for chaining.
204     */
205    public BoxSignRequestSigner setInPerson(Boolean isInPerson) {
206        this.isInPerson = isInPerson;
207        return this;
208    }
209
210    /**
211     * Gets the redirect url for the signer.
212     *
213     * @return redirect url for the signer.
214     */
215    public String getRedirectUrl() {
216        return this.redirectUrl;
217    }
218
219    /**
220     * Sets the redirect url for the signer.
221     *
222     * @param redirectUrl for the signer.
223     * @return this BoxSignRequestSigner object for chaining.
224     */
225    public BoxSignRequestSigner setRedirectUrl(String redirectUrl) {
226        this.redirectUrl = redirectUrl;
227        return this;
228    }
229
230    /**
231     * Gets the declined redirect url for the signer.
232     *
233     * @return declined redirect url for the signer.
234     */
235    public String getDeclinedRedirectUrl() {
236        return this.declinedRedirectUrl;
237    }
238
239    /**
240     * Sets the declined redirect url for the signer.
241     *
242     * @param declinedRedirectUrl for the signer.
243     * @return this BoxSignRequestSigner object for chaining.
244     */
245    public BoxSignRequestSigner setDeclinedRedirectUrl(String declinedRedirectUrl) {
246        this.declinedRedirectUrl = declinedRedirectUrl;
247        return this;
248    }
249
250    /**
251     * {@inheritDoc}
252     */
253    @Override
254    void parseJSONMember(JsonObject.Member member) {
255        JsonValue value = member.getValue();
256        String memberName = member.getName();
257        try {
258            switch (memberName) {
259                case "email":
260                    this.email = value.asString();
261                    break;
262                case "role":
263                    this.role = BoxSignRequestSignerRole.fromJSONString(value.asString());
264                    break;
265                case "is_in_person":
266                    this.isInPerson = value.asBoolean();
267                    break;
268                case "order":
269                    this.order = value.asInt();
270                    break;
271                case "embed_url_external_user_id":
272                    this.embedUrlExternalUserId = value.asString();
273                    break;
274                case "has_viewed_email":
275                    this.hasViewedEmail = value.asBoolean();
276                    break;
277                case "has_viewed_document":
278                    this.hasViewedDocument = value.asBoolean();
279                    break;
280                case "signer_decision":
281                    JsonObject signerDecisionJSON = value.asObject();
282                    this.signerDecision = new BoxSignerDecision(signerDecisionJSON);
283                    break;
284                case "inputs":
285                    List<BoxSignerInput> inputs = new ArrayList<>();
286                    for (JsonValue inputJSON : value.asArray()) {
287                        BoxSignerInput input = new BoxSignerInput(inputJSON.asObject());
288                        inputs.add(input);
289                    }
290                    this.inputs = inputs;
291                    break;
292                case "embed_url":
293                    this.embedUrl = value.asString();
294                    break;
295                case "redirect_url":
296                    this.redirectUrl = value.asString();
297                    break;
298                case "declined_redirect_url":
299                    this.declinedRedirectUrl = value.asString();
300                    break;
301                default:
302                    return;
303            }
304        } catch (Exception e) {
305            throw new BoxDeserializationException(memberName, value.toString(), e);
306        }
307    }
308
309    /**
310     * Gets a JSON object representing this class.
311     *
312     * @return the JSON object representing this class.
313     */
314    public JsonObject getJSONObject() {
315        JsonObject jsonObj = new JsonObject();
316        JsonUtils.addIfNotNull(jsonObj, "email", this.email);
317        JsonUtils.addIfNotNull(jsonObj, "role", this.role);
318        JsonUtils.addIfNotNull(jsonObj, "is_in_person", this.isInPerson);
319        JsonUtils.addIfNotNull(jsonObj, "order", this.order);
320        JsonUtils.addIfNotNull(jsonObj, "embed_url_external_user_id", this.embedUrlExternalUserId);
321        JsonUtils.addIfNotNull(jsonObj, "redirect_url", this.redirectUrl);
322        JsonUtils.addIfNotNull(jsonObj, "declined_redirect_url", this.declinedRedirectUrl);
323        return jsonObj;
324    }
325
326    /**
327     * Type of decision made by signer.
328     */
329    public enum BoxSignRequestSignerDecisionType {
330
331        /**
332         * Signed decision.
333         */
334        Signed("signed"),
335
336        /**
337         * Declined decision.
338         */
339        Declined("declined");
340
341        private final String jsonValue;
342
343        BoxSignRequestSignerDecisionType(String jsonValue) {
344            this.jsonValue = jsonValue;
345        }
346
347        static BoxSignRequestSignerDecisionType fromJSONString(String jsonValue) {
348            if ("signed".equals(jsonValue)) {
349                return Signed;
350            } else if ("declined".equals(jsonValue)) {
351                return Declined;
352            }
353            throw new IllegalArgumentException(
354                "The provided JSON value isn't a valid " + "BoxSignRequestSignerDecisionType.");
355        }
356    }
357
358    /**
359     * Represents a type of input.
360     */
361    public enum BoxSignRequestInputType {
362
363        /**
364         * Signature input.
365         */
366        Signature("signature"),
367
368        /**
369         * Text input.
370         */
371        Text("text"),
372
373        /**
374         * Checkbox input.
375         */
376        Checkbox("checkbox"),
377
378        /**
379         * Date input.
380         */
381        Date("date");
382
383        private final String jsonValue;
384
385        BoxSignRequestInputType(String jsonValue) {
386            this.jsonValue = jsonValue;
387        }
388
389        static BoxSignRequestInputType fromJSONString(String jsonValue) {
390            if ("signature".equals(jsonValue)) {
391                return Signature;
392            } else if ("text".equals(jsonValue)) {
393                return Text;
394            } else if ("checkbox".equals(jsonValue)) {
395                return Checkbox;
396            } else if ("date".equals(jsonValue)) {
397                return Date;
398            }
399            throw new IllegalArgumentException("The provided JSON value isn't a valid " + "BoxSignRequestInputType.");
400        }
401    }
402
403    /**
404     * Represents a content type of input.
405     */
406    public enum BoxSignRequestInputContentType {
407        /**
408         * Initial content type
409         */
410        Initial("initial"),
411        /**
412         * Stamp content type
413         */
414        Stamp("stamp"),
415        /**
416         * Signature content type
417         */
418        Signature("signature"),
419        /**
420         * Company content type
421         */
422        Company("company"),
423        /**
424         * Title content type
425         */
426        Title("title"),
427        /**
428         * Email content type
429         */
430        Email("email"),
431        /**
432         * Full name content type
433         */
434        FullName("full_name"),
435        /**
436         * First name content type
437         */
438        FirstName("first_name"),
439        /**
440         * Last name content type
441         */
442        LastName("last_name"),
443        /**
444         * Text content type
445         */
446        Text("text"),
447        /**
448         * Date content type
449         */
450        Date("date"),
451        /**
452         * Checkbox content type
453         */
454        Checkbox("checkbox");
455
456        private final String jsonValue;
457
458        BoxSignRequestInputContentType(String jsonValue) {
459            this.jsonValue = jsonValue;
460        }
461
462        static BoxSignRequestInputContentType fromJSONString(String jsonValue) {
463            switch (jsonValue) {
464                case "initial":
465                    return Initial;
466                case "stamp":
467                    return Stamp;
468                case "signature":
469                    return Signature;
470                case "company":
471                    return Company;
472                case "title":
473                    return Title;
474                case "email":
475                    return Email;
476                case "full_name":
477                    return FullName;
478                case "first_name":
479                    return FirstName;
480                case "last_name":
481                    return LastName;
482                case "text":
483                    return Text;
484                case "date":
485                    return Date;
486                case "checkbox":
487                    return Checkbox;
488                default:
489                    throw new IllegalArgumentException(
490                        format("The provided JSON value '%s' isn't a valid BoxSignRequestInputContentType.", jsonValue)
491                    );
492            }
493        }
494    }
495
496    /**
497     * Represents a final decision made by signer (type and time the decision was made).
498     */
499    public class BoxSignerDecision extends BoxJSONObject {
500        private BoxSignRequestSignerDecisionType type;
501        private Date finalizedAt;
502
503        /**
504         * Constructs a BoxSignerDecision object using an already parsed JSON object.
505         *
506         * @param jsonObject the parsed JSON object.
507         */
508        public BoxSignerDecision(JsonObject jsonObject) {
509            super(jsonObject);
510        }
511
512        /**
513         * Gets the type of decision made by signer.
514         *
515         * @return type of decision made by signer.
516         */
517        public BoxSignRequestSignerDecisionType getType() {
518            return this.type;
519        }
520
521        /**
522         * Gets the date/time that the decision was made.
523         *
524         * @return date/time that the decision was made.
525         */
526        public Date getFinalizedAt() {
527            return this.finalizedAt;
528        }
529
530        /**
531         * {@inheritDoc}
532         */
533        @Override
534        void parseJSONMember(JsonObject.Member member) {
535            JsonValue value = member.getValue();
536            String memberName = member.getName();
537            try {
538                if (memberName.equals("type")) {
539                    this.type = BoxSignRequestSignerDecisionType.fromJSONString(value.asString());
540                } else if (memberName.equals("finalized_at")) {
541                    this.finalizedAt = BoxDateFormat.parse(value.asString());
542                }
543            } catch (Exception e) {
544                throw new BoxDeserializationException(memberName, value.toString(), e);
545            }
546        }
547    }
548
549    /**
550     * Represents an input created by a signer on a sign request.
551     */
552    public class BoxSignerInput extends BoxJSONObject {
553        private String documentTagId;
554        private String textValue;
555        private boolean checkboxValue;
556        private BoxSignRequestInputContentType contentType;
557        private Date dateValue;
558        private BoxSignRequestInputType type;
559        private int pageIndex;
560
561        /**
562         * Constructs a BoxSignerInput object using an already parsed JSON object.
563         *
564         * @param jsonObject the parsed JSON object.
565         */
566        public BoxSignerInput(JsonObject jsonObject) {
567            super(jsonObject);
568        }
569
570        /**
571         * Gets the reference of the id of a particular tag added to the content
572         * of the files being used to create the sign request.
573         *
574         * @return document tag id.
575         */
576        public String getDocumentTagId() {
577            return this.documentTagId;
578        }
579
580        /**
581         * Gets the text prefill value.
582         *
583         * @return text prefill value.
584         */
585        public String getTextValue() {
586            return this.textValue;
587        }
588
589        /**
590         * Gets the checkbox prefill value.
591         *
592         * @return checkbox prefill value.
593         */
594        public boolean getIsCheckboxValue() {
595            return this.checkboxValue;
596        }
597
598        /**
599         * Gets the content type of the input.
600         *
601         * @return content type of the input.
602         */
603        public BoxSignRequestInputContentType getContentType() {
604            return this.contentType;
605        }
606
607        /**
608         * Gets the date prefill value.
609         *
610         * @return date prefill value.
611         */
612        public Date getDateValue() {
613            return this.dateValue;
614        }
615
616        /**
617         * Gets the type of input.
618         *
619         * @return type of input.
620         */
621        public BoxSignRequestInputType getType() {
622            return this.type;
623        }
624
625        /**
626         * Gets the index of page that input is on.
627         *
628         * @return index of page that input is on.
629         */
630        public int getPageIndex() {
631            return this.pageIndex;
632        }
633
634        /**
635         * {@inheritDoc}
636         */
637        @Override
638        void parseJSONMember(JsonObject.Member member) {
639            JsonValue value = member.getValue();
640            String memberName = member.getName();
641            try {
642                switch (memberName) {
643                    case "documentTagId":
644                        this.documentTagId = value.asString();
645                        break;
646                    case "text_value":
647                        this.textValue = value.asString();
648                        break;
649                    case "checkbox_value":
650                        this.checkboxValue = value.asBoolean();
651                        break;
652                    case "content_type":
653                        this.contentType = BoxSignRequestInputContentType.fromJSONString(value.asString());
654                        break;
655                    case "date_value":
656                        this.dateValue = BoxDateFormat.parseDateOnly(value.asString());
657                        break;
658                    case "type":
659                        this.type = BoxSignRequestInputType.fromJSONString(value.asString());
660                        break;
661                    case "page_index":
662                        this.pageIndex = value.asInt();
663                        break;
664                    default:
665                        return;
666                }
667            } catch (Exception e) {
668                throw new BoxDeserializationException(memberName, value.toString(), e);
669            }
670        }
671    }
672}
673
674