/*-
 * ========================LICENSE_START=================================
 * org.etsi.osl.tmf.api
 * %%
 * Copyright (C) 2019 - 2021 openslice.io
 * %%
 * 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.
 * =========================LICENSE_END==================================
 */
package org.etsi.osl.tmf.po622.model;

import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.etsi.osl.tmf.common.model.service.Note;
import org.etsi.osl.tmf.pim637.model.BillingAccountRef;
import org.etsi.osl.tmf.prm669.model.RelatedParty;
import org.springframework.validation.annotation.Validated;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

/**
 * A Product Order is a type of order which can be used to place an order between a customer and a
 * service provider or between a service provider and a partner and vice versa, Skipped properties:
 * id,href,orderDate
 */
@Schema(
    description = "A Product Order is a type of order which  can  be used to place an order between a customer and a service provider or between a service provider and a partner and vice versa, Skipped properties: id,href,orderDate")
@Validated
@jakarta.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen",
    date = "2020-10-30T10:29:21.184964400+02:00[Europe/Athens]")
public class ProductOrderUpdate {
  @JsonProperty("cancellationDate")
  private OffsetDateTime cancellationDate = null;

  @JsonProperty("cancellationReason")
  private String cancellationReason = null;

  @JsonProperty("category")
  private String category = null;


  private OffsetDateTime completionDate = null;

  @JsonProperty("description")
  private String description = null;

  private OffsetDateTime expectedCompletionDate = null;

  @JsonProperty("externalId")
  private String externalId = null;

  @JsonProperty("notificationContact")
  private String notificationContact = null;

  @JsonProperty("priority")
  private String priority = null;

  private OffsetDateTime requestedCompletionDate = null;

  private OffsetDateTime requestedStartDate = null;

  @JsonProperty("agreement")
  @Valid
  private List<AgreementRef> agreement = null;

  @JsonProperty("billingAccount")
  private BillingAccountRef billingAccount = null;

  @JsonProperty("channel")
  @Valid
  private List<RelatedChannel> channel = null;

  @JsonProperty("note")
  @Valid
  private List<Note> note = null;

  @JsonProperty("orderTotalPrice")
  @Valid
  private List<OrderPrice> orderTotalPrice = null;

  @JsonProperty("payment")
  @Valid
  private List<PaymentRef> payment = null;

  @JsonProperty("productOfferingQualification")
  @Valid
  private List<ProductOfferingQualificationRef> productOfferingQualification = null;

  @JsonProperty("productOrderItem")
  @Valid
  private List<ProductOrderItem> productOrderItem = new ArrayList<>();

  @JsonProperty("quote")
  @Valid
  private List<QuoteRef> quote = null;

  @JsonProperty("relatedParty")
  @Valid
  private List<RelatedParty> relatedParty = null;

  @JsonProperty("state")
  private ProductOrderStateType state = null;

  @JsonProperty("@baseType")
  private String baseType = null;

  @JsonProperty("@schemaLocation")
  private String schemaLocation = null;

  @JsonProperty("@type")
  private String type = null;

  public ProductOrderUpdate cancellationDate(OffsetDateTime cancellationDate) {
    this.cancellationDate = cancellationDate;
    return this;
  }

  /**
   * Date when the order is cancelled. This is used when order is cancelled.
   * 
   * @return cancellationDate
   **/
  @Schema(description = "Date when the order is cancelled. This is used when order is cancelled. ")

  @Valid
  public OffsetDateTime getCancellationDate() {
    return cancellationDate;
  }

  public void setCancellationDate(OffsetDateTime cancellationDate) {
    this.cancellationDate = cancellationDate;
  }

  public ProductOrderUpdate cancellationReason(String cancellationReason) {
    this.cancellationReason = cancellationReason;
    return this;
  }

  /**
   * Reason why the order is cancelled. This is used when order is cancelled.
   * 
   * @return cancellationReason
   **/
  @Schema(description = "Reason why the order is cancelled. This is used when order is cancelled. ")

