<?php

declare (strict_types=1);
namespace WPForms\Vendor\Square\Models;

use stdClass;
/**
 * Represents a tender (i.e., a method of payment) used in a Square transaction.
 */
class Tender implements \JsonSerializable
{
    /**
     * @var string|null
     */
    private $id;
    /**
     * @var array
     */
    private $locationId = [];
    /**
     * @var array
     */
    private $transactionId = [];
    /**
     * @var string|null
     */
    private $createdAt;
    /**
     * @var array
     */
    private $note = [];
    /**
     * @var Money|null
     */
    private $amountMoney;
    /**
     * @var Money|null
     */
    private $tipMoney;
    /**
     * @var Money|null
     */
    private $processingFeeMoney;
    /**
     * @var array
     */
    private $customerId = [];
    /**
     * @var string
     */
    private $type;
    /**
     * @var TenderCardDetails|null
     */
    private $cardDetails;
    /**
     * @var TenderCashDetails|null
     */
    private $cashDetails;
    /**
     * @var TenderBankAccountDetails|null
     */
    private $bankAccountDetails;
    /**
     * @var TenderBuyNowPayLaterDetails|null
     */
    private $buyNowPayLaterDetails;
    /**
     * @var TenderSquareAccountDetails|null
     */
    private $squareAccountDetails;
    /**
     * @var array
     */
    private $additionalRecipients = [];
    /**
     * @var array
     */
    private $paymentId = [];
    /**
     * @param string $type
     */
    public function __construct(string $type)
    {
        $this->type = $type;
    }
    /**
     * Returns Id.
     * The tender's unique ID. It is the associated payment ID.
     */
    public function getId() : ?string
    {
        return $this->id;
    }
    /**
     * Sets Id.
     * The tender's unique ID. It is the associated payment ID.
     *
     * @maps id
     */
    public function setId(?string $id) : void
    {
        $this->id = $id;
    }
    /**
     * Returns Location Id.
     * The ID of the transaction's associated location.
     */
    public function getLocationId() : ?string
    {
        if (\count($this->locationId) == 0) {
            return null;
        }
        return $this->locationId['value'];
    }
    /**
     * Sets Location Id.
     * The ID of the transaction's associated location.
     *
     * @maps location_id
     */
    public function setLocationId(?string $locationId) : void
    {
        $this->locationId['value'] = $locationId;
    }
    /**
     * Unsets Location Id.
     * The ID of the transaction's associated location.
     */
    public function unsetLocationId() : void
    {
        $this->locationId = [];
    }
    /**
     * Returns Transaction Id.
     * The ID of the tender's associated transaction.
     */
    public function getTransactionId() : ?string
    {
        if (\count($this->transactionId) == 0) {
            return null;
        }
        return $this->transactionId['value'];
    }
    /**
     * Sets Transaction Id.
     * The ID of the tender's associated transaction.
     *
     * @maps transaction_id
     */
    public function setTransactionId(?string $transactionId) : void
    {
        $this->transactionId['value'] = $transactionId;
    }
    /**
     * Unsets Transaction Id.
     * The ID of the tender's associated transaction.
     */
    public function unsetTransactionId() : void
    {
        $this->transactionId = [];
    }
    /**
     * Returns Created At.
     * The timestamp for when the tender was created, in RFC 3339 format.
     */
    public function getCreatedAt() : ?string
    {
        return $this->createdAt;
    }
    /**
     * Sets Created At.
     * The timestamp for when the tender was created, in RFC 3339 format.
     *
     * @maps created_at
     */
    public function setCreatedAt(?string $createdAt) : void
    {
        $this->createdAt = $createdAt;
    }
    /**
     * Returns Note.
     * An optional note associated with the tender at the time of payment.
     */
    public function getNote() : ?string
    {
        if (\count($this->note) == 0) {
            return null;
        }
        return $this->note['value'];
    }
    /**
     * Sets Note.
     * An optional note associated with the tender at the time of payment.
     *
     * @maps note
     */
    public function setNote(?string $note) : void
    {
        $this->note['value'] = $note;
    }
    /**
     * Unsets Note.
     * An optional note associated with the tender at the time of payment.
     */
    public function unsetNote() : void
    {
        $this->note = [];
    }
    /**
     * Returns Amount Money.
     * Represents an amount of money. `Money` fields can be signed or unsigned.
     * Fields that do not explicitly define whether they are signed or unsigned are
     * considered unsigned and can only hold positive amounts. For signed fields, the
     * sign of the value indicates the purpose of the money transfer. See
     * [Working with Monetary Amounts](https://developer.squareup.com/docs/build-basics/working-with-
     * monetary-amounts)
     * for more information.
     */
    public function getAmountMoney() : ?Money
    {
        return $this->amountMoney;
    }
    /**
     * Sets Amount Money.
     * Represents an amount of money. `Money` fields can be signed or unsigned.
     * Fields that do not explicitly define whether they are signed or unsigned are
     * considered unsigned and can only hold positive amounts. For signed fields, the
     * sign of the value indicates the purpose of the money transfer. See
     * [Working with Monetary Amounts](https://developer.squareup.com/docs/build-basics/working-with-
     * monetary-amounts)
     * for more information.
     *
     * @maps amount_money
     */
    public function setAmountMoney(?Money $amountMoney) : void
    {
        $this->amountMoney = $amountMoney;
    }
    /**
     * Returns Tip Money.
     * Represents an amount of money. `Money` fields can be signed or unsigned.
     * Fields that do not explicitly define whether they are signed or unsigned are
     * considered unsigned and can only hold positive amounts. For signed fields, the
     * sign of the value indicates the purpose of the money transfer. See
     * [Working with Monetary Amounts](https://developer.squareup.com/docs/build-basics/working-with-
     * monetary-amounts)
     * for more information.
     */
    public function getTipMoney() : ?Money
    {
        return $this->tipMoney;
    }
    /**
     * Sets Tip Money.
     * Represents an amount of money. `Money` fields can be signed or unsigned.
     * Fields that do not explicitly define whether they are signed or unsigned are
     * considered unsigned and can only hold positive amounts. For signed fields, the
     * sign of the value indicates the purpose of the money transfer. See
     * [Working with Monetary Amounts](https://developer.squareup.com/docs/build-basics/working-with-
     * monetary-amounts)
     * for more information.
     *
     * @maps tip_money
     */
    public function setTipMoney(?Money $tipMoney) : void
    {
        $this->tipMoney = $tipMoney;
    }
    /**
     * Returns Processing Fee Money.
     * Represents an amount of money. `Money` fields can be signed or unsigned.
     * Fields that do not explicitly define whether they are signed or unsigned are
     * considered unsigned and can only hold positive amounts. For signed fields, the
     * sign of the value indicates the purpose of the money transfer. See
     * [Working with Monetary Amounts](https://developer.squareup.com/docs/build-basics/working-with-
     * monetary-amounts)
     * for more information.
     */
    public function getProcessingFeeMoney() : ?Money
    {
        return $this->processingFeeMoney;
    }
    /**
     * Sets Processing Fee Money.
     * Represents an amount of money. `Money` fields can be signed or unsigned.
     * Fields that do not explicitly define whether they are signed or unsigned are
     * considered unsigned and can only hold positive amounts. For signed fields, the
     * sign of the value indicates the purpose of the money transfer. See
     * [Working with Monetary Amounts](https://developer.squareup.com/docs/build-basics/working-with-
     * monetary-amounts)
     * for more information.
     *
     * @maps processing_fee_money
     */
    public function setProcessingFeeMoney(?Money $processingFeeMoney) : void
    {
        $this->processingFeeMoney = $processingFeeMoney;
    }
    /**
     * Returns Customer Id.
     * If the tender is associated with a customer or represents a customer's card on file,
     * this is the ID of the associated customer.
     */
    public function getCustomerId() : ?string
    {
        if (\count($this->customerId) == 0) {
            return null;
        }
        return $this->customerId['value'];
    }
    /**
     * Sets Customer Id.
     * If the tender is associated with a customer or represents a customer's card on file,
     * this is the ID of the associated customer.
     *
     * @maps customer_id
     */
    public function setCustomerId(?string $customerId) : void
    {
        $this->customerId['value'] = $customerId;
    }
    /**
     * Unsets Customer Id.
     * If the tender is associated with a customer or represents a customer's card on file,
     * this is the ID of the associated customer.
     */
    public function unsetCustomerId() : void
    {
        $this->customerId = [];
    }
    /**
     * Returns Type.
     * Indicates a tender's type.
     */
    public function getType() : string
    {
        return $this->type;
    }
    /**
     * Sets Type.
     * Indicates a tender's type.
     *
     * @required
     * @maps type
     */
    public function setType(string $type) : void
    {
        $this->type = $type;
    }
    /**
     * Returns Card Details.
     * Represents additional details of a tender with `type` `CARD` or `SQUARE_GIFT_CARD`
     */
    public function getCardDetails() : ?TenderCardDetails
    {
        return $this->cardDetails;
    }
    /**
     * Sets Card Details.
     * Represents additional details of a tender with `type` `CARD` or `SQUARE_GIFT_CARD`
     *
     * @maps card_details
     */
    public function setCardDetails(?TenderCardDetails $cardDetails) : void
    {
        $this->cardDetails = $cardDetails;
    }
    /**
     * Returns Cash Details.
     * Represents the details of a tender with `type` `CASH`.
     */
    public function getCashDetails() : ?TenderCashDetails
    {
        return $this->cashDetails;
    }
    /**
     * Sets Cash Details.
     * Represents the details of a tender with `type` `CASH`.
     *
     * @maps cash_details
     */
    public function setCashDetails(?TenderCashDetails $cashDetails) : void
    {
        $this->cashDetails = $cashDetails;
    }
    /**
     * Returns Bank Account Details.
     * Represents the details of a tender with `type` `BANK_ACCOUNT`.
     *
     * See [BankAccountPaymentDetails]($m/BankAccountPaymentDetails)
     * for more exposed details of a bank account payment.
     */
    public function getBankAccountDetails() : ?TenderBankAccountDetails
    {
        return $this->bankAccountDetails;
    }
    /**
     * Sets Bank Account Details.
     * Represents the details of a tender with `type` `BANK_ACCOUNT`.
     *
     * See [BankAccountPaymentDetails]($m/BankAccountPaymentDetails)
     * for more exposed details of a bank account payment.
     *
     * @maps bank_account_details
     */
    public function setBankAccountDetails(?TenderBankAccountDetails $bankAccountDetails) : void
    {
        $this->bankAccountDetails = $bankAccountDetails;
    }
    /**
     * Returns Buy Now Pay Later Details.
     * Represents the details of a tender with `type` `BUY_NOW_PAY_LATER`.
     */
    public function getBuyNowPayLaterDetails() : ?TenderBuyNowPayLaterDetails
    {
        return $this->buyNowPayLaterDetails;
    }
    /**
     * Sets Buy Now Pay Later Details.
     * Represents the details of a tender with `type` `BUY_NOW_PAY_LATER`.
     *
     * @maps buy_now_pay_later_details
     */
    public function setBuyNowPayLaterDetails(?TenderBuyNowPayLaterDetails $buyNowPayLaterDetails) : void
    {
        $this->buyNowPayLaterDetails = $buyNowPayLaterDetails;
    }
    /**
     * Returns Square Account Details.
     * Represents the details of a tender with `type` `SQUARE_ACCOUNT`.
     */
    public function getSquareAccountDetails() : ?TenderSquareAccountDetails
    {
        return $this->squareAccountDetails;
    }
    /**
     * Sets Square Account Details.
     * Represents the details of a tender with `type` `SQUARE_ACCOUNT`.
     *
     * @maps square_account_details
     */
    public function setSquareAccountDetails(?TenderSquareAccountDetails $squareAccountDetails) : void
    {
        $this->squareAccountDetails = $squareAccountDetails;
    }
    /**
     * Returns Additional Recipients.
     * Additional recipients (other than the merchant) receiving a portion of this tender.
     * For example, fees assessed on the purchase by a third party integration.
     *
     * @return AdditionalRecipient[]|null
     */
    public function getAdditionalRecipients() : ?array
    {
        if (\count($this->additionalRecipients) == 0) {
            return null;
        }
        return $this->additionalRecipients['value'];
    }
    /**
     * Sets Additional Recipients.
     * Additional recipients (other than the merchant) receiving a portion of this tender.
     * For example, fees assessed on the purchase by a third party integration.
     *
     * @maps additional_recipients
     *
     * @param AdditionalRecipient[]|null $additionalRecipients
     */
    public function setAdditionalRecipients(?array $additionalRecipients) : void
    {
        $this->additionalRecipients['value'] = $additionalRecipients;
    }
    /**
     * Unsets Additional Recipients.
     * Additional recipients (other than the merchant) receiving a portion of this tender.
     * For example, fees assessed on the purchase by a third party integration.
     */
    public function unsetAdditionalRecipients() : void
    {
        $this->additionalRecipients = [];
    }
    /**
     * Returns Payment Id.
     * The ID of the [Payment](entity:Payment) that corresponds to this tender.
     * This value is only present for payments created with the v2 Payments API.
     */
    public function getPaymentId() : ?string
    {
        if (\count($this->paymentId) == 0) {
            return null;
        }
        return $this->paymentId['value'];
    }
    /**
     * Sets Payment Id.
     * The ID of the [Payment](entity:Payment) that corresponds to this tender.
     * This value is only present for payments created with the v2 Payments API.
     *
     * @maps payment_id
     */
    public function setPaymentId(?string $paymentId) : void
    {
        $this->paymentId['value'] = $paymentId;
    }
    /**
     * Unsets Payment Id.
     * The ID of the [Payment](entity:Payment) that corresponds to this tender.
     * This value is only present for payments created with the v2 Payments API.
     */
    public function unsetPaymentId() : void
    {
        $this->paymentId = [];
    }
    /**
     * Encode this object to JSON
     *
     * @param bool $asArrayWhenEmpty Whether to serialize this model as an array whenever no fields
     *        are set. (default: false)
     *
     * @return array|stdClass
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize(bool $asArrayWhenEmpty = \false)
    {
        $json = [];
        if (isset($this->id)) {
            $json['id'] = $this->id;
        }
        if (!empty($this->locationId)) {
            $json['location_id'] = $this->locationId['value'];
        }
        if (!empty($this->transactionId)) {
            $json['transaction_id'] = $this->transactionId['value'];
        }
        if (isset($this->createdAt)) {
            $json['created_at'] = $this->createdAt;
        }
        if (!empty($this->note)) {
            $json['note'] = $this->note['value'];
        }
        if (isset($this->amountMoney)) {
            $json['amount_money'] = $this->amountMoney;
        }
        if (isset($this->tipMoney)) {
            $json['tip_money'] = $this->tipMoney;
        }
        if (isset($this->processingFeeMoney)) {
            $json['processing_fee_money'] = $this->processingFeeMoney;
        }
        if (!empty($this->customerId)) {
            $json['customer_id'] = $this->customerId['value'];
        }
        $json['type'] = $this->type;
        if (isset($this->cardDetails)) {
            $json['card_details'] = $this->cardDetails;
        }
        if (isset($this->cashDetails)) {
            $json['cash_details'] = $this->cashDetails;
        }
        if (isset($this->bankAccountDetails)) {
            $json['bank_account_details'] = $this->bankAccountDetails;
        }
        if (isset($this->buyNowPayLaterDetails)) {
            $json['buy_now_pay_later_details'] = $this->buyNowPayLaterDetails;
        }
        if (isset($this->squareAccountDetails)) {
            $json['square_account_details'] = $this->squareAccountDetails;
        }
        if (!empty($this->additionalRecipients)) {
            $json['additional_recipients'] = $this->additionalRecipients['value'];
        }
        if (!empty($this->paymentId)) {
            $json['payment_id'] = $this->paymentId['value'];
        }
        $json = \array_filter($json, function ($val) {
            return $val !== null;
        });
        return !$asArrayWhenEmpty && empty($json) ? new stdClass() : $json;
    }
}
