diff --git a/README.md b/README.md index c7c8536..5af99bd 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,44 @@ document_type | _(required)_ The passenger's document type (e.g passport). See * frequent_traveler | _(optional)_ A boolean. Is this passenger a frequent traveler? special_needs | _(optional)_ A boolean. Does the passenger have special needs? + +##### Events +Parameter | Description +--- | --- +name | _(required)_ The name of the event +date | _(required)_ When the event is going to happen +type | _(optional)_ The type of the event (e.g., show, sports, theater, etc). For the complete list, see **KondutoEventType** enum. +subtype | _(optional)_ +venue | _(optional)_ The event's location address. See **Event Venue** bellow. +tickets | _(optional)_ A list of tickets for the given event. See **Event Ticket** below. + +##### Event Venue +Parameter | Description +--- | --- +name | _(optional)_ The name of the place (e.g. Wembley Stadium, World Trade Center). +capacity | _(optional)_ The total amount of available tickets for sale. +address | _(optional)_ The specific location. +city | _(optional)_ +state | _(optional)_ +country | _(optional)_ The country abbreviation code (e.g., BR, US, AU, etc) + +##### Event Ticket +Parameter | Description +--- | --- +id | _(optional)_ A unique identifier for the ticket. +category | _(required)_ The ticket type, such as senior, student or regular. For the complete list, see **KondutoEventTicketCategory** enum. +section | _(optional)_ The location of the ticket (e.g., lower seats, upper seats, unseated, etc). +premium | _(required)_ Boolean that indicates if the ticket is a premium one. +attendee | _(optional)_ Information about the ticket owner. See **KondutoEventTicketAttendee** bellow. + +##### Event Ticket Attendee +Parameter | Description +--- | --- +name | _(optional)_ The attendee's name. +document | _(required)_ The attendee document value. +documentType | _(optional)_ The type of document informed, such as CPF, CNPJ, passport, etc. For the complete list, see **KondutoEventTicketAttendeeDocumentType** enum. +dateOfBirth | _(optional)_ A string with the attendee's date of birth. +======= ##### Vehicle Parameter | Description --- | --- diff --git a/src/main/java/com/konduto/sdk/models/KondutoEvent.java b/src/main/java/com/konduto/sdk/models/KondutoEvent.java new file mode 100644 index 0000000..cb3884a --- /dev/null +++ b/src/main/java/com/konduto/sdk/models/KondutoEvent.java @@ -0,0 +1,113 @@ +package com.konduto.sdk.models; + +import com.konduto.sdk.annotations.Required; +import com.konduto.sdk.annotations.ValidateFormat; + +import java.util.List; + +/** + * Model that represents an event. + * + * @see Konduto API Spec + */ +public class KondutoEvent extends KondutoModel { + + @Required + private String name; + + @Required + @ValidateFormat( + format = "\\d{4}-(10|11|12|0\\d)-(30|31|[0-2]\\d)T(20|21|22|23|24|[0-1]?\\d):[0-5]?\\d(:[0-5]?\\d)?Z" + ) + private String date; + + private KondutoEventType type; + + private String subtype; + + private KondutoEventVenue venue; + + private List tickets; + + /** + * Fluent constructor + * @param attributeName the attribute name (e.g totalAmount) + * @param attributeValue the attribute value (e.g 123.2) + * @return a new instance + */ + @Override + public KondutoEvent with(String attributeName, Object attributeValue) { + return (KondutoEvent) super.with(attributeName, attributeValue); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + KondutoEvent that = (KondutoEvent) o; + + if (!name.equals(that.name)) return false; + return date.equals(that.date); + } + + @Override + public boolean isValid() { + boolean isValid = true; + if (tickets != null) { + for (KondutoEventTicket ticket : tickets) { + isValid &= ticket.isValid(); + } + } + + return isValid && super.isValid(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public KondutoEventType getType() { + return type; + } + + public void setType(KondutoEventType type) { + this.type = type; + } + + public String getSubtype() { + return subtype; + } + + public void setSubtype(String subtype) { + this.subtype = subtype; + } + + public KondutoEventVenue getVenue() { + return venue; + } + + public void setVenue(KondutoEventVenue venue) { + this.venue = venue; + } + + public List getTickets() { + return tickets; + } + + public void setTickets(List tickets) { + this.tickets = tickets; + } +} diff --git a/src/main/java/com/konduto/sdk/models/KondutoEventTicket.java b/src/main/java/com/konduto/sdk/models/KondutoEventTicket.java new file mode 100644 index 0000000..d849824 --- /dev/null +++ b/src/main/java/com/konduto/sdk/models/KondutoEventTicket.java @@ -0,0 +1,91 @@ +package com.konduto.sdk.models; + +import com.konduto.sdk.annotations.Required; + +/** + * Model that represents an event ticket. + * + * @see Konduto API Spec + */ +public class KondutoEventTicket extends KondutoModel { + + private String id; + + @Required + private KondutoEventTicketCategory category; + + @Required + private Boolean premium; + + private String section; + + private KondutoEventTicketAttendee attendee; + + /** + * Fluent constructor + * @param attributeName the attribute name (e.g totalAmount) + * @param attributeValue the attribute value (e.g 123.2) + * @return a new instance + */ + @Override + public KondutoEventTicket with(String attributeName, Object attributeValue) { + return (KondutoEventTicket) super.with(attributeName, attributeValue); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof KondutoEventTicket)) { return false; } + KondutoEventTicket that = (KondutoEventTicket) obj; + + if (id == null || !id.equals(that.id)) return false; + if (section == null || !section.equals(that.section)) return false; + if (category == null || !category.equals(that.category)) return false; + return attendee != null && attendee.equals(that.attendee); + } + + @Override + public boolean isValid() { + if (attendee != null) return attendee.isValid() && super.isValid(); + return super.isValid(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public KondutoEventTicketCategory getCategory() { + return category; + } + + public void setCategory(KondutoEventTicketCategory category) { + this.category = category; + } + + public String getSection() { + return section; + } + + public void setSection(String section) { + this.section = section; + } + + public Boolean getPremium() { + return premium; + } + + public void setPremium(Boolean premium) { + this.premium = premium; + } + + public KondutoEventTicketAttendee getAttendee() { + return attendee; + } + + public void setAttendee(KondutoEventTicketAttendee attendee) { + this.attendee = attendee; + } +} diff --git a/src/main/java/com/konduto/sdk/models/KondutoEventTicketAttendee.java b/src/main/java/com/konduto/sdk/models/KondutoEventTicketAttendee.java new file mode 100644 index 0000000..7e8280b --- /dev/null +++ b/src/main/java/com/konduto/sdk/models/KondutoEventTicketAttendee.java @@ -0,0 +1,75 @@ +package com.konduto.sdk.models; + +import com.google.gson.annotations.SerializedName; +import com.konduto.sdk.annotations.Required; +import com.konduto.sdk.annotations.ValidateFormat; + +/** + * Model representing an attendee to an event. + * + * @see Konduto API Spec + * + */ +public class KondutoEventTicketAttendee extends KondutoModel { + + @Required + private String document; + + private KondutoEventTicketAttendeeDocumentType documentType; + + @SerializedName("dob") + @ValidateFormat(format = "\\d{4}-(10|11|12|0\\d)-(30|31|[0-2]\\d)") + private String dateOfBirth; + + private String name; + + /** + * Fluent constructor + * @param attributeName the attribute name (e.g totalAmount) + * @param attributeValue the attribute value (e.g 123.2) + * @return a new instance + */ + @Override + public KondutoEventTicketAttendee with(String attributeName, Object attributeValue) { + return (KondutoEventTicketAttendee) super.with(attributeName, attributeValue); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof KondutoEventTicketAttendee)) { return false; } + KondutoEventTicketAttendee that = (KondutoEventTicketAttendee) obj; + return this.document != null && this.document.equals(that.document); + } + + public KondutoEventTicketAttendeeDocumentType getDocumentType() { + return documentType; + } + + public void setDocumentType(KondutoEventTicketAttendeeDocumentType documentType) { + this.documentType = documentType; + } + + public String getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(String dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public String getDocument() { + return document; + } + + public void setDocument(String document) { + this.document = document; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/konduto/sdk/models/KondutoEventTicketAttendeeDocumentType.java b/src/main/java/com/konduto/sdk/models/KondutoEventTicketAttendeeDocumentType.java new file mode 100644 index 0000000..2713951 --- /dev/null +++ b/src/main/java/com/konduto/sdk/models/KondutoEventTicketAttendeeDocumentType.java @@ -0,0 +1,21 @@ +package com.konduto.sdk.models; + +import com.google.gson.annotations.SerializedName; + +/** + * Enum representing the types of documents Konduto's API accepts when handling event tickets attendee's + * + * @see Konduto API Spec + */ +public enum KondutoEventTicketAttendeeDocumentType { + @SerializedName("cpf") + CPF, + @SerializedName("cnpj") + CNPJ, + @SerializedName("rg") + RG, + @SerializedName("passport") + PASSPORT, + @SerializedName("other") + OTHER +} diff --git a/src/main/java/com/konduto/sdk/models/KondutoEventTicketCategory.java b/src/main/java/com/konduto/sdk/models/KondutoEventTicketCategory.java new file mode 100644 index 0000000..a2786d8 --- /dev/null +++ b/src/main/java/com/konduto/sdk/models/KondutoEventTicketCategory.java @@ -0,0 +1,23 @@ +package com.konduto.sdk.models; + +import com.google.gson.annotations.SerializedName; + +/** + * Enum representing a event ticket category. + * For instance, if the ticket was bought by a student it will probably have a discount. The same applies to + * senior citizens. + * + * @see Konduto API Spec + */ +public enum KondutoEventTicketCategory { + @SerializedName("student") + STUDENT, + @SerializedName("senior") + SENIOR, + @SerializedName("government") + GOVERNMENT, + @SerializedName("social") + SOCIAL, + @SerializedName("regular") + REGULAR +} diff --git a/src/main/java/com/konduto/sdk/models/KondutoEventType.java b/src/main/java/com/konduto/sdk/models/KondutoEventType.java new file mode 100644 index 0000000..db5b010 --- /dev/null +++ b/src/main/java/com/konduto/sdk/models/KondutoEventType.java @@ -0,0 +1,27 @@ +package com.konduto.sdk.models; + +import com.google.gson.annotations.SerializedName; + +/** + * Enum representing the types of events Konduto's API currently supports. + * + * @see Konduto API Spec + */ +public enum KondutoEventType { + @SerializedName("show") + SHOW, + @SerializedName("theater") + THEATER, + @SerializedName("movies") + MOVIES, + @SerializedName("party") + PARTY, + @SerializedName("festival") + FESTIVAL, + @SerializedName("course") + COURSE, + @SerializedName("sports") + SPORTS, + @SerializedName("corporate") + CORPORATE +} diff --git a/src/main/java/com/konduto/sdk/models/KondutoEventVenue.java b/src/main/java/com/konduto/sdk/models/KondutoEventVenue.java new file mode 100644 index 0000000..db71d29 --- /dev/null +++ b/src/main/java/com/konduto/sdk/models/KondutoEventVenue.java @@ -0,0 +1,97 @@ +package com.konduto.sdk.models; + +import com.konduto.sdk.annotations.ValidateFormat; + +/** + * Model that represents the venue where an event will take place. + * + * @see Konduto API Spec + */ +public class KondutoEventVenue extends KondutoModel { + + private String name; + + private Integer capacity; + + private String address; + + private String city; + + private String state; + + @ValidateFormat(format = "[A-Za-z]{2}") + private String country; + + /** + * Fluent constructor + * @param attributeName the attribute name (e.g totalAmount) + * @param attributeValue the attribute value (e.g 123.2) + * @return a new instance + */ + @Override + public KondutoEventVenue with(String attributeName, Object attributeValue) { + return (KondutoEventVenue) super.with(attributeName, attributeValue); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + KondutoEventVenue that = (KondutoEventVenue) o; + + return capacity != null && capacity.equals(that.capacity) && + name != null && name.equals(that.name) && + address != null && address.equals(that.address) && + city != null && city.equals(that.city) && + state != null && state.equals(that.state) && + country != null && country.equals(that.country); + } + + public Integer getCapacity() { + return capacity; + } + + public void setCapacity(Integer capacity) { + this.capacity = capacity; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } +} diff --git a/src/main/java/com/konduto/sdk/models/KondutoOrder.java b/src/main/java/com/konduto/sdk/models/KondutoOrder.java index 088d7b8..8798576 100644 --- a/src/main/java/com/konduto/sdk/models/KondutoOrder.java +++ b/src/main/java/com/konduto/sdk/models/KondutoOrder.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.Date; +import java.util.List; /** * @@ -91,7 +92,9 @@ public final class KondutoOrder extends KondutoModel { private KondutoOption options; private KondutoHotel hotel; - private KondutoVehicle vehicle; + private List events; + + private KondutoVehicle vehicle; /* Constructors */ public KondutoOrder() {} @@ -296,8 +299,8 @@ public void setScore(Double score) { public void setRecommendation(KondutoRecommendation recommendation) { this.recommendation = recommendation; } - public boolean getAnalyze() { return analyze; } - public void setAnalyze(boolean analyze) { this.analyze = analyze; } + public boolean getAnalyze() { return analyze; } + public void setAnalyze(boolean analyze) { this.analyze = analyze; } public Integer getMessagesExchanged() { return messagesExchanged; } public void setMessagesExchanged(Integer messagesExchanged) { this.messagesExchanged = messagesExchanged; } public KondutoTravel getTravel() { @@ -349,6 +352,14 @@ public Collection getDecisionListEntries() { return decisionListEntries; } + public List getEvents() { + return events; + } + + public void setEvents(List events) { + this.events = events; + } + public KondutoVehicle getVehicle() { return vehicle; } @@ -356,4 +367,5 @@ public KondutoVehicle getVehicle() { public void setVehicle(KondutoVehicle vehicle) { this.vehicle = vehicle; } + } diff --git a/src/test/java/com/konduto/sdk/factories/KondutoEventFactory.java b/src/test/java/com/konduto/sdk/factories/KondutoEventFactory.java new file mode 100644 index 0000000..2e5619f --- /dev/null +++ b/src/test/java/com/konduto/sdk/factories/KondutoEventFactory.java @@ -0,0 +1,75 @@ +package com.konduto.sdk.factories; + +import com.konduto.sdk.models.*; + +import java.util.Arrays; +import java.util.List; + +public class KondutoEventFactory { + + public static KondutoEvent getSingleEvent() { + return new KondutoEvent() + .with("name", "Safadão no Maracanã") + .with("date", "2021-01-01T03:00:00Z") + .with("type", KondutoEventType.SHOW) + .with("subtype", "sertanejo") + .with( + "venue", + new KondutoEventVenue() + .with("name", "Estádio do Maracanã") + .with("capacity", 80000) + .with("address", "Av. Maracanã s/n") + .with("city", "Rio de Janeiro") + .with("state", "RJ") + .with("country", "BR") + ) + .with( + "tickets", + Arrays.asList( + new KondutoEventTicket() + .with("category", KondutoEventTicketCategory.REGULAR) + .with("premium", true) + .with("section", "Pista Premium") + .with( + "attendee", + new KondutoEventTicketAttendee() + .with("document","12345678900") + .with("documentType", KondutoEventTicketAttendeeDocumentType.CPF) + .with("dateOfBirth", "1990-10-28") + ), + new KondutoEventTicket() + .with("category", KondutoEventTicketCategory.STUDENT) + .with("premium", false) + + ) + ); + } + + public static List getMultipleEvents() { + return Arrays.asList( + getSingleEvent(), + new KondutoEvent() + .with("name", "Heat @ Knicks") + .with("date", "2020-11-21T01:00:00Z") + .with("type", KondutoEventType.SPORTS) + .with("subtype", "NBA") + .with( + "tickets", + Arrays.asList( + new KondutoEventTicket() + .with("category", KondutoEventTicketCategory.REGULAR) + .with("premium", true) + .with("section", "general"), + new KondutoEventTicket() + .with("category", KondutoEventTicketCategory.REGULAR) + .with("premium", true) + .with("section", "general") + + ) + ) + ); + } + +} + + diff --git a/src/test/java/com/konduto/sdk/factories/KondutoOrderFactory.java b/src/test/java/com/konduto/sdk/factories/KondutoOrderFactory.java index ca2d93e..a743a7b 100644 --- a/src/test/java/com/konduto/sdk/factories/KondutoOrderFactory.java +++ b/src/test/java/com/konduto/sdk/factories/KondutoOrderFactory.java @@ -37,6 +37,7 @@ public static KondutoOrder completeOrder() throws ParseException { order.setMessagesExchanged(2); order.setSeller(KondutoSellerFactory.getKondutoSeller()); order.setBureauxQueries(KondutoBureauQueryFactory.getQueries()); + order.setEvents(KondutoEventFactory.getMultipleEvents()); order.setVehicle(KondutoVehicleFactory.getVehicle()); return order; } diff --git a/src/test/java/com/konduto/sdk/models/KondutoEventTest.java b/src/test/java/com/konduto/sdk/models/KondutoEventTest.java new file mode 100644 index 0000000..d6a8c37 --- /dev/null +++ b/src/test/java/com/konduto/sdk/models/KondutoEventTest.java @@ -0,0 +1,32 @@ +package com.konduto.sdk.models; + +import com.google.gson.JsonObject; +import com.konduto.sdk.exceptions.KondutoInvalidEntityException; +import com.konduto.sdk.factories.KondutoEventFactory; +import com.konduto.sdk.utils.TestUtils; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class KondutoEventTest { + + private KondutoEvent singleEvent; + private static JsonObject expectedJSON; + + @BeforeClass + public static void initializeJson() { + expectedJSON = (JsonObject) TestUtils.readJSONFromFile("event.json"); + } + + @Before + public void restartEvent() { + singleEvent = KondutoEventFactory.getSingleEvent(); + } + + @Test + public void serializeTest() throws KondutoInvalidEntityException { + assertEquals(expectedJSON, singleEvent.toJSON()); + } +} diff --git a/src/test/resources/event.json b/src/test/resources/event.json new file mode 100644 index 0000000..c26b8a1 --- /dev/null +++ b/src/test/resources/event.json @@ -0,0 +1,30 @@ +{ + "name": "Safadão no Maracanã", + "date": "2021-01-01T03:00:00Z", + "type": "show", + "subtype": "sertanejo", + "venue": { + "name": "Estádio do Maracanã", + "capacity": 80000, + "address": "Av. Maracanã s/n", + "city": "Rio de Janeiro", + "state": "RJ", + "country": "BR" + }, + "tickets": [ + { + "category": "regular", + "premium": true, + "section": "Pista Premium", + "attendee": { + "document": "12345678900", + "document_type": "cpf", + "dob": "1990-10-28" + } + }, + { + "category": "student", + "premium": false + } + ] +} \ No newline at end of file diff --git a/src/test/resources/order.json b/src/test/resources/order.json index ae7bdf6..93ea6be 100644 --- a/src/test/resources/order.json +++ b/src/test/resources/order.json @@ -149,6 +149,56 @@ } } ], + "events": [ + { + "name": "Safadão no Maracanã", + "date": "2021-01-01T03:00:00Z", + "type": "show", + "subtype": "sertanejo", + "venue": { + "name": "Estádio do Maracanã", + "capacity": 80000, + "address": "Av. Maracanã s/n", + "city": "Rio de Janeiro", + "state": "RJ", + "country": "BR" + }, + "tickets": [ + { + "category": "regular", + "premium": true, + "section": "Pista Premium", + "attendee": { + "document": "12345678900", + "document_type": "cpf", + "dob": "1990-10-28" + } + }, + { + "category": "student", + "premium": false + } + ] + }, + { + "name": "Heat @ Knicks", + "date": "2020-11-21T01:00:00Z", + "type": "sports", + "subtype": "NBA", + "tickets": [ + { + "category": "regular", + "premium": true, + "section": "general" + }, + { + "category": "regular", + "section": "general", + "premium": true + } + ] + } + ], "vehicle": { "make": "Bentley", "model": "Bacalar",