  public String getCancellationReason() {
    return cancellationReason;
  }

  public void setCancellationReason(String cancellationReason) {
    this.cancellationReason = cancellationReason;
  }

  public ProductOrderUpdate category(String category) {
    this.category = category;
    return this;
  }

  /**
   * Used to categorize the order from a business perspective that can be useful for the OM system
   * (e.g. \"enterprise\", \"residential\", ...)
   * 
   * @return category
   **/
  @Schema(
      description = "Used to categorize the order from a business perspective that can be useful for the OM system (e.g. \"enterprise\", \"residential\", ...)")

  public String getCategory() {
    return category;
  }

  public void setCategory(String category) {
    this.category = category;
  }

  public ProductOrderUpdate completionDate(OffsetDateTime completionDate) {
    this.completionDate = completionDate;
    return this;
  }

  /**
   * Date when the order was completed
   * 
   * @return completionDate
   **/
  @Schema(description = "Date when the order was completed")

  @Valid
  public OffsetDateTime getCompletionDate() {
    return completionDate;
  }

  public void setCompletionDate(OffsetDateTime completionDate) {
    this.completionDate = completionDate;
  }

  public ProductOrderUpdate description(String description) {
    this.description = description;
    return this;
  }

  @JsonProperty("completionDate")

  public String getCompletionDateStr() {
    if (completionDate != null) {
      return completionDate.toString();
    } else {
      return null;
    }
  }

  public void setCompletionDate(String completionDate) {

    if (completionDate != null) {
      this.completionDate = OffsetDateTime.parse(completionDate);

    }
  }


  /**
   * Description of the product order
   * 
   * @return description
   **/
  @Schema(description = "Description of the product order")

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public ProductOrderUpdate expectedCompletionDate(OffsetDateTime expectedCompletionDate) {
    this.expectedCompletionDate = expectedCompletionDate;
    return this;
  }

  /**
   * Expected delivery date amended by the provider
   * 
   * @return expectedCompletionDate
   **/
  @Schema(description = "Expected delivery date amended by the provider")

  @Valid
  public OffsetDateTime getExpectedCompletionDate() {
    return expectedCompletionDate;
  }

  @JsonProperty("expectedCompletionDate")
  public String getExpectedCompletionDateStr() {
    if (expectedCompletionDate != null) {
      return expectedCompletionDate.toString();
    } else {
      return null;
    }
  }

  public void setExpectedCompletionDate(OffsetDateTime expectedCompletionDate) {
    this.expectedCompletionDate = expectedCompletionDate;
  }

  public void setExpectedCompletionDate(String expectedCompletionDate) {

    if (expectedCompletionDate != null) {
      this.expectedCompletionDate = OffsetDateTime.parse(expectedCompletionDate);

    }
  }

  public ProductOrderUpdate externalId(String externalId) {
    this.externalId = externalId;
    return this;
  }

  /**
   * ID given by the consumer and only understandable by him (to facilitate his searches afterwards)
   * 
   * @return externalId
   **/
  @Schema(
      description = "ID given by the consumer and only understandable by him (to facilitate his searches afterwards)")

  public String getExternalId() {
    return externalId;
  }

  public void setExternalId(String externalId) {
    this.externalId = externalId;
  }

  public ProductOrderUpdate notificationContact(String notificationContact) {
    this.notificationContact = notificationContact;
    return this;
  }

  /**
   * Contact attached to the order to send back information regarding this order
   * 
   * @return notificationContact
   **/
  @Schema(
      description = "Contact attached to the order to send back information regarding this order")

  public String getNotificationContact() {
    return notificationContact;
  }

  public void setNotificationContact(String notificationContact) {
    this.notificationContact = notificationContact;
  }

  public ProductOrderUpdate priority(String priority) {
    this.priority = priority;
    return this;
  }

  /**
   * A way that can be used by consumers to prioritize orders in OM system (from 0 to 4 : 0 is the
   * highest priority, and 4 the lowest)
   * 
   * @return priority
   **/
  @Schema(
      description = "A way that can be used by consumers to prioritize orders in OM system (from 0 to 4 : 0 is the highest priority, and 4 the lowest)")

