/* * This work was created by participants in the DataONE project, and is * jointly copyrighted by participating institutions in DataONE. For * more information on DataONE, see our web site at http://dataone.org. * * Copyright 2019. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.dataone.bookkeeper.api; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import java.io.IOException; import java.util.List; import java.util.Objects; /** * Orders represent a list of purchased products by customers */ @JsonIgnoreProperties({"chargeJSON", "metadataJSON", "itemsJSON", "statusTransitionsJSON"}) @JsonInclude(JsonInclude.Include.NON_NULL) public class Order { /* The order unique id */ private Integer id; /* The order object type */ @NotEmpty @NotNull @Pattern(regexp = "order") private String object; /* The order amount (in the smallest unit of the currency) */ private Integer amount; /* The order amount returned */ private Integer amountReturned; /* The order payment charge details */ private ObjectNode charge; /* The order creation date (seconds since the epoch) */ private Integer created; /* The order currency id */ private String currency; /* The order subject identifier, likely an ORCID or DataONE group DN */ private String subject; /* The order customer id */ @NotNull private Integer customer; /* The order customer's email */ private String email; /* The order item list of products */ @NotEmpty @NotNull @Valid private List items; /* The order metadata */ private ObjectNode metadata; /* The name of the order, set by the customer */ private String name; /* The order status */ @Pattern(regexp = "active|created|paid|past_due|refunded|trialing|unpaid") private String status; /* The order status transitions (history of status/timestamp key/value pairs*/ private ObjectNode statusTransitions; /* The order update date (seconds since the epoch) */ private Integer updated; /*The order series identifier used to track renewals */ private String seriesId; /* The start date for the order used to determine service expiry */ private Integer startDate; /* The end date for the order used to determine service expiry */ private Integer endDate; /* The quotas associated with the product, if any */ private List quotas; /** * Construct an empty order */ public Order() { super(); } /** * Construct an order * @param id the order identifier * @param object the order object type * @param amount the order amount * @param amountReturned the order amount returned * @param charge the charge associated with the order * @param created the order create timestamp (seconds since the epoch) * @param currency the order currency identifier * @param customer the order customer identifier * @param email the order customer email * @param items the order items list * @param metadata the metadata object associated with an order * @param name the name of the order, set by the customer * @param status the order status, one of active|created|paid|past_due|refunded|trialing|unpaid * @param statusTransitions the object showing status transitions * @param updated the order update timestamp (seconds since the epoch) * @param seriesId the order series identifier * @param startDate the ordered services start timestamp (seconds since the epoch) * @param endDate the ordered services end timestamp (seconds since the epoch) * @param quotas the quotas associated with the order */ public Order( Integer id, @NotEmpty @NotNull @Pattern(regexp = "order") String object, @NotNull Integer amount, Integer amountReturned, ObjectNode charge, Integer created, String currency, String subject, @NotNull Integer customer, String email, @NotEmpty @NotNull @Valid List items, ObjectNode metadata, String name, @NotEmpty @NotNull @Pattern(regexp = "active|created|paid|past_due|refunded|trialing|unpaid") String status, ObjectNode statusTransitions, Integer updated, String seriesId, Integer startDate, Integer endDate, List quotas) { super(); this.id = id; this.object = object; this.amount = amount; this.amountReturned = amountReturned; this.charge = charge; this.created = created; this.currency = currency; this.subject = subject; this.customer = customer; this.email = email; this.items = items; this.metadata = metadata; this.name = name; this.status = status; this.statusTransitions = statusTransitions; this.updated = updated; this.seriesId = seriesId; this.startDate = startDate; this.endDate = endDate; this.quotas = quotas; } /** * Get the order id * @return id the order identifier */ @JsonProperty public Integer getId() { return id; } /** * Set the order id * @param id the order identifier */ @JsonProperty public void setId(Integer id) { this.id = id; } /** * Get the order object type * @return object the order object type */ @JsonProperty public String getObject() { return object; } /** * Set the order object type * @param object the order object type ("order") */ @JsonProperty public void setObject(String object) { this.object = object; } /** * Get the order amount * @return amount the order amount in the smallest unit of the currency */ @JsonProperty public Integer getAmount() { return amount; } /** * Set the order amount * @param amount the order amount in the smallest unit of the currency */ @JsonProperty public void setAmount(Integer amount) { this.amount = amount; } @JsonProperty public Integer getTotalAmount() { Integer total = 0; // If we have an item list, total the items if ( ! getItems().isEmpty() ) { for (OrderItem item : getItems() ) { total = total + item.getAmount(); } } return total; } /** * Get the order amount returned * @return the order amount returned */ @JsonProperty public Integer getAmountReturned() { return amountReturned; } /** * Set the order amount returned * @param amountReturned the order amount returned */ @JsonProperty public void setAmountReturned(Integer amountReturned) { this.amountReturned = amountReturned; } /** * Get the order payment charge details * @return charge the order charge details */ @JsonProperty public ObjectNode getCharge() { return charge; } /** * Set the order payment charge details * @param charge the order payment charge details */ @JsonProperty public void setCharge(ObjectNode charge) { this.charge = charge; } /** * Get the order creation date * @return created the order creation date in seconds since the epoch */ @JsonProperty public Integer getCreated() { return created; } /** * Set the order creation date * @param created the order creation date in seconds since the epoch */ @JsonProperty public void setCreated(Integer created) { this.created = created; } /** * Get the order currency code * @return currency the order currency code */ @JsonProperty public String getCurrency() { return currency; } /** * Set the order currency code * @param currency the order currency code */ @JsonProperty public void setCurrency(String currency) { this.currency = currency; } /** * Get the order customer * @return customer the order customer */ @JsonProperty public Integer getCustomer() { return customer; } /** * Set the order customer id * @param customer the order customer id */ @JsonProperty public void setCustomer(Integer customer) { this.customer = customer; } /** * Get the order subject * @return the order subject */ @JsonProperty public String getSubject() { return subject; } /** * Set the order subject * @param subject the order subject */ @JsonProperty public void setSubject(String subject) { this.subject = subject; } /** * Get the order email * @return email the order email */ @JsonProperty public String getEmail() { return email; } /** * Set the order email * @param email the order email */ @JsonProperty public void setEmail(String email) { this.email = email; } /** * Get the order items * @return the list of order items */ @JsonProperty public List getItems() { return items; } /** * Set the order items * @param items the list of order items */ @JsonProperty public void setItems(List items) { this.items = items; } /** * Get the order metadata * @return metadata the JSON metadata associated with the order */ @JsonProperty public ObjectNode getMetadata() { return metadata; } /** * Set the order metadata * @param metadata the JSON metadata associated with the order */ @JsonProperty public void setMetadata(ObjectNode metadata) { this.metadata = metadata; } /** * Get the name of the order * @return the order name set by the customer */ @JsonProperty public String getName() { return name; } /** * Set the name of the order * @param name the order name set by the customer */ @JsonProperty public void setName(String name) { this.name = name; } /** * Get the order status * @return status the status of the order */ @JsonProperty public String getStatus() { return status; } /** * Set the order status * @param status the status of the order */ @JsonProperty public void setStatus(String status) { this.status = status; } /** * Get the order status transitions * @return statusTransitions the JSON object of status transitions */ @JsonProperty public ObjectNode getStatusTransitions() { return statusTransitions; } /** * Set the order status transitions * @param statusTransitions the JSON object of status transitions */ @JsonProperty public void setStatusTransitions(ObjectNode statusTransitions) { this.statusTransitions = statusTransitions; } /** * Get the order updated date * @return updated the order updated date */ @JsonProperty public Integer getUpdated() { return updated; } /** * Set the order updated date * @param updated the order updated date in seconds since the epoch */ @JsonProperty public void setUpdated(Integer updated) { this.updated = updated; } /** * Get the order series identifier * @return the order series identifier */ @JsonProperty public String getSeriesId() { return seriesId; } /** * Set the order series identifier * @param seriesId the order series identifier */ @JsonProperty public void setSeriesId(String seriesId) { this.seriesId = seriesId; } /** * Get the order start date * @return the order start date */ @JsonProperty public Integer getStartDate() { return startDate; } /** * Set the order start date * @param startDate the order start date */ @JsonProperty public void setStartDate(Integer startDate) { this.startDate = startDate; } /** * Get the order end date * @return the order end date */ @JsonProperty public Integer getEndDate() { return endDate; } /** * Set the order end date * @param endDate the order end date */ @JsonProperty public void setEndDate(Integer endDate) { this.endDate = endDate; } /** * Get the order quotas * @return quotas the order quotas */ @JsonProperty public List getQuotas() { return quotas; } /** * Set the order quotas * @param quotas the order quotas */ @JsonProperty public void setQuotas(List quotas) { this.quotas = quotas; } /** * Return the charge hash as a JSON string * @return charge the charge hash as a JSON string * @throws JsonProcessingException a JSON processing exception */ public String getChargeJSON() throws JsonProcessingException { if ( charge != null ) { return new ObjectMapper().writeValueAsString(getCharge()); } else { return "{}"; } } /** * Return the items list as a JSON array * @return items the order items list * @throws IOException an I/O exception */ public String getItemsJSON() throws IOException { if ( items != null ) { ObjectMapper mapper = new ObjectMapper(); ArrayNode itemsArray = mapper.createArrayNode(); for (OrderItem item : items) { itemsArray.add(mapper.readTree(mapper.writeValueAsString(item))); } return itemsArray.toString(); } else { return "[]"; } } /** * Return the metadata hash as a JSON string * @return metadata the metadata hash as a JSON string * @throws JsonProcessingException a JSON processing exception */ public String getMetadataJSON() throws JsonProcessingException { if ( metadata != null ) { return new ObjectMapper().writeValueAsString(getMetadata()); } else { return "{}"; } } /** * Return the charge hash as a JSON string * @return charge the charge hash as a JSON string * @throws JsonProcessingException a JSON processing exception */ public String getStatusTransitionsJSON() throws JsonProcessingException { if ( statusTransitions != null ) { return new ObjectMapper().writeValueAsString(getStatusTransitions()); } else { return "{}"; } } /** * Determine equality of another order * @param o the object to compare * @return true if they are equal */ @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Order order = (Order) o; return Objects.equals(getId(), order.getId()) && getObject().equals(order.getObject()) && getAmount().equals(order.getAmount()) && Objects.equals(getAmountReturned(), order.getAmountReturned()) && Objects.equals(getCharge(), order.getCharge()) && Objects.equals(getCreated(), order.getCreated()) && Objects.equals(getCurrency(), order.getCurrency()) && Objects.equals(getSubject(), order.getSubject()) && getCustomer().equals(order.getCustomer()) && Objects.equals(getEmail(), order.getEmail()) && getItems().equals(order.getItems()) && Objects.equals(getMetadata(), order.getMetadata()) && Objects.equals(getName(), order.getName()) && getStatus().equals(order.getStatus()) && Objects.equals(getStatusTransitions(), order.getStatusTransitions()) && Objects.equals(getUpdated(), order.getUpdated()) && getSeriesId().equals(order.getSeriesId()) && Objects.equals(getStartDate(), order.getStartDate()) && Objects.equals(getEndDate(), order.getEndDate()) && Objects.equals(getQuotas(), order.getQuotas()); } /** * Generate an order hash code * @return hash the order hash */ @Override public int hashCode() { return Objects.hash(getId(), getObject(), getAmount(), getAmountReturned(), getCharge(), getCreated(), getCurrency(), getSubject(), getCustomer(), getEmail(), getItems(), getMetadata(), getName(), getStatus(), getStatusTransitions(), getUpdated(), getSeriesId(), getStartDate(), getEndDate(), getQuotas()); } }