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

import typing
from ...core.client_wrapper import SyncClientWrapper
from .raw_client import RawCustomAttributesClient
from ...requests.bulk_delete_order_custom_attributes_request_delete_custom_attribute import (
    BulkDeleteOrderCustomAttributesRequestDeleteCustomAttributeParams,
)
from ...core.request_options import RequestOptions
from ...types.bulk_delete_order_custom_attributes_response import BulkDeleteOrderCustomAttributesResponse
from ...requests.bulk_upsert_order_custom_attributes_request_upsert_custom_attribute import (
    BulkUpsertOrderCustomAttributesRequestUpsertCustomAttributeParams,
)
from ...types.bulk_upsert_order_custom_attributes_response import BulkUpsertOrderCustomAttributesResponse
from ...types.visibility_filter import VisibilityFilter
from ...core.pagination import SyncPager
from ...types.custom_attribute import CustomAttribute
from ...core.jsonable_encoder import jsonable_encoder
from ...types.list_order_custom_attributes_response import ListOrderCustomAttributesResponse
from ...core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from ...types.retrieve_order_custom_attribute_response import RetrieveOrderCustomAttributeResponse
from ...requests.custom_attribute import CustomAttributeParams
from ...types.upsert_order_custom_attribute_response import UpsertOrderCustomAttributeResponse
from ...types.delete_order_custom_attribute_response import DeleteOrderCustomAttributeResponse
from ...core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawCustomAttributesClient
from ...core.pagination import AsyncPager

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


class CustomAttributesClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawCustomAttributesClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawCustomAttributesClient
        """
        return self._raw_client

    def batch_delete(
        self,
        *,
        values: typing.Dict[str, BulkDeleteOrderCustomAttributesRequestDeleteCustomAttributeParams],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkDeleteOrderCustomAttributesResponse:
        """
        Deletes order [custom attributes](entity:CustomAttribute) as a bulk operation.

        Use this endpoint to delete one or more custom attributes from one or more orders.
        A custom attribute is based on a custom attribute definition in a Square seller account.  (To create a
        custom attribute definition, use the [CreateOrderCustomAttributeDefinition](api-endpoint:OrderCustomAttributes-CreateOrderCustomAttributeDefinition) endpoint.)

        This `BulkDeleteOrderCustomAttributes` endpoint accepts a map of 1 to 25 individual delete
        requests and returns a map of individual delete responses. Each delete request has a unique ID
        and provides an order ID and custom attribute. Each delete response is returned with the ID
        of the corresponding request.

        To delete a custom attribute owned by another application, the `visibility` setting
        must be `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        values : typing.Dict[str, BulkDeleteOrderCustomAttributesRequestDeleteCustomAttributeParams]
            A map of requests that correspond to individual delete operations for custom attributes.

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

        Returns
        -------
        BulkDeleteOrderCustomAttributesResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.custom_attributes.batch_delete(
            values={
                "cover-count": {
                    "key": "cover-count",
                    "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                },
                "table-number": {
                    "key": "table-number",
                    "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                },
            },
        )
        """
        response = self._raw_client.batch_delete(values=values, request_options=request_options)
        return response.data

    def batch_upsert(
        self,
        *,
        values: typing.Dict[str, BulkUpsertOrderCustomAttributesRequestUpsertCustomAttributeParams],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkUpsertOrderCustomAttributesResponse:
        """
        Creates or updates order [custom attributes](entity:CustomAttribute) as a bulk operation.

        Use this endpoint to delete one or more custom attributes from one or more orders.
        A custom attribute is based on a custom attribute definition in a Square seller account.  (To create a
        custom attribute definition, use the [CreateOrderCustomAttributeDefinition](api-endpoint:OrderCustomAttributes-CreateOrderCustomAttributeDefinition) endpoint.)

        This `BulkUpsertOrderCustomAttributes` endpoint accepts a map of 1 to 25 individual upsert
        requests and returns a map of individual upsert responses. Each upsert request has a unique ID
        and provides an order ID and custom attribute. Each upsert response is returned with the ID
        of the corresponding request.

        To create or update a custom attribute owned by another application, the `visibility` setting
        must be `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        values : typing.Dict[str, BulkUpsertOrderCustomAttributesRequestUpsertCustomAttributeParams]
            A map of requests that correspond to individual upsert operations for custom attributes.

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

        Returns
        -------
        BulkUpsertOrderCustomAttributesResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.custom_attributes.batch_upsert(
            values={
                "cover-count": {
                    "custom_attribute": {
                        "key": "cover-count",
                        "value": "6",
                        "version": 2,
                    },
                    "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                },
                "table-number": {
                    "custom_attribute": {
                        "key": "table-number",
                        "value": "11",
                        "version": 4,
                    },
                    "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                },
            },
        )
        """
        response = self._raw_client.batch_upsert(values=values, request_options=request_options)
        return response.data

    def list(
        self,
        order_id: str,
        *,
        visibility_filter: typing.Optional[VisibilityFilter] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        with_definitions: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[CustomAttribute]:
        """
        Lists the [custom attributes](entity:CustomAttribute) associated with an order.

        You can use the `with_definitions` query parameter to also retrieve custom attribute definitions
        in the same call.

        When all response pages are retrieved, the results include all custom attributes that are
        visible to the requesting application, including those that are owned by other applications
        and set to `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        visibility_filter : typing.Optional[VisibilityFilter]
            Requests that all of the custom attributes be returned, or only those that are read-only or read-write.

        cursor : typing.Optional[str]
            The cursor returned in the paged response from the previous call to this endpoint.
            Provide this cursor to retrieve the next page of results for your original request.
            For more information, see [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination).

        limit : typing.Optional[int]
            The maximum number of results to return in a single paged response. This limit is advisory.
            The response might contain more or fewer results. The minimum value is 1 and the maximum value is 100.
            The default value is 20.
            For more information, see [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination).

        with_definitions : typing.Optional[bool]
            Indicates whether to return the [custom attribute definition](entity:CustomAttributeDefinition) in the `definition` field of each
            custom attribute. Set this parameter to `true` to get the name and description of each custom attribute,
            information about the data type, or other definition details. The default value is `false`.

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

        Returns
        -------
        SyncPager[CustomAttribute]
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.orders.custom_attributes.list(
            order_id="order_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/orders/{jsonable_encoder(order_id)}/custom-attributes",
            method="GET",
            params={
                "visibility_filter": visibility_filter,
                "cursor": cursor,
                "limit": limit,
                "with_definitions": with_definitions,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListOrderCustomAttributesResponse,
                    construct_type(
                        type_=ListOrderCustomAttributesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.list(
                    order_id,
                    visibility_filter=visibility_filter,
                    cursor=_parsed_next,
                    limit=limit,
                    with_definitions=with_definitions,
                    request_options=request_options,
                )
                _items = _parsed_response.custom_attributes
                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 get(
        self,
        order_id: str,
        custom_attribute_key: str,
        *,
        version: typing.Optional[int] = None,
        with_definition: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RetrieveOrderCustomAttributeResponse:
        """
        Retrieves a [custom attribute](entity:CustomAttribute) associated with an order.

        You can use the `with_definition` query parameter to also retrieve the custom attribute definition
        in the same call.

        To retrieve a custom attribute owned by another application, the `visibility` setting must be
        `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        custom_attribute_key : str
            The key of the custom attribute to retrieve.  This key must match the key of an
            existing custom attribute definition.

        version : typing.Optional[int]
            To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, include this optional field and specify the current version of the custom attribute.

        with_definition : typing.Optional[bool]
            Indicates whether to return the [custom attribute definition](entity:CustomAttributeDefinition) in the `definition` field of each
            custom attribute. Set this parameter to `true` to get the name and description of each custom attribute,
            information about the data type, or other definition details. The default value is `false`.

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

        Returns
        -------
        RetrieveOrderCustomAttributeResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.custom_attributes.get(
            order_id="order_id",
            custom_attribute_key="custom_attribute_key",
        )
        """
        response = self._raw_client.get(
            order_id,
            custom_attribute_key,
            version=version,
            with_definition=with_definition,
            request_options=request_options,
        )
        return response.data

    def upsert(
        self,
        order_id: str,
        custom_attribute_key: str,
        *,
        custom_attribute: CustomAttributeParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpsertOrderCustomAttributeResponse:
        """
        Creates or updates a [custom attribute](entity:CustomAttribute) for an order.

        Use this endpoint to set the value of a custom attribute for a specific order.
        A custom attribute is based on a custom attribute definition in a Square seller account. (To create a
        custom attribute definition, use the [CreateOrderCustomAttributeDefinition](api-endpoint:OrderCustomAttributes-CreateOrderCustomAttributeDefinition) endpoint.)

        To create or update a custom attribute owned by another application, the `visibility` setting
        must be `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        custom_attribute_key : str
            The key of the custom attribute to create or update.  This key must match the key
            of an existing custom attribute definition.

        custom_attribute : CustomAttributeParams
            The custom attribute to create or update, with the following fields:

            - `value`. This value must conform to the `schema` specified by the definition.
            For more information, see [Value data types](https://developer.squareup.com/docs/customer-custom-attributes-api/custom-attributes#value-data-types).

            - `version`. To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, include this optional field and specify the current version of the custom attribute.

        idempotency_key : typing.Optional[str]
            A unique identifier for this request, used to ensure idempotency.
            For more information, see [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency).

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

        Returns
        -------
        UpsertOrderCustomAttributeResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.custom_attributes.upsert(
            order_id="order_id",
            custom_attribute_key="custom_attribute_key",
            custom_attribute={"key": "table-number", "value": "42", "version": 1},
        )
        """
        response = self._raw_client.upsert(
            order_id,
            custom_attribute_key,
            custom_attribute=custom_attribute,
            idempotency_key=idempotency_key,
            request_options=request_options,
        )
        return response.data

    def delete(
        self, order_id: str, custom_attribute_key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteOrderCustomAttributeResponse:
        """
        Deletes a [custom attribute](entity:CustomAttribute) associated with a customer profile.

        To delete a custom attribute owned by another application, the `visibility` setting must be
        `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        custom_attribute_key : str
            The key of the custom attribute to delete.  This key must match the key of an
            existing custom attribute definition.

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

        Returns
        -------
        DeleteOrderCustomAttributeResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.custom_attributes.delete(
            order_id="order_id",
            custom_attribute_key="custom_attribute_key",
        )
        """
        response = self._raw_client.delete(order_id, custom_attribute_key, request_options=request_options)
        return response.data


class AsyncCustomAttributesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawCustomAttributesClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawCustomAttributesClient
        """
        return self._raw_client

    async def batch_delete(
        self,
        *,
        values: typing.Dict[str, BulkDeleteOrderCustomAttributesRequestDeleteCustomAttributeParams],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkDeleteOrderCustomAttributesResponse:
        """
        Deletes order [custom attributes](entity:CustomAttribute) as a bulk operation.

        Use this endpoint to delete one or more custom attributes from one or more orders.
        A custom attribute is based on a custom attribute definition in a Square seller account.  (To create a
        custom attribute definition, use the [CreateOrderCustomAttributeDefinition](api-endpoint:OrderCustomAttributes-CreateOrderCustomAttributeDefinition) endpoint.)

        This `BulkDeleteOrderCustomAttributes` endpoint accepts a map of 1 to 25 individual delete
        requests and returns a map of individual delete responses. Each delete request has a unique ID
        and provides an order ID and custom attribute. Each delete response is returned with the ID
        of the corresponding request.

        To delete a custom attribute owned by another application, the `visibility` setting
        must be `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        values : typing.Dict[str, BulkDeleteOrderCustomAttributesRequestDeleteCustomAttributeParams]
            A map of requests that correspond to individual delete operations for custom attributes.

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

        Returns
        -------
        BulkDeleteOrderCustomAttributesResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.custom_attributes.batch_delete(
                values={
                    "cover-count": {
                        "key": "cover-count",
                        "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                    },
                    "table-number": {
                        "key": "table-number",
                        "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                    },
                },
            )


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

    async def batch_upsert(
        self,
        *,
        values: typing.Dict[str, BulkUpsertOrderCustomAttributesRequestUpsertCustomAttributeParams],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkUpsertOrderCustomAttributesResponse:
        """
        Creates or updates order [custom attributes](entity:CustomAttribute) as a bulk operation.

        Use this endpoint to delete one or more custom attributes from one or more orders.
        A custom attribute is based on a custom attribute definition in a Square seller account.  (To create a
        custom attribute definition, use the [CreateOrderCustomAttributeDefinition](api-endpoint:OrderCustomAttributes-CreateOrderCustomAttributeDefinition) endpoint.)

        This `BulkUpsertOrderCustomAttributes` endpoint accepts a map of 1 to 25 individual upsert
        requests and returns a map of individual upsert responses. Each upsert request has a unique ID
        and provides an order ID and custom attribute. Each upsert response is returned with the ID
        of the corresponding request.

        To create or update a custom attribute owned by another application, the `visibility` setting
        must be `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        values : typing.Dict[str, BulkUpsertOrderCustomAttributesRequestUpsertCustomAttributeParams]
            A map of requests that correspond to individual upsert operations for custom attributes.

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

        Returns
        -------
        BulkUpsertOrderCustomAttributesResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.custom_attributes.batch_upsert(
                values={
                    "cover-count": {
                        "custom_attribute": {
                            "key": "cover-count",
                            "value": "6",
                            "version": 2,
                        },
                        "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                    },
                    "table-number": {
                        "custom_attribute": {
                            "key": "table-number",
                            "value": "11",
                            "version": 4,
                        },
                        "order_id": "7BbXGEIWNldxAzrtGf9GPVZTwZ4F",
                    },
                },
            )


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

    async def list(
        self,
        order_id: str,
        *,
        visibility_filter: typing.Optional[VisibilityFilter] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        with_definitions: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[CustomAttribute]:
        """
        Lists the [custom attributes](entity:CustomAttribute) associated with an order.

        You can use the `with_definitions` query parameter to also retrieve custom attribute definitions
        in the same call.

        When all response pages are retrieved, the results include all custom attributes that are
        visible to the requesting application, including those that are owned by other applications
        and set to `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        visibility_filter : typing.Optional[VisibilityFilter]
            Requests that all of the custom attributes be returned, or only those that are read-only or read-write.

        cursor : typing.Optional[str]
            The cursor returned in the paged response from the previous call to this endpoint.
            Provide this cursor to retrieve the next page of results for your original request.
            For more information, see [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination).

        limit : typing.Optional[int]
            The maximum number of results to return in a single paged response. This limit is advisory.
            The response might contain more or fewer results. The minimum value is 1 and the maximum value is 100.
            The default value is 20.
            For more information, see [Pagination](https://developer.squareup.com/docs/working-with-apis/pagination).

        with_definitions : typing.Optional[bool]
            Indicates whether to return the [custom attribute definition](entity:CustomAttributeDefinition) in the `definition` field of each
            custom attribute. Set this parameter to `true` to get the name and description of each custom attribute,
            information about the data type, or other definition details. The default value is `false`.

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

        Returns
        -------
        AsyncPager[CustomAttribute]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.orders.custom_attributes.list(
                order_id="order_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/orders/{jsonable_encoder(order_id)}/custom-attributes",
            method="GET",
            params={
                "visibility_filter": visibility_filter,
                "cursor": cursor,
                "limit": limit,
                "with_definitions": with_definitions,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListOrderCustomAttributesResponse,
                    construct_type(
                        type_=ListOrderCustomAttributesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.list(
                    order_id,
                    visibility_filter=visibility_filter,
                    cursor=_parsed_next,
                    limit=limit,
                    with_definitions=with_definitions,
                    request_options=request_options,
                )
                _items = _parsed_response.custom_attributes
                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 get(
        self,
        order_id: str,
        custom_attribute_key: str,
        *,
        version: typing.Optional[int] = None,
        with_definition: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RetrieveOrderCustomAttributeResponse:
        """
        Retrieves a [custom attribute](entity:CustomAttribute) associated with an order.

        You can use the `with_definition` query parameter to also retrieve the custom attribute definition
        in the same call.

        To retrieve a custom attribute owned by another application, the `visibility` setting must be
        `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        custom_attribute_key : str
            The key of the custom attribute to retrieve.  This key must match the key of an
            existing custom attribute definition.

        version : typing.Optional[int]
            To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, include this optional field and specify the current version of the custom attribute.

        with_definition : typing.Optional[bool]
            Indicates whether to return the [custom attribute definition](entity:CustomAttributeDefinition) in the `definition` field of each
            custom attribute. Set this parameter to `true` to get the name and description of each custom attribute,
            information about the data type, or other definition details. The default value is `false`.

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

        Returns
        -------
        RetrieveOrderCustomAttributeResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.custom_attributes.get(
                order_id="order_id",
                custom_attribute_key="custom_attribute_key",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.get(
            order_id,
            custom_attribute_key,
            version=version,
            with_definition=with_definition,
            request_options=request_options,
        )
        return response.data

    async def upsert(
        self,
        order_id: str,
        custom_attribute_key: str,
        *,
        custom_attribute: CustomAttributeParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpsertOrderCustomAttributeResponse:
        """
        Creates or updates a [custom attribute](entity:CustomAttribute) for an order.

        Use this endpoint to set the value of a custom attribute for a specific order.
        A custom attribute is based on a custom attribute definition in a Square seller account. (To create a
        custom attribute definition, use the [CreateOrderCustomAttributeDefinition](api-endpoint:OrderCustomAttributes-CreateOrderCustomAttributeDefinition) endpoint.)

        To create or update a custom attribute owned by another application, the `visibility` setting
        must be `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        custom_attribute_key : str
            The key of the custom attribute to create or update.  This key must match the key
            of an existing custom attribute definition.

        custom_attribute : CustomAttributeParams
            The custom attribute to create or update, with the following fields:

            - `value`. This value must conform to the `schema` specified by the definition.
            For more information, see [Value data types](https://developer.squareup.com/docs/customer-custom-attributes-api/custom-attributes#value-data-types).

            - `version`. To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, include this optional field and specify the current version of the custom attribute.

        idempotency_key : typing.Optional[str]
            A unique identifier for this request, used to ensure idempotency.
            For more information, see [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency).

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

        Returns
        -------
        UpsertOrderCustomAttributeResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.custom_attributes.upsert(
                order_id="order_id",
                custom_attribute_key="custom_attribute_key",
                custom_attribute={"key": "table-number", "value": "42", "version": 1},
            )


        asyncio.run(main())
        """
        response = await self._raw_client.upsert(
            order_id,
            custom_attribute_key,
            custom_attribute=custom_attribute,
            idempotency_key=idempotency_key,
            request_options=request_options,
        )
        return response.data

    async def delete(
        self, order_id: str, custom_attribute_key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteOrderCustomAttributeResponse:
        """
        Deletes a [custom attribute](entity:CustomAttribute) associated with a customer profile.

        To delete a custom attribute owned by another application, the `visibility` setting must be
        `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        order_id : str
            The ID of the target [order](entity:Order).

        custom_attribute_key : str
            The key of the custom attribute to delete.  This key must match the key of an
            existing custom attribute definition.

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

        Returns
        -------
        DeleteOrderCustomAttributeResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.custom_attributes.delete(
                order_id="order_id",
                custom_attribute_key="custom_attribute_key",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.delete(order_id, custom_attribute_key, request_options=request_options)
        return response.data
