<?php

namespace Square\Types;

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

/**
 * Represents a change in state or quantity of product inventory at a
 * particular time and location.
 */
class InventoryAdjustment extends JsonSerializableType
{
    /**
     * A unique ID generated by Square for the
     * `InventoryAdjustment`.
     *
     * @var ?string $id
     */
    #[JsonProperty('id')]
    private ?string $id;

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

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

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

    /**
     * The Square-generated ID of the [Location](entity:Location) where the related
     * quantity of items is being tracked.
     *
     * @var ?string $locationId
     */
    #[JsonProperty('location_id')]
    private ?string $locationId;

    /**
     * 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 adjustment as a decimal string.
     * Can support up to 5 digits after the decimal point.
     *
     * @var ?string $quantity
     */
    #[JsonProperty('quantity')]
    private ?string $quantity;

    /**
     * The total price paid for goods associated with the
     * adjustment. Present if and only if `to_state` is `SOLD`. Always
     * non-negative.
     *
     * @var ?Money $totalPriceMoney
     */
    #[JsonProperty('total_price_money')]
    private ?Money $totalPriceMoney;

    /**
     * A client-generated RFC 3339-formatted timestamp that indicates when
     * the inventory adjustment took place. For inventory adjustment updates, 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;

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

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

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

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

    /**
     * The Square-generated ID of the [Transaction](entity:Transaction) that
     * caused the adjustment. Only relevant for payment-related state
     * transitions.
     *
     * @var ?string $transactionId
     */
    #[JsonProperty('transaction_id')]
    private ?string $transactionId;

    /**
     * The Square-generated ID of the [Refund](entity:Refund) that
     * caused the adjustment. Only relevant for refund-related state
     * transitions.
     *
     * @var ?string $refundId
     */
    #[JsonProperty('refund_id')]
    private ?string $refundId;

    /**
     * The Square-generated ID of the purchase order that caused the
     * adjustment. Only relevant for state transitions from the Square for Retail
     * app.
     *
     * @var ?string $purchaseOrderId
     */
    #[JsonProperty('purchase_order_id')]
    private ?string $purchaseOrderId;

    /**
     * The Square-generated ID of the goods receipt that caused the
     * adjustment. Only relevant for state transitions from the Square for Retail
     * app.
     *
     * @var ?string $goodsReceiptId
     */
    #[JsonProperty('goods_receipt_id')]
    private ?string $goodsReceiptId;

    /**
     * @var ?InventoryAdjustmentGroup $adjustmentGroup An adjustment group bundling the related adjustments of item variations through stock conversions in a single inventory event.
     */
    #[JsonProperty('adjustment_group')]
    private ?InventoryAdjustmentGroup $adjustmentGroup;

    /**
     * @param array{
     *   id?: ?string,
     *   referenceId?: ?string,
     *   fromState?: ?value-of<InventoryState>,
     *   toState?: ?value-of<InventoryState>,
     *   locationId?: ?string,
     *   catalogObjectId?: ?string,
     *   catalogObjectType?: ?string,
     *   quantity?: ?string,
     *   totalPriceMoney?: ?Money,
     *   occurredAt?: ?string,
     *   createdAt?: ?string,
     *   source?: ?SourceApplication,
     *   employeeId?: ?string,
     *   teamMemberId?: ?string,
     *   transactionId?: ?string,
     *   refundId?: ?string,
     *   purchaseOrderId?: ?string,
     *   goodsReceiptId?: ?string,
     *   adjustmentGroup?: ?InventoryAdjustmentGroup,
     * } $values
     */
    public function __construct(
        array $values = [],
    ) {
        $this->id = $values['id'] ?? null;
        $this->referenceId = $values['referenceId'] ?? null;
        $this->fromState = $values['fromState'] ?? null;
        $this->toState = $values['toState'] ?? null;
        $this->locationId = $values['locationId'] ?? null;
        $this->catalogObjectId = $values['catalogObjectId'] ?? null;
        $this->catalogObjectType = $values['catalogObjectType'] ?? null;
        $this->quantity = $values['quantity'] ?? null;
        $this->totalPriceMoney = $values['totalPriceMoney'] ?? 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;
        $this->transactionId = $values['transactionId'] ?? null;
        $this->refundId = $values['refundId'] ?? null;
        $this->purchaseOrderId = $values['purchaseOrderId'] ?? null;
        $this->goodsReceiptId = $values['goodsReceiptId'] ?? null;
        $this->adjustmentGroup = $values['adjustmentGroup'] ?? 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 getFromState(): ?string
    {
        return $this->fromState;
    }

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

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

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

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

    /**
     * @param ?string $value
     */
    public function setLocationId(?string $value = null): self
    {
        $this->locationId = $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 ?Money
     */
    public function getTotalPriceMoney(): ?Money
    {
        return $this->totalPriceMoney;
    }

    /**
     * @param ?Money $value
     */
    public function setTotalPriceMoney(?Money $value = null): self
    {
        $this->totalPriceMoney = $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 getTransactionId(): ?string
    {
        return $this->transactionId;
    }

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

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

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

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

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

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

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

    /**
     * @return ?InventoryAdjustmentGroup
     */
    public function getAdjustmentGroup(): ?InventoryAdjustmentGroup
    {
        return $this->adjustmentGroup;
    }

    /**
     * @param ?InventoryAdjustmentGroup $value
     */
    public function setAdjustmentGroup(?InventoryAdjustmentGroup $value = null): self
    {
        $this->adjustmentGroup = $value;
        return $this;
    }

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