  public String getPriority() {
    return priority;
  }

  public void setPriority(String priority) {
    this.priority = priority;
  }

  public ProductOrderUpdate requestedCompletionDate(OffsetDateTime requestedCompletionDate) {
    this.requestedCompletionDate = requestedCompletionDate;
    return this;
  }

  @JsonProperty("requestedCompletionDate")
  public String getRequestedCompletionDateStr() {
    if (requestedCompletionDate != null) {
      return requestedCompletionDate.toString();
    } else {
      return null;
    }
  }

  public void setRequestedCompletionDate(String requestedCompletionDate) {

    if (requestedCompletionDate != null) {
      this.requestedCompletionDate = OffsetDateTime.parse(requestedCompletionDate);

    }
  }

  /**
   * Requested delivery date from the requestor perspective
   * 
   * @return requestedCompletionDate
   **/
  @Schema(description = "Requested delivery date from the requestor perspective")

  @Valid
  public OffsetDateTime getRequestedCompletionDate() {
    return requestedCompletionDate;
  }

  public void setRequestedCompletionDate(OffsetDateTime requestedCompletionDate) {
    this.requestedCompletionDate = requestedCompletionDate;
  }

  public ProductOrderUpdate requestedStartDate(OffsetDateTime requestedStartDate) {
    this.requestedStartDate = requestedStartDate;
    return this;
  }

  /**
   * Order fulfillment start date wished by the requestor. This is used when, for any reason,
   * requestor cannot allow seller to begin to operationally begin the fulfillment before a date.
   * 
   * @return requestedStartDate
   **/
  @Schema(
      description = "Order fulfillment start date wished by the requestor. This is used when, for any reason, requestor cannot allow seller to begin to operationally begin the fulfillment before a date. ")

  @Valid
  public OffsetDateTime getRequestedStartDate() {
    return requestedStartDate;
  }

  public void setRequestedStartDate(OffsetDateTime requestedStartDate) {
    this.requestedStartDate = requestedStartDate;
  }
  
  @JsonProperty("requestedStartDate")
  public String getRequestedStartDateStr() {

    if (requestedStartDate != null) {
      return requestedStartDate.toString();
    }

    return null;
  }
  
  public void setRequestedStartDate(String requestedStartDate) {

    if (requestedStartDate != null) {
      this.requestedStartDate = OffsetDateTime.parse(requestedStartDate);

    }
  }

  public ProductOrderUpdate agreement(List<AgreementRef> agreement) {
    this.agreement = agreement;
    return this;
  }

  public ProductOrderUpdate addAgreementItem(AgreementRef agreementItem) {
    if (this.agreement == null) {
      this.agreement = new ArrayList<>();
    }
    this.agreement.add(agreementItem);
    return this;
  }

  /**
   * A reference to an agreement defined in the context of the product order
   * 
   * @return agreement
   **/
  @Schema(description = "A reference to an agreement defined in the context of the product order")
  @Valid
  public List<AgreementRef> getAgreement() {
    return agreement;
  }

  public void setAgreement(List<AgreementRef> agreement) {
    this.agreement = agreement;
  }

  public ProductOrderUpdate billingAccount(BillingAccountRef billingAccount) {
    this.billingAccount = billingAccount;
    return this;
  }

  /**
   * Get billingAccount
   * 
   * @return billingAccount
   **/
  @Schema(description = "")

  @Valid
  public BillingAccountRef getBillingAccount() {
    return billingAccount;
  }

  public void setBillingAccount(BillingAccountRef billingAccount) {
    this.billingAccount = billingAccount;
  }

  public ProductOrderUpdate channel(List<RelatedChannel> channel) {
    this.channel = channel;
    return this;
  }

  public ProductOrderUpdate addChannelItem(RelatedChannel channelItem) {
    if (this.channel == null) {
      this.channel = new ArrayList<>();
    }
    this.channel.add(channelItem);
    return this;
  }

