<?php

namespace Square\Types;

use Square\Core\Json\JsonSerializableType;
use Square\Core\Json\JsonProperty;

/**
 * Represents the transfer of a quantity of product inventory at a
 * particular time from one location to another.
 */
class InventoryTransfer extends JsonSerializableType
{
    /**
     * A unique ID generated by Square for the
     * `InventoryTransfer`.
     *
     * @var ?string $id
     */
    #[JsonProperty('id')]
    private ?string $id;

    /**
     * An optional ID provided by the application to tie the
     * `InventoryTransfer` to an external system.
     *
     * @var ?string $referenceId
     */
    #[JsonProperty('reference_id')]
    private ?string $referenceId;

    /**
     * The [inventory state](entity:InventoryState) for the quantity of
     * items being transferred.
     * See [InventoryState](#type-inventorystate) for possible values
     *
     * @var ?value-of<InventoryState> $state
     */
    #[JsonProperty('state')]
    private ?string $state;

    /**
     * The Square-generated ID of the [Location](entity:Location) where the related
     * quantity of items was tracked before the transfer.
     *
     * @var ?string $fromLocationId
     */
    #[JsonProperty('from_location_id')]
    private ?string $fromLocationId;

    /**
     * The Square-generated ID of the [Location](entity:Location) where the related
     * quantity of items was tracked after the transfer.
     *
     * @var ?string $toLocationId
     */
    #[JsonProperty('to_location_id')]
    private ?string $toLocationId;

    /**
     * The Square-generated ID of the
     * [CatalogObject](entity:CatalogObject) being tracked.
     *
     * @var ?string $catalogObjectId
     */
    #[JsonProperty('catalog_object_id')]
    private ?string $catalogObjectId;

    /**
     * The [type](entity:CatalogObjectType) of the [CatalogObject](entity:CatalogObject) being tracked.
     *
     * The Inventory API supports setting and reading the `"catalog_object_type": "ITEM_VARIATION"` field value.
     * In addition, it can also read the `"catalog_object_type": "ITEM"` field value that is set by the Square Restaurants app.
     *
     * @var ?string $catalogObjectType
     */
    #[JsonProperty('catalog_object_type')]
    private ?string $catalogObjectType;

    /**
     * The number of items affected by the transfer as a decimal string.
     * Can support up to 5 digits after the decimal point.
     *
     * @var ?string $quantity
     */
    #[JsonProperty('quantity')]
    private ?string $quantity;

    /**
     * A client-generated RFC 3339-formatted timestamp that indicates when
     * the transfer took place. For write actions, the `occurred_at` timestamp
     * cannot be older than 24 hours or in the future relative to the time of the
     * request.
     *
     * @var ?string $occurredAt
     */
    #[JsonProperty('occurred_at')]
    private ?string $occurredAt;

    /**
     * An RFC 3339-formatted timestamp that indicates when Square
     * received the transfer request.
     *
     * @var ?string $createdAt
     */
    #[JsonProperty('created_at')]
    private ?string $createdAt;

    /**
     * Information about the application that initiated the
     * inventory transfer.
     *
     * @var ?SourceApplication $source
     */
    #[JsonProperty('source')]
    private ?SourceApplication $source;

    /**
     * The Square-generated ID of the [Employee](entity:Employee) responsible for the
     * inventory transfer.
     *
     * @var ?string $employeeId
     */
    #[JsonProperty('employee_id')]
    private ?string $employeeId;

    /**
     * The Square-generated ID of the [Team Member](entity:TeamMember) responsible for the
     * inventory transfer.
     *
     * @var ?string $teamMemberId
     */
    #[JsonProperty('team_member_id')]
    private ?string $teamMemberId;

