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