  /**
   * Get channel
   * 
   * @return channel
   **/
  @Schema(description = "")
  @Valid
  public List<RelatedChannel> getChannel() {
    return channel;
  }

  public void setChannel(List<RelatedChannel> channel) {
    this.channel = channel;
  }

  public ProductOrderUpdate note(List<Note> note) {
    this.note = note;
    return this;
  }

  public ProductOrderUpdate addNoteItem(Note noteItem) {
    if (this.note == null) {
      this.note = new ArrayList<>();
    }
    this.note.add(noteItem);
    return this;
  }

  /**
   * Get note
   * 
   * @return note
   **/
  @Schema(description = "")
  @Valid
  public List<Note> getNote() {
    return note;
  }

  public void setNote(List<Note> note) {
    this.note = note;
  }

  public ProductOrderUpdate orderTotalPrice(List<OrderPrice> orderTotalPrice) {
    this.orderTotalPrice = orderTotalPrice;
    return this;
  }

  public ProductOrderUpdate addOrderTotalPriceItem(OrderPrice orderTotalPriceItem) {
    if (this.orderTotalPrice == null) {
      this.orderTotalPrice = new ArrayList<>();
    }
    this.orderTotalPrice.add(orderTotalPriceItem);
    return this;
  }

  /**
   * Get orderTotalPrice
   * 
   * @return orderTotalPrice
   **/
  @Schema(description = "")
  @Valid
  public List<OrderPrice> getOrderTotalPrice() {
    return orderTotalPrice;
  }

  public void setOrderTotalPrice(List<OrderPrice> orderTotalPrice) {
    this.orderTotalPrice = orderTotalPrice;
  }

  public ProductOrderUpdate payment(List<PaymentRef> payment) {
    this.payment = payment;
    return this;
  }

  public ProductOrderUpdate addPaymentItem(PaymentRef paymentItem) {
    if (this.payment == null) {
      this.payment = new ArrayList<>();
    }
    this.payment.add(paymentItem);
    return this;
  }

  /**
   * Get payment
   * 
   * @return payment
   **/
  @Schema(description = "")
  @Valid
  public List<PaymentRef> getPayment() {
    return payment;
  }

  public void setPayment(List<PaymentRef> payment) {
    this.payment = payment;
  }

  public ProductOrderUpdate productOfferingQualification(
      List<ProductOfferingQualificationRef> productOfferingQualification) {
    this.productOfferingQualification = productOfferingQualification;
    return this;
  }

  public ProductOrderUpdate addProductOfferingQualificationItem(
      ProductOfferingQualificationRef productOfferingQualificationItem) {
    if (this.productOfferingQualification == null) {
      this.productOfferingQualification = new ArrayList<>();
    }
    this.productOfferingQualification.add(productOfferingQualificationItem);
    return this;
  }

  /**
   * Get productOfferingQualification
   * 
   * @return productOfferingQualification
   **/
  @Schema(description = "")
  @Valid
  public List<ProductOfferingQualificationRef> getProductOfferingQualification() {
    return productOfferingQualification;
  }

  public void setProductOfferingQualification(
      List<ProductOfferingQualificationRef> productOfferingQualification) {
    this.productOfferingQualification = productOfferingQualification;
  }

  public ProductOrderUpdate productOrderItem(List<ProductOrderItem> productOrderItem) {
    this.productOrderItem = productOrderItem;
    return this;
  }

  public ProductOrderUpdate addProductOrderItemItem(ProductOrderItem productOrderItemItem) {
    this.productOrderItem.add(productOrderItemItem);
    return this;
  }

  /**
   * Get productOrderItem
   * 
   * @return productOrderItem
   **/
  @Schema(description = "")
  @NotNull
  @Valid
  @Size(min = 1)
  public List<ProductOrderItem> getProductOrderItem() {
    return productOrderItem;
  }

  public void setProductOrderItem(List<ProductOrderItem> productOrderItem) {
    this.productOrderItem = productOrderItem;
  }

