# This file was auto-generated by Fern from our API Definition.

import typing
from ..core.client_wrapper import SyncClientWrapper
from .raw_client import RawInventoryClient
from ..core.request_options import RequestOptions
from ..types.get_inventory_adjustment_response import GetInventoryAdjustmentResponse
from ..requests.inventory_change import InventoryChangeParams
from ..types.batch_change_inventory_response import BatchChangeInventoryResponse
from ..types.inventory_change_type import InventoryChangeType
from ..types.inventory_state import InventoryState
from ..types.batch_get_inventory_changes_response import BatchGetInventoryChangesResponse
from ..types.batch_get_inventory_counts_response import BatchGetInventoryCountsResponse
from ..core.pagination import SyncPager
from ..types.inventory_change import InventoryChange
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.inventory_count import InventoryCount
from ..types.get_inventory_physical_count_response import GetInventoryPhysicalCountResponse
from ..types.get_inventory_transfer_response import GetInventoryTransferResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..types.get_inventory_count_response import GetInventoryCountResponse
from ..types.get_inventory_changes_response import GetInventoryChangesResponse
from ..core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawInventoryClient
from ..core.pagination import AsyncPager

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class InventoryClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawInventoryClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawInventoryClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawInventoryClient
        """
        return self._raw_client

    def deprecated_get_adjustment(
        self, adjustment_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryAdjustmentResponse:
        """
        Deprecated version of [RetrieveInventoryAdjustment](api-endpoint:Inventory-RetrieveInventoryAdjustment) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        adjustment_id : str
            ID of the [InventoryAdjustment](entity:InventoryAdjustment) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryAdjustmentResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.deprecated_get_adjustment(
            adjustment_id="adjustment_id",
        )
        """
        response = self._raw_client.deprecated_get_adjustment(adjustment_id, request_options=request_options)
        return response.data

    def get_adjustment(
        self, adjustment_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryAdjustmentResponse:
        """
        Returns the [InventoryAdjustment](entity:InventoryAdjustment) object
        with the provided `adjustment_id`.

        Parameters
        ----------
        adjustment_id : str
            ID of the [InventoryAdjustment](entity:InventoryAdjustment) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryAdjustmentResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.get_adjustment(
            adjustment_id="adjustment_id",
        )
        """
        response = self._raw_client.get_adjustment(adjustment_id, request_options=request_options)
        return response.data

    def deprecated_batch_change(
        self,
        *,
        idempotency_key: str,
        changes: typing.Optional[typing.Sequence[InventoryChangeParams]] = OMIT,
        ignore_unchanged_counts: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchChangeInventoryResponse:
        """
        Deprecated version of [BatchChangeInventory](api-endpoint:Inventory-BatchChangeInventory) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        idempotency_key : str
            A client-supplied, universally unique identifier (UUID) for the
            request.

            See [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency) in the
            [API Development 101](https://developer.squareup.com/docs/buildbasics) section for more
            information.

        changes : typing.Optional[typing.Sequence[InventoryChangeParams]]
            The set of physical counts and inventory adjustments to be made.
            Changes are applied based on the client-supplied timestamp and may be sent
            out of order.

        ignore_unchanged_counts : typing.Optional[bool]
            Indicates whether the current physical count should be ignored if
            the quantity is unchanged since the last physical count. Default: `true`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchChangeInventoryResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.deprecated_batch_change(
            idempotency_key="8fc6a5b0-9fe8-4b46-b46b-2ef95793abbe",
            changes=[
                {
                    "type": "PHYSICAL_COUNT",
                    "physical_count": {
                        "reference_id": "1536bfbf-efed-48bf-b17d-a197141b2a92",
                        "catalog_object_id": "W62UWFY35CWMYGVWK6TWJDNI",
                        "state": "IN_STOCK",
                        "location_id": "C6W5YS5QM06F5",
                        "quantity": "53",
                        "team_member_id": "LRK57NSQ5X7PUD05",
                        "occurred_at": "2016-11-16T22:25:24.878Z",
                    },
                }
            ],
            ignore_unchanged_counts=True,
        )
        """
        response = self._raw_client.deprecated_batch_change(
            idempotency_key=idempotency_key,
            changes=changes,
            ignore_unchanged_counts=ignore_unchanged_counts,
            request_options=request_options,
        )
        return response.data

    def deprecated_batch_get_changes(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        types: typing.Optional[typing.Sequence[InventoryChangeType]] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        updated_before: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchGetInventoryChangesResponse:
        """
        Deprecated version of [BatchRetrieveInventoryChanges](api-endpoint:Inventory-BatchRetrieveInventoryChanges) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is only applicable when set. The default value is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            The filter is only applicable when set. The default value is null.

        types : typing.Optional[typing.Sequence[InventoryChangeType]]
            The filter to return results by `InventoryChangeType` values other than `TRANSFER`.
            The default value is `[PHYSICAL_COUNT, ADJUSTMENT]`.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return `ADJUSTMENT` query results by
            `InventoryState`. This filter is only applied when set.
            The default value is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        updated_before : typing.Optional[str]
            The filter to return results with their `created_at` or `calculated_at` value
            strictly before the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryChange) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchGetInventoryChangesResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.deprecated_batch_get_changes(
            catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
            location_ids=["C6W5YS5QM06F5"],
            types=["PHYSICAL_COUNT"],
            states=["IN_STOCK"],
            updated_after="2016-11-01T00:00:00.000Z",
            updated_before="2016-12-01T00:00:00.000Z",
        )
        """
        response = self._raw_client.deprecated_batch_get_changes(
            catalog_object_ids=catalog_object_ids,
            location_ids=location_ids,
            types=types,
            states=states,
            updated_after=updated_after,
            updated_before=updated_before,
            cursor=cursor,
            limit=limit,
            request_options=request_options,
        )
        return response.data

    def deprecated_batch_get_counts(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchGetInventoryCountsResponse:
        """
        Deprecated version of [BatchRetrieveInventoryCounts](api-endpoint:Inventory-BatchRetrieveInventoryCounts) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is applicable only when set.  The default is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            This filter is applicable only when set. The default is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return results by `InventoryState`. The filter is only applicable when set.
            Ignored are untracked states of `NONE`, `SOLD`, and `UNLINKED_RETURN`.
            The default is null.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryCount) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchGetInventoryCountsResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.deprecated_batch_get_counts(
            catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
            location_ids=["59TNP9SA8VGDA"],
            updated_after="2016-11-16T00:00:00.000Z",
        )
        """
        response = self._raw_client.deprecated_batch_get_counts(
            catalog_object_ids=catalog_object_ids,
            location_ids=location_ids,
            updated_after=updated_after,
            cursor=cursor,
            states=states,
            limit=limit,
            request_options=request_options,
        )
        return response.data

    def batch_create_changes(
        self,
        *,
        idempotency_key: str,
        changes: typing.Optional[typing.Sequence[InventoryChangeParams]] = OMIT,
        ignore_unchanged_counts: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchChangeInventoryResponse:
        """
        Applies adjustments and counts to the provided item quantities.

        On success: returns the current calculated counts for all objects
        referenced in the request.
        On failure: returns a list of related errors.

        Parameters
        ----------
        idempotency_key : str
            A client-supplied, universally unique identifier (UUID) for the
            request.

            See [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency) in the
            [API Development 101](https://developer.squareup.com/docs/buildbasics) section for more
            information.

        changes : typing.Optional[typing.Sequence[InventoryChangeParams]]
            The set of physical counts and inventory adjustments to be made.
            Changes are applied based on the client-supplied timestamp and may be sent
            out of order.

        ignore_unchanged_counts : typing.Optional[bool]
            Indicates whether the current physical count should be ignored if
            the quantity is unchanged since the last physical count. Default: `true`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchChangeInventoryResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.batch_create_changes(
            idempotency_key="8fc6a5b0-9fe8-4b46-b46b-2ef95793abbe",
            changes=[
                {
                    "type": "PHYSICAL_COUNT",
                    "physical_count": {
                        "reference_id": "1536bfbf-efed-48bf-b17d-a197141b2a92",
                        "catalog_object_id": "W62UWFY35CWMYGVWK6TWJDNI",
                        "state": "IN_STOCK",
                        "location_id": "C6W5YS5QM06F5",
                        "quantity": "53",
                        "team_member_id": "LRK57NSQ5X7PUD05",
                        "occurred_at": "2016-11-16T22:25:24.878Z",
                    },
                }
            ],
            ignore_unchanged_counts=True,
        )
        """
        response = self._raw_client.batch_create_changes(
            idempotency_key=idempotency_key,
            changes=changes,
            ignore_unchanged_counts=ignore_unchanged_counts,
            request_options=request_options,
        )
        return response.data

    def batch_get_changes(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        types: typing.Optional[typing.Sequence[InventoryChangeType]] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        updated_before: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[InventoryChange]:
        """
        Returns historical physical counts and adjustments based on the
        provided filter criteria.

        Results are paginated and sorted in ascending order according their
        `occurred_at` timestamp (oldest first).

        BatchRetrieveInventoryChanges is a catch-all query endpoint for queries
        that cannot be handled by other, simpler endpoints.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is only applicable when set. The default value is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            The filter is only applicable when set. The default value is null.

        types : typing.Optional[typing.Sequence[InventoryChangeType]]
            The filter to return results by `InventoryChangeType` values other than `TRANSFER`.
            The default value is `[PHYSICAL_COUNT, ADJUSTMENT]`.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return `ADJUSTMENT` query results by
            `InventoryState`. This filter is only applied when set.
            The default value is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        updated_before : typing.Optional[str]
            The filter to return results with their `created_at` or `calculated_at` value
            strictly before the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryChange) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[InventoryChange]
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.inventory.batch_get_changes(
            catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
            location_ids=["C6W5YS5QM06F5"],
            types=["PHYSICAL_COUNT"],
            states=["IN_STOCK"],
            updated_after="2016-11-01T00:00:00.000Z",
            updated_before="2016-12-01T00:00:00.000Z",
        )
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        _response = self._raw_client._client_wrapper.httpx_client.request(
            "v2/inventory/changes/batch-retrieve",
            method="POST",
            json={
                "catalog_object_ids": catalog_object_ids,
                "location_ids": location_ids,
                "types": types,
                "states": states,
                "updated_after": updated_after,
                "updated_before": updated_before,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    BatchGetInventoryChangesResponse,
                    construct_type(
                        type_=BatchGetInventoryChangesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.batch_get_changes(
                    catalog_object_ids=catalog_object_ids,
                    location_ids=location_ids,
                    types=types,
                    states=states,
                    updated_after=updated_after,
                    updated_before=updated_before,
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.changes
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def batch_get_counts(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[InventoryCount]:
        """
        Returns current counts for the provided
        [CatalogObject](entity:CatalogObject)s at the requested
        [Location](entity:Location)s.

        Results are paginated and sorted in descending order according to their
        `calculated_at` timestamp (newest first).

        When `updated_after` is specified, only counts that have changed since that
        time (based on the server timestamp for the most recent change) are
        returned. This allows clients to perform a "sync" operation, for example
        in response to receiving a Webhook notification.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is applicable only when set.  The default is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            This filter is applicable only when set. The default is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return results by `InventoryState`. The filter is only applicable when set.
            Ignored are untracked states of `NONE`, `SOLD`, and `UNLINKED_RETURN`.
            The default is null.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryCount) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[InventoryCount]
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.inventory.batch_get_counts(
            catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
            location_ids=["59TNP9SA8VGDA"],
            updated_after="2016-11-16T00:00:00.000Z",
        )
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        _response = self._raw_client._client_wrapper.httpx_client.request(
            "v2/inventory/counts/batch-retrieve",
            method="POST",
            json={
                "catalog_object_ids": catalog_object_ids,
                "location_ids": location_ids,
                "updated_after": updated_after,
                "cursor": cursor,
                "states": states,
                "limit": limit,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    BatchGetInventoryCountsResponse,
                    construct_type(
                        type_=BatchGetInventoryCountsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.batch_get_counts(
                    catalog_object_ids=catalog_object_ids,
                    location_ids=location_ids,
                    updated_after=updated_after,
                    cursor=_parsed_next,
                    states=states,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.counts
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def deprecated_get_physical_count(
        self, physical_count_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryPhysicalCountResponse:
        """
        Deprecated version of [RetrieveInventoryPhysicalCount](api-endpoint:Inventory-RetrieveInventoryPhysicalCount) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        physical_count_id : str
            ID of the
            [InventoryPhysicalCount](entity:InventoryPhysicalCount) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryPhysicalCountResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.deprecated_get_physical_count(
            physical_count_id="physical_count_id",
        )
        """
        response = self._raw_client.deprecated_get_physical_count(physical_count_id, request_options=request_options)
        return response.data

    def get_physical_count(
        self, physical_count_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryPhysicalCountResponse:
        """
        Returns the [InventoryPhysicalCount](entity:InventoryPhysicalCount)
        object with the provided `physical_count_id`.

        Parameters
        ----------
        physical_count_id : str
            ID of the
            [InventoryPhysicalCount](entity:InventoryPhysicalCount) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryPhysicalCountResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.get_physical_count(
            physical_count_id="physical_count_id",
        )
        """
        response = self._raw_client.get_physical_count(physical_count_id, request_options=request_options)
        return response.data

    def get_transfer(
        self, transfer_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryTransferResponse:
        """
        Returns the [InventoryTransfer](entity:InventoryTransfer) object
        with the provided `transfer_id`.

        Parameters
        ----------
        transfer_id : str
            ID of the [InventoryTransfer](entity:InventoryTransfer) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryTransferResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.inventory.get_transfer(
            transfer_id="transfer_id",
        )
        """
        response = self._raw_client.get_transfer(transfer_id, request_options=request_options)
        return response.data

    def get(
        self,
        catalog_object_id: str,
        *,
        location_ids: typing.Optional[str] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[InventoryCount]:
        """
        Retrieves the current calculated stock count for a given
        [CatalogObject](entity:CatalogObject) at a given set of
        [Location](entity:Location)s. Responses are paginated and unsorted.
        For more sophisticated queries, use a batch endpoint.

        Parameters
        ----------
        catalog_object_id : str
            ID of the [CatalogObject](entity:CatalogObject) to retrieve.

        location_ids : typing.Optional[str]
            The [Location](entity:Location) IDs to look up as a comma-separated
            list. An empty list queries all locations.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[InventoryCount]
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.inventory.get(
            catalog_object_id="catalog_object_id",
        )
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        _response = self._raw_client._client_wrapper.httpx_client.request(
            f"v2/inventory/{jsonable_encoder(catalog_object_id)}",
            method="GET",
            params={
                "location_ids": location_ids,
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    GetInventoryCountResponse,
                    construct_type(
                        type_=GetInventoryCountResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.get(
                    catalog_object_id,
                    location_ids=location_ids,
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.counts
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def changes(
        self,
        catalog_object_id: str,
        *,
        location_ids: typing.Optional[str] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[InventoryChange]:
        """
        Returns a set of physical counts and inventory adjustments for the
        provided [CatalogObject](entity:CatalogObject) at the requested
        [Location](entity:Location)s.

        You can achieve the same result by calling [BatchRetrieveInventoryChanges](api-endpoint:Inventory-BatchRetrieveInventoryChanges)
        and having the `catalog_object_ids` list contain a single element of the `CatalogObject` ID.

        Results are paginated and sorted in descending order according to their
        `occurred_at` timestamp (newest first).

        There are no limits on how far back the caller can page. This endpoint can be
        used to display recent changes for a specific item. For more
        sophisticated queries, use a batch endpoint.

        Parameters
        ----------
        catalog_object_id : str
            ID of the [CatalogObject](entity:CatalogObject) to retrieve.

        location_ids : typing.Optional[str]
            The [Location](entity:Location) IDs to look up as a comma-separated
            list. An empty list queries all locations.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[InventoryChange]
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.inventory.changes(
            catalog_object_id="catalog_object_id",
        )
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        _response = self._raw_client._client_wrapper.httpx_client.request(
            f"v2/inventory/{jsonable_encoder(catalog_object_id)}/changes",
            method="GET",
            params={
                "location_ids": location_ids,
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    GetInventoryChangesResponse,
                    construct_type(
                        type_=GetInventoryChangesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.changes(
                    catalog_object_id,
                    location_ids=location_ids,
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.changes
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncInventoryClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawInventoryClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawInventoryClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawInventoryClient
        """
        return self._raw_client

    async def deprecated_get_adjustment(
        self, adjustment_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryAdjustmentResponse:
        """
        Deprecated version of [RetrieveInventoryAdjustment](api-endpoint:Inventory-RetrieveInventoryAdjustment) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        adjustment_id : str
            ID of the [InventoryAdjustment](entity:InventoryAdjustment) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryAdjustmentResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.deprecated_get_adjustment(
                adjustment_id="adjustment_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.deprecated_get_adjustment(adjustment_id, request_options=request_options)
        return response.data

    async def get_adjustment(
        self, adjustment_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryAdjustmentResponse:
        """
        Returns the [InventoryAdjustment](entity:InventoryAdjustment) object
        with the provided `adjustment_id`.

        Parameters
        ----------
        adjustment_id : str
            ID of the [InventoryAdjustment](entity:InventoryAdjustment) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryAdjustmentResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.get_adjustment(
                adjustment_id="adjustment_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.get_adjustment(adjustment_id, request_options=request_options)
        return response.data

    async def deprecated_batch_change(
        self,
        *,
        idempotency_key: str,
        changes: typing.Optional[typing.Sequence[InventoryChangeParams]] = OMIT,
        ignore_unchanged_counts: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchChangeInventoryResponse:
        """
        Deprecated version of [BatchChangeInventory](api-endpoint:Inventory-BatchChangeInventory) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        idempotency_key : str
            A client-supplied, universally unique identifier (UUID) for the
            request.

            See [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency) in the
            [API Development 101](https://developer.squareup.com/docs/buildbasics) section for more
            information.

        changes : typing.Optional[typing.Sequence[InventoryChangeParams]]
            The set of physical counts and inventory adjustments to be made.
            Changes are applied based on the client-supplied timestamp and may be sent
            out of order.

        ignore_unchanged_counts : typing.Optional[bool]
            Indicates whether the current physical count should be ignored if
            the quantity is unchanged since the last physical count. Default: `true`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchChangeInventoryResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.deprecated_batch_change(
                idempotency_key="8fc6a5b0-9fe8-4b46-b46b-2ef95793abbe",
                changes=[
                    {
                        "type": "PHYSICAL_COUNT",
                        "physical_count": {
                            "reference_id": "1536bfbf-efed-48bf-b17d-a197141b2a92",
                            "catalog_object_id": "W62UWFY35CWMYGVWK6TWJDNI",
                            "state": "IN_STOCK",
                            "location_id": "C6W5YS5QM06F5",
                            "quantity": "53",
                            "team_member_id": "LRK57NSQ5X7PUD05",
                            "occurred_at": "2016-11-16T22:25:24.878Z",
                        },
                    }
                ],
                ignore_unchanged_counts=True,
            )


        asyncio.run(main())
        """
        response = await self._raw_client.deprecated_batch_change(
            idempotency_key=idempotency_key,
            changes=changes,
            ignore_unchanged_counts=ignore_unchanged_counts,
            request_options=request_options,
        )
        return response.data

    async def deprecated_batch_get_changes(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        types: typing.Optional[typing.Sequence[InventoryChangeType]] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        updated_before: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchGetInventoryChangesResponse:
        """
        Deprecated version of [BatchRetrieveInventoryChanges](api-endpoint:Inventory-BatchRetrieveInventoryChanges) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is only applicable when set. The default value is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            The filter is only applicable when set. The default value is null.

        types : typing.Optional[typing.Sequence[InventoryChangeType]]
            The filter to return results by `InventoryChangeType` values other than `TRANSFER`.
            The default value is `[PHYSICAL_COUNT, ADJUSTMENT]`.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return `ADJUSTMENT` query results by
            `InventoryState`. This filter is only applied when set.
            The default value is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        updated_before : typing.Optional[str]
            The filter to return results with their `created_at` or `calculated_at` value
            strictly before the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryChange) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchGetInventoryChangesResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.deprecated_batch_get_changes(
                catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
                location_ids=["C6W5YS5QM06F5"],
                types=["PHYSICAL_COUNT"],
                states=["IN_STOCK"],
                updated_after="2016-11-01T00:00:00.000Z",
                updated_before="2016-12-01T00:00:00.000Z",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.deprecated_batch_get_changes(
            catalog_object_ids=catalog_object_ids,
            location_ids=location_ids,
            types=types,
            states=states,
            updated_after=updated_after,
            updated_before=updated_before,
            cursor=cursor,
            limit=limit,
            request_options=request_options,
        )
        return response.data

    async def deprecated_batch_get_counts(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchGetInventoryCountsResponse:
        """
        Deprecated version of [BatchRetrieveInventoryCounts](api-endpoint:Inventory-BatchRetrieveInventoryCounts) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is applicable only when set.  The default is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            This filter is applicable only when set. The default is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return results by `InventoryState`. The filter is only applicable when set.
            Ignored are untracked states of `NONE`, `SOLD`, and `UNLINKED_RETURN`.
            The default is null.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryCount) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchGetInventoryCountsResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.deprecated_batch_get_counts(
                catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
                location_ids=["59TNP9SA8VGDA"],
                updated_after="2016-11-16T00:00:00.000Z",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.deprecated_batch_get_counts(
            catalog_object_ids=catalog_object_ids,
            location_ids=location_ids,
            updated_after=updated_after,
            cursor=cursor,
            states=states,
            limit=limit,
            request_options=request_options,
        )
        return response.data

    async def batch_create_changes(
        self,
        *,
        idempotency_key: str,
        changes: typing.Optional[typing.Sequence[InventoryChangeParams]] = OMIT,
        ignore_unchanged_counts: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BatchChangeInventoryResponse:
        """
        Applies adjustments and counts to the provided item quantities.

        On success: returns the current calculated counts for all objects
        referenced in the request.
        On failure: returns a list of related errors.

        Parameters
        ----------
        idempotency_key : str
            A client-supplied, universally unique identifier (UUID) for the
            request.

            See [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency) in the
            [API Development 101](https://developer.squareup.com/docs/buildbasics) section for more
            information.

        changes : typing.Optional[typing.Sequence[InventoryChangeParams]]
            The set of physical counts and inventory adjustments to be made.
            Changes are applied based on the client-supplied timestamp and may be sent
            out of order.

        ignore_unchanged_counts : typing.Optional[bool]
            Indicates whether the current physical count should be ignored if
            the quantity is unchanged since the last physical count. Default: `true`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BatchChangeInventoryResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.batch_create_changes(
                idempotency_key="8fc6a5b0-9fe8-4b46-b46b-2ef95793abbe",
                changes=[
                    {
                        "type": "PHYSICAL_COUNT",
                        "physical_count": {
                            "reference_id": "1536bfbf-efed-48bf-b17d-a197141b2a92",
                            "catalog_object_id": "W62UWFY35CWMYGVWK6TWJDNI",
                            "state": "IN_STOCK",
                            "location_id": "C6W5YS5QM06F5",
                            "quantity": "53",
                            "team_member_id": "LRK57NSQ5X7PUD05",
                            "occurred_at": "2016-11-16T22:25:24.878Z",
                        },
                    }
                ],
                ignore_unchanged_counts=True,
            )


        asyncio.run(main())
        """
        response = await self._raw_client.batch_create_changes(
            idempotency_key=idempotency_key,
            changes=changes,
            ignore_unchanged_counts=ignore_unchanged_counts,
            request_options=request_options,
        )
        return response.data

    async def batch_get_changes(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        types: typing.Optional[typing.Sequence[InventoryChangeType]] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        updated_before: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[InventoryChange]:
        """
        Returns historical physical counts and adjustments based on the
        provided filter criteria.

        Results are paginated and sorted in ascending order according their
        `occurred_at` timestamp (oldest first).

        BatchRetrieveInventoryChanges is a catch-all query endpoint for queries
        that cannot be handled by other, simpler endpoints.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is only applicable when set. The default value is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            The filter is only applicable when set. The default value is null.

        types : typing.Optional[typing.Sequence[InventoryChangeType]]
            The filter to return results by `InventoryChangeType` values other than `TRANSFER`.
            The default value is `[PHYSICAL_COUNT, ADJUSTMENT]`.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return `ADJUSTMENT` query results by
            `InventoryState`. This filter is only applied when set.
            The default value is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        updated_before : typing.Optional[str]
            The filter to return results with their `created_at` or `calculated_at` value
            strictly before the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryChange) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[InventoryChange]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.inventory.batch_get_changes(
                catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
                location_ids=["C6W5YS5QM06F5"],
                types=["PHYSICAL_COUNT"],
                states=["IN_STOCK"],
                updated_after="2016-11-01T00:00:00.000Z",
                updated_before="2016-12-01T00:00:00.000Z",
            )
            async for item in response:
                yield item
            # alternatively, you can paginate page-by-page
            async for page in response.iter_pages():
                yield page


        asyncio.run(main())
        """
        _response = await self._raw_client._client_wrapper.httpx_client.request(
            "v2/inventory/changes/batch-retrieve",
            method="POST",
            json={
                "catalog_object_ids": catalog_object_ids,
                "location_ids": location_ids,
                "types": types,
                "states": states,
                "updated_after": updated_after,
                "updated_before": updated_before,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    BatchGetInventoryChangesResponse,
                    construct_type(
                        type_=BatchGetInventoryChangesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.batch_get_changes(
                    catalog_object_ids=catalog_object_ids,
                    location_ids=location_ids,
                    types=types,
                    states=states,
                    updated_after=updated_after,
                    updated_before=updated_before,
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.changes
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def batch_get_counts(
        self,
        *,
        catalog_object_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        location_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        updated_after: typing.Optional[str] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        states: typing.Optional[typing.Sequence[InventoryState]] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[InventoryCount]:
        """
        Returns current counts for the provided
        [CatalogObject](entity:CatalogObject)s at the requested
        [Location](entity:Location)s.

        Results are paginated and sorted in descending order according to their
        `calculated_at` timestamp (newest first).

        When `updated_after` is specified, only counts that have changed since that
        time (based on the server timestamp for the most recent change) are
        returned. This allows clients to perform a "sync" operation, for example
        in response to receiving a Webhook notification.

        Parameters
        ----------
        catalog_object_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `CatalogObject` ID.
            The filter is applicable only when set.  The default is null.

        location_ids : typing.Optional[typing.Sequence[str]]
            The filter to return results by `Location` ID.
            This filter is applicable only when set. The default is null.

        updated_after : typing.Optional[str]
            The filter to return results with their `calculated_at` value
            after the given time as specified in an RFC 3339 timestamp.
            The default value is the UNIX epoch of (`1970-01-01T00:00:00Z`).

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        states : typing.Optional[typing.Sequence[InventoryState]]
            The filter to return results by `InventoryState`. The filter is only applicable when set.
            Ignored are untracked states of `NONE`, `SOLD`, and `UNLINKED_RETURN`.
            The default is null.

        limit : typing.Optional[int]
            The number of [records](entity:InventoryCount) to return.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[InventoryCount]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.inventory.batch_get_counts(
                catalog_object_ids=["W62UWFY35CWMYGVWK6TWJDNI"],
                location_ids=["59TNP9SA8VGDA"],
                updated_after="2016-11-16T00:00:00.000Z",
            )
            async for item in response:
                yield item
            # alternatively, you can paginate page-by-page
            async for page in response.iter_pages():
                yield page


        asyncio.run(main())
        """
        _response = await self._raw_client._client_wrapper.httpx_client.request(
            "v2/inventory/counts/batch-retrieve",
            method="POST",
            json={
                "catalog_object_ids": catalog_object_ids,
                "location_ids": location_ids,
                "updated_after": updated_after,
                "cursor": cursor,
                "states": states,
                "limit": limit,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    BatchGetInventoryCountsResponse,
                    construct_type(
                        type_=BatchGetInventoryCountsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.batch_get_counts(
                    catalog_object_ids=catalog_object_ids,
                    location_ids=location_ids,
                    updated_after=updated_after,
                    cursor=_parsed_next,
                    states=states,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.counts
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def deprecated_get_physical_count(
        self, physical_count_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryPhysicalCountResponse:
        """
        Deprecated version of [RetrieveInventoryPhysicalCount](api-endpoint:Inventory-RetrieveInventoryPhysicalCount) after the endpoint URL
        is updated to conform to the standard convention.

        Parameters
        ----------
        physical_count_id : str
            ID of the
            [InventoryPhysicalCount](entity:InventoryPhysicalCount) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryPhysicalCountResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.deprecated_get_physical_count(
                physical_count_id="physical_count_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.deprecated_get_physical_count(
            physical_count_id, request_options=request_options
        )
        return response.data

    async def get_physical_count(
        self, physical_count_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryPhysicalCountResponse:
        """
        Returns the [InventoryPhysicalCount](entity:InventoryPhysicalCount)
        object with the provided `physical_count_id`.

        Parameters
        ----------
        physical_count_id : str
            ID of the
            [InventoryPhysicalCount](entity:InventoryPhysicalCount) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryPhysicalCountResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.get_physical_count(
                physical_count_id="physical_count_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.get_physical_count(physical_count_id, request_options=request_options)
        return response.data

    async def get_transfer(
        self, transfer_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetInventoryTransferResponse:
        """
        Returns the [InventoryTransfer](entity:InventoryTransfer) object
        with the provided `transfer_id`.

        Parameters
        ----------
        transfer_id : str
            ID of the [InventoryTransfer](entity:InventoryTransfer) to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetInventoryTransferResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.inventory.get_transfer(
                transfer_id="transfer_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.get_transfer(transfer_id, request_options=request_options)
        return response.data

    async def get(
        self,
        catalog_object_id: str,
        *,
        location_ids: typing.Optional[str] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[InventoryCount]:
        """
        Retrieves the current calculated stock count for a given
        [CatalogObject](entity:CatalogObject) at a given set of
        [Location](entity:Location)s. Responses are paginated and unsorted.
        For more sophisticated queries, use a batch endpoint.

        Parameters
        ----------
        catalog_object_id : str
            ID of the [CatalogObject](entity:CatalogObject) to retrieve.

        location_ids : typing.Optional[str]
            The [Location](entity:Location) IDs to look up as a comma-separated
            list. An empty list queries all locations.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[InventoryCount]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.inventory.get(
                catalog_object_id="catalog_object_id",
            )
            async for item in response:
                yield item
            # alternatively, you can paginate page-by-page
            async for page in response.iter_pages():
                yield page


        asyncio.run(main())
        """
        _response = await self._raw_client._client_wrapper.httpx_client.request(
            f"v2/inventory/{jsonable_encoder(catalog_object_id)}",
            method="GET",
            params={
                "location_ids": location_ids,
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    GetInventoryCountResponse,
                    construct_type(
                        type_=GetInventoryCountResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.get(
                    catalog_object_id,
                    location_ids=location_ids,
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.counts
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def changes(
        self,
        catalog_object_id: str,
        *,
        location_ids: typing.Optional[str] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[InventoryChange]:
        """
        Returns a set of physical counts and inventory adjustments for the
        provided [CatalogObject](entity:CatalogObject) at the requested
        [Location](entity:Location)s.

        You can achieve the same result by calling [BatchRetrieveInventoryChanges](api-endpoint:Inventory-BatchRetrieveInventoryChanges)
        and having the `catalog_object_ids` list contain a single element of the `CatalogObject` ID.

        Results are paginated and sorted in descending order according to their
        `occurred_at` timestamp (newest first).

        There are no limits on how far back the caller can page. This endpoint can be
        used to display recent changes for a specific item. For more
        sophisticated queries, use a batch endpoint.

        Parameters
        ----------
        catalog_object_id : str
            ID of the [CatalogObject](entity:CatalogObject) to retrieve.

        location_ids : typing.Optional[str]
            The [Location](entity:Location) IDs to look up as a comma-separated
            list. An empty list queries all locations.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for the original query.

            See the [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination) guide for more information.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[InventoryChange]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.inventory.changes(
                catalog_object_id="catalog_object_id",
            )
            async for item in response:
                yield item
            # alternatively, you can paginate page-by-page
            async for page in response.iter_pages():
                yield page


        asyncio.run(main())
        """
        _response = await self._raw_client._client_wrapper.httpx_client.request(
            f"v2/inventory/{jsonable_encoder(catalog_object_id)}/changes",
            method="GET",
            params={
                "location_ids": location_ids,
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    GetInventoryChangesResponse,
                    construct_type(
                        type_=GetInventoryChangesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.changes(
                    catalog_object_id,
                    location_ids=location_ids,
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.changes
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
