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