  public ProductOrderUpdate quote(List<QuoteRef> quote) {
    this.quote = quote;
    return this;
  }

  public ProductOrderUpdate addQuoteItem(QuoteRef quoteItem) {
    if (this.quote == null) {
      this.quote = new ArrayList<>();
    }
    this.quote.add(quoteItem);
    return this;
  }

  /**
   * Get quote
   * 
   * @return quote
   **/
  @Schema(description = "")
  @Valid
  public List<QuoteRef> getQuote() {
    return quote;
  }

  public void setQuote(List<QuoteRef> quote) {
    this.quote = quote;
  }

  public ProductOrderUpdate relatedParty(List<RelatedParty> relatedParty) {
    this.relatedParty = relatedParty;
    return this;
  }

  public ProductOrderUpdate addRelatedPartyItem(RelatedParty relatedPartyItem) {
    if (this.relatedParty == null) {
      this.relatedParty = new ArrayList<>();
    }
    this.relatedParty.add(relatedPartyItem);
    return this;
  }

  /**
   * Get relatedParty
   * 
   * @return relatedParty
   **/
  @Schema(description = "")
  @Valid
  public List<RelatedParty> getRelatedParty() {
    return relatedParty;
  }

  public void setRelatedParty(List<RelatedParty> relatedParty) {
    this.relatedParty = relatedParty;
  }

  public ProductOrderUpdate state(ProductOrderStateType state) {
    this.state = state;
    return this;
  }

  /**
   * Get state
   * 
   * @return state
   **/
  @Schema(description = "")

  @Valid
  public ProductOrderStateType getState() {
    return state;
  }

  public void setState(ProductOrderStateType state) {
    this.state = state;
  }

  public ProductOrderUpdate baseType(String baseType) {
    this.baseType = baseType;
    return this;
  }

  /**
   * When sub-classing, this defines the super-class
   * 
   * @return baseType
   **/
  @Schema(description = "When sub-classing, this defines the super-class")

  public String getAtBaseType() {
    return baseType;
  }

  public void setAtBaseType(String baseType) {
    this.baseType = baseType;
  }

  public ProductOrderUpdate schemaLocation(String schemaLocation) {
    this.schemaLocation = schemaLocation;
    return this;
  }

  /**
   * A URI to a JSON-Schema file that defines additional attributes and relationships
   * 
   * @return schemaLocation
   **/
  @Schema(
      description = "A URI to a JSON-Schema file that defines additional attributes and relationships")

  public String getAtSchemaLocation() {
    return schemaLocation;
  }

  public void setAtSchemaLocation(String schemaLocation) {
    this.schemaLocation = schemaLocation;
  }

  public ProductOrderUpdate type(String type) {
    this.type = type;
    return this;
  }

  /**
   * When sub-classing, this defines the sub-class entity name
   * 
   * @return type
   **/
  @Schema(description = "When sub-classing, this defines the sub-class entity name")

  public String getAtType() {
    return type;
  }

  public void setAtType(String type) {
    this.type = type;
  }