    /**
     * @param array{
     *   id?: ?string,
     *   referenceId?: ?string,
     *   state?: ?value-of<InventoryState>,
     *   fromLocationId?: ?string,
     *   toLocationId?: ?string,
     *   catalogObjectId?: ?string,
     *   catalogObjectType?: ?string,
     *   quantity?: ?string,
     *   occurredAt?: ?string,
     *   createdAt?: ?string,
     *   source?: ?SourceApplication,
     *   employeeId?: ?string,
     *   teamMemberId?: ?string,
     * } $values
     */
    public function __construct(
        array $values = [],
    ) {
        $this->id = $values['id'] ?? null;
        $this->referenceId = $values['referenceId'] ?? null;
        $this->state = $values['state'] ?? null;
        $this->fromLocationId = $values['fromLocationId'] ?? null;
        $this->toLocationId = $values['toLocationId'] ?? null;
        $this->catalogObjectId = $values['catalogObjectId'] ?? null;
        $this->catalogObjectType = $values['catalogObjectType'] ?? null;
        $this->quantity = $values['quantity'] ?? null;
        $this->occurredAt = $values['occurredAt'] ?? null;
        $this->createdAt = $values['createdAt'] ?? null;
        $this->source = $values['source'] ?? null;
        $this->employeeId = $values['employeeId'] ?? null;
        $this->teamMemberId = $values['teamMemberId'] ?? null;
    }

    /**
     * @return ?string
     */
    public function getId(): ?string
    {
        return $this->id;
    }

    /**
     * @param ?string $value
     */
    public function setId(?string $value = null): self
    {
        $this->id = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getReferenceId(): ?string
    {
        return $this->referenceId;
    }

    /**
     * @param ?string $value
     */
    public function setReferenceId(?string $value = null): self
    {
        $this->referenceId = $value;
        return $this;
    }

    /**
     * @return ?value-of<InventoryState>
     */
    public function getState(): ?string
    {
        return $this->state;
    }

    /**
     * @param ?value-of<InventoryState> $value
     */
    public function setState(?string $value = null): self
    {
        $this->state = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getFromLocationId(): ?string
    {
        return $this->fromLocationId;
    }

    /**
     * @param ?string $value
     */
    public function setFromLocationId(?string $value = null): self
    {
        $this->fromLocationId = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getToLocationId(): ?string
    {
        return $this->toLocationId;
    }

    /**
     * @param ?string $value
     */
    public function setToLocationId(?string $value = null): self
    {
        $this->toLocationId = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getCatalogObjectId(): ?string
    {
        return $this->catalogObjectId;
    }

    /**
     * @param ?string $value
     */
    public function setCatalogObjectId(?string $value = null): self
    {
        $this->catalogObjectId = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getCatalogObjectType(): ?string
    {
        return $this->catalogObjectType;
    }

    /**
     * @param ?string $value
     */
    public function setCatalogObjectType(?string $value = null): self
    {
        $this->catalogObjectType = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getQuantity(): ?string
    {
        return $this->quantity;
    }

    /**
     * @param ?string $value
     */
    public function setQuantity(?string $value = null): self
    {
        $this->quantity = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getOccurredAt(): ?string
    {
        return $this->occurredAt;
    }

    /**
     * @param ?string $value
     */
    public function setOccurredAt(?string $value = null): self
    {
        $this->occurredAt = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getCreatedAt(): ?string
    {
        return $this->createdAt;
    }

    /**
     * @param ?string $value
     */
    public function setCreatedAt(?string $value = null): self
    {
        $this->createdAt = $value;
        return $this;
    }

    /**
     * @return ?SourceApplication
     */
    public function getSource(): ?SourceApplication
    {
        return $this->source;
    }

    /**
     * @param ?SourceApplication $value
     */
    public function setSource(?SourceApplication $value = null): self
    {
        $this->source = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getEmployeeId(): ?string
    {
        return $this->employeeId;
    }

    /**
     * @param ?string $value
     */
    public function setEmployeeId(?string $value = null): self
    {
        $this->employeeId = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getTeamMemberId(): ?string
    {
        return $this->teamMemberId;
    }

    /**
     * @param ?string $value
     */
    public function setTeamMemberId(?string $value = null): self
    {
        $this->teamMemberId = $value;
        return $this;
    }

    /**
     * @return string
     */
    public function __toString(): string
    {
        return $this->toJson();
    }
}