  @Override
  public boolean equals(java.lang.Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    ProductOrderUpdate productOrderUpdate = (ProductOrderUpdate) o;
    return Objects.equals(this.cancellationDate, productOrderUpdate.cancellationDate)
        && Objects.equals(this.cancellationReason, productOrderUpdate.cancellationReason)
        && Objects.equals(this.category, productOrderUpdate.category)
        && Objects.equals(this.completionDate, productOrderUpdate.completionDate)
        && Objects.equals(this.description, productOrderUpdate.description)
        && Objects.equals(this.expectedCompletionDate, productOrderUpdate.expectedCompletionDate)
        && Objects.equals(this.externalId, productOrderUpdate.externalId)
        && Objects.equals(this.notificationContact, productOrderUpdate.notificationContact)
        && Objects.equals(this.priority, productOrderUpdate.priority)
        && Objects.equals(this.requestedCompletionDate, productOrderUpdate.requestedCompletionDate)
        && Objects.equals(this.requestedStartDate, productOrderUpdate.requestedStartDate)
        && Objects.equals(this.agreement, productOrderUpdate.agreement)
        && Objects.equals(this.billingAccount, productOrderUpdate.billingAccount)
        && Objects.equals(this.channel, productOrderUpdate.channel)
        && Objects.equals(this.note, productOrderUpdate.note)
        && Objects.equals(this.orderTotalPrice, productOrderUpdate.orderTotalPrice)
        && Objects.equals(this.payment, productOrderUpdate.payment)
        && Objects.equals(this.productOfferingQualification,
            productOrderUpdate.productOfferingQualification)
        && Objects.equals(this.productOrderItem, productOrderUpdate.productOrderItem)
        && Objects.equals(this.quote, productOrderUpdate.quote)
        && Objects.equals(this.relatedParty, productOrderUpdate.relatedParty)
        && Objects.equals(this.state, productOrderUpdate.state)
        && Objects.equals(this.baseType, productOrderUpdate.baseType)
        && Objects.equals(this.schemaLocation, productOrderUpdate.schemaLocation)
        && Objects.equals(this.type, productOrderUpdate.type);
  }

  @Override
  public int hashCode() {
    return Objects.hash(cancellationDate, cancellationReason, category, completionDate, description,
        expectedCompletionDate, externalId, notificationContact, priority, requestedCompletionDate,
        requestedStartDate, agreement, billingAccount, channel, note, orderTotalPrice, payment,
        productOfferingQualification, productOrderItem, quote, relatedParty, state, baseType,
        schemaLocation, type);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class ProductOrderUpdate {\n");

    sb.append("    cancellationDate: ").append(toIndentedString(cancellationDate)).append("\n");
    sb.append("    cancellationReason: ").append(toIndentedString(cancellationReason)).append("\n");
    sb.append("    category: ").append(toIndentedString(category)).append("\n");
    sb.append("    completionDate: ").append(toIndentedString(completionDate)).append("\n");
    sb.append("    description: ").append(toIndentedString(description)).append("\n");
    sb.append("    expectedCompletionDate: ").append(toIndentedString(expectedCompletionDate))
        .append("\n");
    sb.append("    externalId: ").append(toIndentedString(externalId)).append("\n");
    sb.append("    notificationContact: ").append(toIndentedString(notificationContact))
        .append("\n");
    sb.append("    priority: ").append(toIndentedString(priority)).append("\n");
    sb.append("    requestedCompletionDate: ").append(toIndentedString(requestedCompletionDate))
        .append("\n");
    sb.append("    requestedStartDate: ").append(toIndentedString(requestedStartDate)).append("\n");
    sb.append("    agreement: ").append(toIndentedString(agreement)).append("\n");
    sb.append("    billingAccount: ").append(toIndentedString(billingAccount)).append("\n");
    sb.append("    channel: ").append(toIndentedString(channel)).append("\n");
    sb.append("    note: ").append(toIndentedString(note)).append("\n");
    sb.append("    orderTotalPrice: ").append(toIndentedString(orderTotalPrice)).append("\n");
    sb.append("    payment: ").append(toIndentedString(payment)).append("\n");
    sb.append("    productOfferingQualification: ")
        .append(toIndentedString(productOfferingQualification)).append("\n");
    sb.append("    productOrderItem: ").append(toIndentedString(productOrderItem)).append("\n");
    sb.append("    quote: ").append(toIndentedString(quote)).append("\n");
    sb.append("    relatedParty: ").append(toIndentedString(relatedParty)).append("\n");
    sb.append("    state: ").append(toIndentedString(state)).append("\n");
    sb.append("    baseType: ").append(toIndentedString(baseType)).append("\n");
    sb.append("    schemaLocation: ").append(toIndentedString(schemaLocation)).append("\n");
    sb.append("    type: ").append(toIndentedString(type)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces (except the first line).
   */
  private String toIndentedString(java.lang.Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}
