"""API Wrapper Tools for Xero

DO NOT EDIT THIS MODULE DIRECTLY.

THIS MODULE WAS AUTO-GENERATED BY TRANSPILING THE API WRAPPER TOOL JSON DEFINITIONS
IN THE ../wrapper_tools DIRECTORY INTO PYTHON CODE. ANY CHANGES TO THIS MODULE WILL
BE OVERWRITTEN BY THE TRANSPILER.
"""

import asyncio
from typing import Annotated, Any

import httpx
from arcade_tdk import ToolContext, tool
from arcade_tdk.auth import OAuth2

# Retry configuration
INITIAL_RETRY_DELAY = 0.5  # seconds

HTTP_CLIENT = httpx.AsyncClient(
    timeout=httpx.Timeout(60.0, connect=10.0),
    limits=httpx.Limits(max_keepalive_connections=20, max_connections=100),
    transport=httpx.AsyncHTTPTransport(retries=3),
    http2=True,
    follow_redirects=True,
)


def remove_none_values(data: dict[str, Any]) -> dict[str, Any]:
    return {k: v for k, v in data.items() if v is not None}


async def make_request(
    url: str,
    method: str,
    params: dict[str, Any] | None = None,
    headers: dict[str, Any] | None = None,
    data: dict[str, Any] | None = None,
    max_retries: int = 3,
) -> httpx.Response:
    """Make an HTTP request with retry logic for 5xx server errors."""
    for attempt in range(max_retries):
        try:
            response = await HTTP_CLIENT.request(
                url=url,
                method=method,
                params=params,
                headers=headers,
                data=data,
            )
            response.raise_for_status()
        except httpx.HTTPStatusError as e:
            # Only retry on 5xx server errors
            if e.response.status_code >= 500 and attempt < max_retries - 1:
                # Exponential backoff: 0.5s, 1s, 2s
                await asyncio.sleep(INITIAL_RETRY_DELAY * (2**attempt))
                continue
            # Re-raise for 4xx errors or if max retries reached
            raise
        except httpx.RequestError:
            # Don't retry request errors (network issues are handled by transport)
            raise
        else:
            return response

    # This should never be reached, but satisfies type checker
    raise httpx.RequestError("Max retries exceeded")  # noqa: TRY003


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_full_chart_of_accounts(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str, "Unique identifier for the Xero tenant to retrieve its accounts."
    ],
    filter_by_attribute: Annotated[
        str | None, "Filter accounts by specific attributes or conditions using string syntax."
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specify a field to order the returned accounts (e.g., 'Name' or 'AccountType').",
    ] = None,
    only_modified_since_timestamp: Annotated[
        str | None,
        "Specify a timestamp to return only records created or modified since that time. The timestamp should be in ISO 8601 format.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAccounts'."]:
    """Retrieves the full chart of accounts from Xero.

    Use this tool to obtain the complete chart of accounts from Xero, which includes all accounting categories and their details. It is useful for analyzing financial structures within the Xero platform."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Accounts",
        method="GET",
        params=remove_none_values({"where": filter_by_attribute, "order": order_by_element}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "If-Modified-Since": only_modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_account_details(
    context: ToolContext,
    account_id: Annotated[
        str, "Unique identifier for the Account object to retrieve specific account details."
    ],
    xero_tenant_identifier: Annotated[
        str, "Xero identifier for the tenant to retrieve the account details from."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAccount'."]:
    """Retrieve chart of accounts using a unique account ID.

    Use this tool to fetch details of a specific account from the chart of accounts by providing a unique account ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Accounts/{AccountID}".format(AccountID=account_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.settings"]))
async def delete_account(
    context: ToolContext,
    account_id: Annotated[str, "The unique identifier for the Account object to be deleted."],
    xero_tenant_identifier: Annotated[
        str, "Xero identifier for the Tenant. Required to specify which tenant's account to delete."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteAccount'."]:
    """Delete a chart of accounts in Xero.

    Use this tool to delete a specified chart of accounts by providing the AccountID in Xero. This tool should be called when an account needs to be permanently removed."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Accounts/{AccountID}".format(AccountID=account_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_account_attachments(
    context: ToolContext,
    account_id: Annotated[
        str, "Unique identifier for the account object to retrieve attachments from."
    ],
    tenant_identifier: Annotated[
        str, "Xero identifier for the Tenant, used to specify which tenant's data to access."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAccountAttachments'."]:
    """Retrieve attachments for a specified account.

    This tool is used to get attachments associated with a specific account by providing the account's unique ID. Useful for accessing documents or files linked to financial accounts in the Xero platform."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Accounts/{AccountID}/Attachments".format(  # noqa: UP032
            AccountID=account_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_account_attachment(
    context: ToolContext,
    account_unique_identifier: Annotated[
        str, "Unique identifier for the Account object to retrieve the attachment from."
    ],
    attachment_id: Annotated[
        str,
        "Unique identifier for the attachment you want to retrieve from an account. This ID is necessary to specify the exact attachment you need.",  # noqa: E501
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Required to specify which tenant's account attachment you want to retrieve.",  # noqa: E501
    ],
    mime_type_of_attachment: Annotated[
        str, "The MIME type of the attachment file, such as image/jpg or application/pdf."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAccountAttachmentById'."]:
    """Retrieve a specific account attachment by ID.

    Use this tool to retrieve an attachment from a specific account by providing the unique attachment ID. It is useful when you need to access detailed information or content of an attachment associated with a particular account in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Accounts/{AccountID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            AccountID=account_unique_identifier, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": mime_type_of_attachment,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_account_attachment_by_filename(
    context: ToolContext,
    account_id: Annotated[str, "Unique identifier for the Account object in Xero."],
    attachment_file_name: Annotated[
        str, "The name of the attachment to retrieve for a specific account."
    ],
    tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the Tenant. Required to access the specific tenant's attachments.",  # noqa: E501
    ],
    mime_type_of_attachment: Annotated[
        str,
        "The MIME type of the attachment file to retrieve, such as image/jpg or application/pdf.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAccountAttachmentByFileName'."]:
    """Retrieve an attachment for a specific account by filename.

    This tool retrieves an attachment file from a specific account in Xero using the filename. It should be called when a user needs to access a specific account's attachment by providing the account ID and filename."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Accounts/{AccountID}/Attachments/{FileName}".format(  # noqa: UP032
            AccountID=account_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "contentType": mime_type_of_attachment,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_batch_payments(
    context: ToolContext,
    tenant_identifier: Annotated[
        str, "Xero identifier for the Tenant required to access its specific batch payment data."
    ],
    filter_by_element: Annotated[
        str | None, "Apply a filter to the batch payments using any specified element."
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specify the element to sort the batch payments by. The value should be a string representing the element.",  # noqa: E501
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Timestamp to filter records modified or created since then. Format: ISO 8601 date and time.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBatchPayments'."]:
    """Retrieve batch payments for invoices.

    Use this tool to retrieve information about one or many batch payments associated with invoices. Useful for accessing payment details and histories."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BatchPayments",
        method="GET",
        params=remove_none_values({"where": filter_by_element, "order": order_by_element}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_batch_payment_details(
    context: ToolContext,
    batch_payment_id: Annotated[
        str, "Unique identifier for the batch payment to retrieve details."
    ],
    xero_tenant_id: Annotated[
        str,
        "The unique Xero identifier for the tenant, necessary for accessing tenant-specific data.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBatchPayment'."]:
    """Retrieve details of a specific batch payment by ID.

    Use this tool to get information about a specific batch payment by providing its unique ID."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BatchPayments/{BatchPaymentID}".format(  # noqa: UP032
            BatchPaymentID=batch_payment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_batch_payment_history(
    context: ToolContext,
    batch_payment_id: Annotated[
        str, "Unique identifier for the batch payment to retrieve its history."
    ],
    xero_tenant_id: Annotated[
        str, "The unique identifier for the Xero tenant. Required to access specific tenant data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBatchPaymentHistory'."]:
    """Retrieve the history of a specific batch payment.

    Use this tool to access detailed history for a specific batch payment in Xero. Call this tool when needing to understand past actions, updates, or changes made to a batch payment."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BatchPayments/{BatchPaymentID}/History".format(  # noqa: UP032
            BatchPaymentID=batch_payment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_batch_payment_history_record(
    context: ToolContext,
    batch_payment_id: Annotated[str, "Unique identifier for the specific batch payment in Xero."],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for Tenant. This is required to specify which tenant's batch payment history is being recorded.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None, "A unique string to prevent duplicate processing. Maximum 128 characters."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createBatchPaymentHistoryRecord'."]:
    """Creates a history record for a batch payment.

    This tool is used to create a historical record for a specified batch payment in Xero. Call this tool when you want to log information or updates about a batch payment's history."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BatchPayments/{BatchPaymentID}/History".format(  # noqa: UP032
            BatchPaymentID=batch_payment_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_bank_transactions(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str, "Xero identifier for the Tenant, required to specify which account to access."
    ],
    filter_by_element: Annotated[
        str | None,
        "Specify criteria to filter transactions by any element. Use valid filter expressions based on transaction fields.",  # noqa: E501
    ] = None,
    order_transactions_by: Annotated[
        str | None,
        "Specify the element by which to order the transactions, such as date or amount.",
    ] = None,
    transaction_page_number: Annotated[
        int | None, "Specifies which page of up to 100 bank transactions to retrieve."
    ] = None,
    use_four_decimal_places: Annotated[
        int | None, "Indicate if unit amounts should use four decimal places (e.g., 4)."
    ] = None,
    records_per_page: Annotated[
        int | None,
        "Specify the number of records to retrieve per page. This controls the pagination size.",
    ] = None,
    modified_since_timestamp: Annotated[
        str | None, "Return records created or modified since this UTC timestamp (ISO 8601 format)."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransactions'."]:
    """Retrieve spent or received money transactions from Xero.

    Use this tool to get a list of transactions where money was spent or received. This is useful for financial tracking and reporting."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransactions",
        method="GET",
        params=remove_none_values({
            "where": filter_by_element,
            "order": order_transactions_by,
            "page": transaction_page_number,
            "unitdp": use_four_decimal_places,
            "pageSize": records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_bank_transaction(
    context: ToolContext,
    bank_transaction_id: Annotated[
        str, "Unique identifier for a specific bank transaction in Xero."
    ],
    xero_tenant_id: Annotated[
        str,
        "The Xero identifier for the tenant (organization). Required to access the specific tenant's data.",  # noqa: E501
    ],
    use_four_decimal_places: Annotated[
        int | None, "Option to use four decimal places for unit amounts. Specify '4' to enable."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransaction'."]:
    """Retrieve bank transaction details by ID.

    Use this tool to get details of a specific spent or received bank transaction by providing its unique ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransactions/{BankTransactionID}".format(  # noqa: UP032
            BankTransactionID=bank_transaction_id
        ),
        method="GET",
        params=remove_none_values({"unitdp": use_four_decimal_places}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_bank_transaction_attachments(
    context: ToolContext,
    bank_transaction_id: Annotated[
        str,
        "Xero generated unique identifier for a bank transaction, used to retrieve corresponding attachments.",  # noqa: E501
    ],
    xero_tenant_id: Annotated[
        str, "The unique identifier for a Xero tenant, required to access specific tenant data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransactionAttachments'."]:
    """Retrieve attachments from a specific bank transaction.

    Use this tool to obtain any attachments linked to a specific bank transaction. It accesses the attachments related to a given transaction ID within the Xero platform."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransactions/{BankTransactionID}/Attachments".format(  # noqa: UP032
            BankTransactionID=bank_transaction_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_bank_transaction_attachment(
    context: ToolContext,
    bank_transaction_id: Annotated[str, "Xero generated unique identifier for a bank transaction."],
    attachment_id: Annotated[str, "Unique identifier for the Attachment object."],
    xero_tenant_identifier: Annotated[
        str,
        "Xero unique identifier for the Tenant. This is required to specify which organization data is to be accessed.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str,
        "The mime type of the attachment file to retrieve, such as image/jpeg or application/pdf.",
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getBankTransactionAttachmentById'."
]:
    """Retrieve a specific attachment from a bank transaction.

    Use this tool to obtain specific attachments from a bank transaction by providing the unique BankTransaction ID and Attachment ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransactions/{BankTransactionID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            BankTransactionID=bank_transaction_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_bank_transaction_attachment(
    context: ToolContext,
    bank_transaction_id: Annotated[
        str,
        "Xero generated unique identifier for a bank transaction. Required to retrieve the correct attachment.",  # noqa: E501
    ],
    attachment_filename: Annotated[
        str, "Name of the attachment to retrieve from the bank transaction."
    ],
    xero_tenant_identifier: Annotated[
        str, "The unique identifier for the Xero tenant associated with the bank transaction."
    ],
    attachment_mime_type: Annotated[
        str,
        "The MIME type of the attachment file to retrieve, such as image/jpg or application/pdf.",
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getBankTransactionAttachmentByFileName'."
]:
    """Retrieve an attachment from a bank transaction by filename.

    Use this tool to get a specific attachment from a bank transaction using the filename. Ideal for cases where attachments need to be reviewed or downloaded based on their association with bank transactions."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransactions/{BankTransactionID}/Attachments/{FileName}".format(  # noqa: UP032
            BankTransactionID=bank_transaction_id, FileName=attachment_filename
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_bank_transaction_history(
    context: ToolContext,
    bank_transaction_id: Annotated[
        str,
        "The unique identifier for a bank transaction generated by Xero. Use this ID to retrieve specific transaction history.",  # noqa: E501
    ],
    tenant_identifier: Annotated[
        str, "Xero unique identifier for the tenant. Required to access tenant-specific data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransactionsHistory'."]:
    """Retrieve history of a specific bank transaction by ID.

    This tool fetches the historical details of a particular bank transaction using its unique ID. It should be called when users need to view past records or changes related to a specific transaction."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransactions/{BankTransactionID}/History".format(  # noqa: UP032
            BankTransactionID=bank_transaction_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_bank_transaction_history(
    context: ToolContext,
    bank_transaction_id: Annotated[
        str, "Xero-generated unique identifier for the bank transaction to create a history record."
    ],
    tenant_id: Annotated[
        str,
        "Xero identifier for the tenant. This is required to specify which Xero account the transaction history will be associated with.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None, "A unique key to prevent duplicate processing. Maximum 128 characters."
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'createBankTransactionHistoryRecord'."
]:
    """Creates a record in the bank transaction history.

    Use this tool to create a history record for a specific bank transaction in Xero. It's useful for logging changes or updates to bank transactions."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransactions/{BankTransactionID}/History".format(  # noqa: UP032
            BankTransactionID=bank_transaction_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_bank_transfers(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str, "A unique string identifier for the Xero tenant to retrieve bank transfers from."
    ],
    filter_bank_transfers: Annotated[
        str | None,
        "String to filter bank transfer records by a specific element, such as status or date range.",  # noqa: E501
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specify the field to order the bank transfer records by. Use the field names available in the Xero bank transfer dataset.",  # noqa: E501
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Filter records to only include those created or modified since this timestamp. Use ISO 8601 format (e.g., '2023-10-01T00:00:00Z').",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransfers'."]:
    """Retrieve all bank transfers from Xero.

    Use this tool to access all bank transfer records from Xero. It helps in obtaining comprehensive transfer data for financial review or auditing purposes."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransfers",
        method="GET",
        params=remove_none_values({"where": filter_bank_transfers, "order": order_by_element}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_bank_transfer(
    context: ToolContext,
    bank_transfer_id: Annotated[
        str, "The unique identifier for a bank transfer generated by Xero."
    ],
    tenant_id: Annotated[
        str,
        "Xero identifier for the tenant. This is required to specify which tenant's data to access.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransfer'."]:
    """Retrieve details of a specific bank transfer using its ID.

    This tool retrieves information about a specific bank transfer by using its unique bank transfer ID. It should be called when you need detailed information about a particular bank transfer within the Xero service."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransfers/{BankTransferID}".format(  # noqa: UP032
            BankTransferID=bank_transfer_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_bank_transfer_attachments(
    context: ToolContext,
    bank_transfer_id: Annotated[
        str,
        "Xero-generated unique identifier for a bank transfer. Required to retrieve associated attachments.",  # noqa: E501
    ],
    tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for your tenant. This ID specifies which tenant the bank transfer belongs to.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransferAttachments'."]:
    """Retrieve attachments from a specific bank transfer in Xero.

    Use this tool to get a list of attachments related to a particular bank transfer in Xero by providing the BankTransferID. Ideal for when you need access to documents associated with bank transactions."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransfers/{BankTransferID}/Attachments".format(  # noqa: UP032
            BankTransferID=bank_transfer_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def fetch_bank_transfer_attachment(
    context: ToolContext,
    bank_transfer_unique_id: Annotated[
        str,
        "Xero-generated unique identifier for a bank transfer. It is required to locate the specific transfer for the attachment.",  # noqa: E501
    ],
    attachment_id: Annotated[
        str,
        "Unique identifier for the attachment object that you want to retrieve from a specific bank transfer.",  # noqa: E501
    ],
    tenant_identifier: Annotated[str, "The Xero identifier for the tenant you want to access."],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment to retrieve, e.g., image/jpg, application/pdf."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransferAttachmentById'."]:
    """Fetch a specific bank transfer attachment by ID.

    Use this tool to retrieve a specific attachment related to a bank transfer using the unique attachment ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransfers/{BankTransferID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            BankTransferID=bank_transfer_unique_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_bank_transfer_attachment(
    context: ToolContext,
    bank_transfer_id: Annotated[
        str,
        "Xero-generated unique identifier for a bank transfer. Required to specify which bank transfer's attachment is being retrieved.",  # noqa: E501
    ],
    attachment_file_name: Annotated[
        str, "The name of the attachment file to retrieve from the bank transfer."
    ],
    xero_tenant_identifier: Annotated[
        str, "The unique identifier for the Xero tenant associated with the bank transfer."
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file, such as 'image/jpg' or 'application/pdf'."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getBankTransferAttachmentByFileName'."
]:
    """Retrieve a bank transfer attachment by file name.

    Use this tool to obtain a specific attachment related to a bank transfer by providing the file name."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransfers/{BankTransferID}/Attachments/{FileName}".format(  # noqa: UP032
            BankTransferID=bank_transfer_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_bank_transfer_history(
    context: ToolContext,
    bank_transfer_id: Annotated[
        str, "Unique identifier for the Xero bank transfer needed to retrieve its history."
    ],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. Required to specify which tenant's bank transfer history to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBankTransferHistory'."]:
    """Retrieve specific bank transfer history by ID.

    This tool is used to get the history of a specific bank transfer using its unique ID. It should be called when detailed transaction records or changes related to a particular bank transfer are needed."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransfers/{BankTransferID}/History".format(  # noqa: UP032
            BankTransferID=bank_transfer_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_bank_transfer_history(
    context: ToolContext,
    bank_transfer_id: Annotated[
        str,
        "Xero generated unique identifier for the specific bank transfer to create a history record for.",  # noqa: E501
    ],
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for a Xero tenant. Required to specify which tenant's data to access.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string to safely retry requests without risk of duplication, limited to 128 characters.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createBankTransferHistoryRecord'."]:
    """Create a history record for a bank transfer.

    This tool creates a history record for a specified bank transfer within the Xero service. It is useful for tracking changes and updates to bank transfers."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BankTransfers/{BankTransferID}/History".format(  # noqa: UP032
            BankTransferID=bank_transfer_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_branding_themes(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str, "The unique identifier for the Xero tenant to retrieve branding themes."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBrandingThemes'."]:
    """Retrieve all branding themes from Xero.

    This tool calls the Xero API to fetch all available branding themes. It should be used when needing a comprehensive list of branding themes for the account."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BrandingThemes",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_branding_theme(
    context: ToolContext,
    branding_theme_id: Annotated[
        str, "Unique identifier for a branding theme to retrieve its details."
    ],
    tenant_identifier: Annotated[
        str,
        "The Xero identifier for the Tenant. This is required to specify which tenant's branding theme to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBrandingTheme'."]:
    """Retrieve details of a specific branding theme.

    This tool retrieves information about a specific branding theme by using its unique ID. It is useful for accessing and displaying branding theme details in accounting or financial software."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BrandingThemes/{BrandingThemeID}".format(  # noqa: UP032
            BrandingThemeID=branding_theme_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["paymentservices"]))
async def get_payment_services_for_branding_theme(
    context: ToolContext,
    branding_theme_id: Annotated[
        str, "Unique identifier for a Branding Theme to retrieve associated payment services."
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the Tenant. This unique ID is required to specify which tenant's data is being accessed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBrandingThemePaymentServices'."]:
    """Retrieve payment services for a specific branding theme.

    This tool retrieves the payment services linked to a given branding theme by its ID. Call this tool when you need to access payment service information tied to particular branding configurations."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/BrandingThemes/{BrandingThemeID}/PaymentServices".format(  # noqa: UP032
            BrandingThemeID=branding_theme_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.budgets.read"]))
async def retrieve_budgets(
    context: ToolContext,
    tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the tenant. Required for accessing specific tenant data.",
    ],
    filter_by_budget_id: Annotated[
        str | None, "Filter to retrieve a specific budget by its BudgetID."
    ] = None,
    filter_start_date: Annotated[
        str | None, "The start date to filter budgets until. Expected format is YYYY-MM-DD."
    ] = None,
    filter_by_end_date: Annotated[
        str | None, "Specify the end date to filter the budgets. Use the format YYYY-MM-DD."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBudgets'."]:
    """Retrieve a list of budgets from Xero.

    Use this tool to obtain detailed budgeting information from the Xero platform, helping manage and analyze budget data."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Budgets",
        method="GET",
        params=remove_none_values({
            "IDs": filter_by_budget_id,
            "DateTo": filter_start_date,
            "DateFrom": filter_by_end_date,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.budgets.read"]))
async def retrieve_budget_details(
    context: ToolContext,
    budget_identifier: Annotated[
        str,
        "Unique identifier for budgets. Required to retrieve specific budget details including budget lines.",  # noqa: E501
    ],
    tenant_identifier: Annotated[
        str, "Xero identifier for the Tenant to specify which tenant's budget to retrieve."
    ],
    filter_end_date: Annotated[
        str | None, "Specifies the end date to filter the budget data. Use the format YYYY-MM-DD."
    ] = None,
    filter_start_date: Annotated[
        str | None,
        "The start date from which to filter the budget details. Format must be YYYY-MM-DD.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBudget'."]:
    """Retrieve detailed information about a budget including lines.

    Use this tool to get information about a specified budget by its ID, including all associated budget lines."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Budgets/{BudgetID}".format(  # noqa: UP032
            BudgetID=budget_identifier
        ),
        method="GET",
        params=remove_none_values({"DateTo": filter_end_date, "DateFrom": filter_start_date}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.contacts.read", "accounting.contacts"]
    )
)
async def fetch_all_xero_contacts(
    context: ToolContext,
    tenant_identifier: Annotated[str, "A unique string to identify the tenant in Xero."],
    filter_by_element: Annotated[
        str | None, "Specify conditions to filter contacts by any element within their data fields."
    ] = None,
    sort_order: Annotated[
        str | None,
        "Specifies the sorting order for contacts based on a specified element, such as name or date.",  # noqa: E501
    ] = None,
    contact_ids: Annotated[
        list[str] | None,
        "Comma-separated list of ContactIDs to retrieve specific contacts. Use this to filter the contacts returned by their unique IDs in a single call.",  # noqa: E501
    ] = None,
    pagination_page_number: Annotated[
        int | None,
        "The specific page number to retrieve when fetching contacts. Each page returns up to 100 contacts.",  # noqa: E501
    ] = None,
    search_term: Annotated[
        str | None,
        "A case-insensitive search term for filtering contacts by Name, FirstName, LastName, ContactNumber, or EmailAddress.",  # noqa: E501
    ] = None,
    records_per_page: Annotated[
        int | None, "Number of contact records to retrieve per page."
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Retrieve only records created or modified after the specified timestamp. Use ISO 8601 format for the timestamp.",  # noqa: E501
    ] = None,
    include_archived_contacts: Annotated[
        bool | None,
        "Set to true to include contacts with a status of ARCHIVED in the response. False will exclude them.",  # noqa: E501
    ] = None,
    retrieve_summary_only_contacts: Annotated[
        bool | None,
        "Set to true to retrieve only lightweight contact fields, excluding computation-heavy data for faster API responses.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContacts'."]:
    """Retrieve all contacts from a Xero organization.

    Use this tool to obtain a list of all contacts within a specified Xero organization. It should be called when there's a need to access or manage contact information in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts",
        method="GET",
        params=remove_none_values({
            "where": filter_by_element,
            "order": sort_order,
            "IDs": contact_ids,
            "page": pagination_page_number,
            "includeArchived": include_archived_contacts,
            "summaryOnly": retrieve_summary_only_contacts,
            "searchTerm": search_term,
            "pageSize": records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.contacts.read", "accounting.contacts"]
    )
)
async def get_xero_contact_by_number(
    context: ToolContext,
    contact_number: Annotated[
        str, "The unique contact number to identify a Xero contact; max length 50 characters."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. It is required to specify which organization's data to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactByContactNumber'."]:
    """Retrieve a contact from Xero by contact number.

    This tool retrieves details of a specific contact in a Xero organization using their contact number. It should be called when you need to access contact information by specifying the unique contact number."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactNumber}".format(  # noqa: UP032
            ContactNumber=contact_number
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.contacts.read", "accounting.contacts"]
    )
)
async def retrieve_xero_contact(
    context: ToolContext,
    contact_id: Annotated[
        str,
        "Provide the unique identifier for the contact to retrieve their information from Xero.",
    ],
    xero_tenant_identifier: Annotated[
        str, "The unique identifier for the tenant in Xero, required to retrieve contact details."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContact'."]:
    """Retrieve specific contact information from Xero.

    Use this tool to retrieve details of a specific contact in a Xero organization by providing a unique contact ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactID}".format(ContactID=contact_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_contact_attachments(
    context: ToolContext,
    contact_id: Annotated[str, "Unique identifier for a contact in Xero."],
    xero_tenant_identifier: Annotated[
        str, "The unique Xero tenant identifier for the organisation."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactAttachments'."]:
    """Retrieve attachments for a Xero contact.

    This tool retrieves all attachments associated with a specific contact within a Xero organisation. Call this tool when you need to access files linked to a contact in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactID}/Attachments".format(  # noqa: UP032
            ContactID=contact_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_contact_attachment(
    context: ToolContext,
    contact_id: Annotated[
        str, "Unique identifier for a Contact in Xero to retrieve a specific attachment."
    ],
    attachment_id: Annotated[
        str, "Unique identifier for the Attachment object from a contact in Xero."
    ],
    tenant_identifier: Annotated[
        str,
        "The unique identifier for the tenant in Xero to access specific data connected to a tenant account.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file (e.g., image/jpeg, application/pdf)."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactAttachmentById'."]:
    """Retrieve a specific contact attachment by ID.

    Use this tool to get a specific attachment from a contact by providing the unique attachment ID. Useful for accessing detailed attachment data linked to a contact in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            ContactID=contact_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_contact_attachment(
    context: ToolContext,
    contact_identifier: Annotated[
        str, "Unique identifier for a contact in Xero to retrieve its specific attachment."
    ],
    attachment_file_name: Annotated[
        str, "Specify the name of the attachment to retrieve from the contact."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. This is required to specify which tenant's data should be accessed.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file, such as image/jpg or application/pdf."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactAttachmentByFileName'."]:
    """Retrieve a contact's attachment by file name.

    Fetches a specific attachment associated with a contact using the file name in Xero. Use when you need to access a particular contact's attachment."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactID}/Attachments/{FileName}".format(  # noqa: UP032
            ContactID=contact_identifier, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_contact_cis_settings(
    context: ToolContext,
    contact_identifier: Annotated[str, "Unique identifier for a specific contact in Xero."],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. Required for accessing the correct organization within Xero.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactCISSettings'."]:
    """Retrieve CIS settings for a Xero contact.

    Use this tool to obtain the CIS (Construction Industry Scheme) settings for a specific contact within a Xero organization. This is useful for businesses managing construction-related compliance and financial data."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactID}/CISSettings".format(  # noqa: UP032
            ContactID=contact_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.contacts.read", "accounting.contacts"]
    )
)
async def get_contact_history(
    context: ToolContext,
    contact_id: Annotated[
        str, "Unique identifier for a contact to retrieve their history records."
    ],
    tenant_identifier: Annotated[
        str, "The unique Xero identifier for the tenant. Required to access specific tenant data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactHistory'."]:
    """Retrieve history records for a specific contact.

    Use this tool to obtain historical interaction records for a specific contact, which can provide insights into past communications and actions."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactID}/History".format(  # noqa: UP032
            ContactID=contact_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.contacts"]))
async def add_contact_history_record(
    context: ToolContext,
    contact_unique_identifier: Annotated[
        str,
        "Unique identifier for a Contact in Xero. Required to specify which contact the history record is for.",  # noqa: E501
    ],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Required to specify which tenant's contact history to update.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string up to 128 characters to safely retry requests without duplicate processing.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createContactHistory'."]:
    """Create a new history record for a contact in Xero.

    This tool allows you to add a new history entry for a specific contact in Xero. Use it to log interactions, notes, or any relevant information about the contact."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Contacts/{ContactID}/History".format(  # noqa: UP032
            ContactID=contact_unique_identifier
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.contacts.read", "accounting.contacts"]
    )
)
async def retrieve_contact_groups(
    context: ToolContext,
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Required to access the correct tenant's contact groups.",
    ],
    filter_criteria: Annotated[
        str | None,
        "A string to filter contact groups based on specified criteria, using any element.",
    ] = None,
    order_by: Annotated[
        str | None,
        "Specify the criteria to order the contact groups by. It can be any element to sort the results accordingly.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactGroups'."]:
    """Retrieve contact group IDs and names from Xero.

    Use this tool to get a list of contact groups from Xero, including each group's ID and name. Ideal for identifying specific contact groups and managing contacts effectively."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ContactGroups",
        method="GET",
        params=remove_none_values({"where": filter_criteria, "order": order_by}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.contacts.read", "accounting.contacts"]
    )
)
async def retrieve_contact_group(
    context: ToolContext,
    contact_group_id: Annotated[
        str,
        "Unique identifier for a Contact Group in Xero. Use this to retrieve specific group details.",  # noqa: E501
    ],
    xero_tenant_id: Annotated[
        str, "Identifier for the Xero tenant needed to access specific tenant data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getContactGroup'."]:
    """Retrieve a specific contact group by ID.

    Call this tool to get details of a particular contact group using its unique ID on Xero."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ContactGroups/{ContactGroupID}".format(  # noqa: UP032
            ContactGroupID=contact_group_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.contacts"]))
async def remove_contacts_from_group(
    context: ToolContext,
    contact_group_id: Annotated[
        str, "Unique identifier for the contact group to remove contacts from."
    ],
    xero_tenant_identifier: Annotated[
        str, "Xero identifier for the specific tenant required to access its data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteContactGroupContacts'."]:
    """Removes all contacts from a specified contact group in Xero.

    Use this tool to delete all contacts from a specific contact group in Xero. Ideal for cleaning or reorganizing contact groups."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ContactGroups/{ContactGroupID}/Contacts".format(  # noqa: UP032
            ContactGroupID=contact_group_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.contacts"]))
async def remove_contact_from_group(
    context: ToolContext,
    contact_group_id: Annotated[
        str,
        "Unique identifier for a contact group to specify which group the contact should be removed from.",  # noqa: E501
    ],
    contact_identifier: Annotated[
        str, "Unique identifier for a contact to be removed from the group."
    ],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. Required for specifying the target tenant in requests.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteContactGroupContact'."]:
    """Delete a specific contact from a contact group.

    This tool removes a specified contact from a contact group using unique identifiers for both the contact and the group. It should be called when there is a need to manage and update contact groups by removing contacts."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ContactGroups/{ContactGroupID}/Contacts/{ContactID}".format(  # noqa: UP032
            ContactGroupID=contact_group_id, ContactID=contact_identifier
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_credit_notes(
    context: ToolContext,
    tenant_identifier: Annotated[
        str,
        "The unique identifier for the Xero tenant. Required to specify which tenant's credit notes to retrieve.",  # noqa: E501
    ],
    filter_by_element: Annotated[
        str | None, "A string to filter credit notes by specific criteria using any element."
    ] = None,
    sort_credit_notes: Annotated[
        str | None, "Specifies the order to retrieve credit notes, e.g., by date or amount."
    ] = None,
    page_number: Annotated[
        int | None,
        "The page number to retrieve. Each page returns up to 100 credit notes with line items.",
    ] = None,
    unit_decimal_places: Annotated[
        int | None,
        "Specify the number of decimal places for unit amounts. For example, use 4 for four decimal places.",  # noqa: E501
    ] = None,
    number_of_records_per_page: Annotated[
        int | None,
        "Defines the number of credit notes to retrieve per page from the Xero service. This helps control the size of each result set.",  # noqa: E501
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Only retrieve records created or modified after this timestamp (in ISO 8601 format).",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCreditNotes'."]:
    """Retrieve credit notes from the Xero service.

    Use this tool to obtain credit notes from Xero. Ideal for financial checks or reconciliations requiring credit note information."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes",
        method="GET",
        params=remove_none_values({
            "where": filter_by_element,
            "order": sort_credit_notes,
            "page": page_number,
            "unitdp": unit_decimal_places,
            "pageSize": number_of_records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_credit_note(
    context: ToolContext,
    credit_note_id: Annotated[
        str, "Unique identifier for the credit note to retrieve details from Xero."
    ],
    tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the tenant associated with the credit note. It is required to specify which tenant's data to access.",  # noqa: E501
    ],
    use_four_decimal_places: Annotated[
        int | None,
        "Specify if four decimal places should be used for unit amounts. Default is false.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCreditNote'."]:
    """Retrieve a credit note using its unique ID.

    Use this tool to get detailed information about a specific credit note by providing its unique ID. Ideal for obtaining precise credit note data from your Xero account."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}".format(  # noqa: UP032
            CreditNoteID=credit_note_id
        ),
        method="GET",
        params=remove_none_values({"unitdp": use_four_decimal_places}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_credit_note_attachments(
    context: ToolContext,
    credit_note_id: Annotated[
        str, "Unique identifier for a specific Credit Note in Xero to fetch attachments."
    ],
    tenant_identifier: Annotated[
        str, "Xero identifier for the tenant. Required to specify which tenant's data to access."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCreditNoteAttachments'."]:
    """Fetch attachments for a specific credit note from Xero.

    Use this tool to retrieve attachments associated with a specific credit note in Xero. Call this tool when you need details or files attached to a credit note."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}/Attachments".format(  # noqa: UP032
            CreditNoteID=credit_note_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_credit_note_attachment(
    context: ToolContext,
    credit_note_id: Annotated[
        str, "Unique identifier for the credit note you want to retrieve an attachment from."
    ],
    attachment_id: Annotated[str, "Unique identifier for the attachment object to be retrieved."],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. It's required to specify which organization to access.",
    ],
    attachment_mime_type: Annotated[
        str,
        "The MIME type of the attachment file to retrieve, such as image/jpg or application/pdf.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCreditNoteAttachmentById'."]:
    """Retrieve specific attachment from a credit note by ID.

    Use this tool to get an attachment from a credit note using the unique attachment ID."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            CreditNoteID=credit_note_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_credit_note_attachment(
    context: ToolContext,
    credit_note_id: Annotated[
        str,
        "Unique identifier for a Credit Note. Use this ID to specify which credit note's attachment you want to retrieve.",  # noqa: E501
    ],
    attachment_file_name: Annotated[
        str, "The name of the attachment to be retrieved from the credit note (e.g., invoice.pdf)."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Unique identifier for the Xero Tenant. Required to specify which tenant's data to access.",
    ],
    attachment_mime_type: Annotated[
        str,
        "The MIME type of the attachment file to retrieve, such as 'image/jpg' or 'application/pdf'.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getCreditNoteAttachmentByFileName'."
]:
    """Retrieve a specific credit note attachment by file name.

    Use this tool to get a particular attachment from a specific credit note using the file name as a reference. It is helpful when you need to access or verify document details associated with a credit note."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}/Attachments/{FileName}".format(  # noqa: UP032
            CreditNoteID=credit_note_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_credit_note_pdf(
    context: ToolContext,
    credit_note_id: Annotated[str, "Unique identifier for the credit note to retrieve as a PDF."],
    tenant_identifier: Annotated[
        str, "Xero identifier for the tenant to retrieve the specific credit note PDF."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCreditNoteAsPdf'."]:
    """Retrieve a credit note as a PDF file.

    Use this tool to fetch a specific credit note in PDF format using its ID."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}/pdf".format(  # noqa: UP032
            CreditNoteID=credit_note_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def delete_credit_note_allocation(
    context: ToolContext,
    credit_note_unique_id: Annotated[
        str, "Unique identifier for a specific credit note to delete the allocation from."
    ],
    allocation_id: Annotated[
        str, "Unique identifier for the Allocation object needing deletion from a credit note."
    ],
    xero_tenant_id: Annotated[
        str,
        "Unique Xero identifier for the Tenant. Required to specify which tenant's data is being accessed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteCreditNoteAllocations'."]:
    """Remove an allocation from a specific credit note.

    This tool is used to delete an allocation from a specified credit note in the Xero system. It should be called when you need to remove a particular allocation detail from an existing credit note."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}/Allocations/{AllocationID}".format(  # noqa: UP032
            CreditNoteID=credit_note_unique_id, AllocationID=allocation_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_credit_note_history(
    context: ToolContext,
    credit_note_id: Annotated[
        str,
        "Unique identifier for a specific credit note. Required to retrieve its history records.",
    ],
    xero_tenant_id: Annotated[
        str, "The unique identifier for a Xero tenant. Required to access tenant-specific data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCreditNoteHistory'."]:
    """Retrieve history records of a specific credit note.

    Use this tool to obtain detailed history records for a specific credit note by providing its ID. It helps in tracking changes and updates made to the credit note over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}/History".format(  # noqa: UP032
            CreditNoteID=credit_note_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def fetch_credit_note_history(
    context: ToolContext,
    credit_note_id: Annotated[
        str, "Unique identifier for the credit note whose history you want to retrieve."
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the tenant. Required to specify which tenant's credit note history to retrieve.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "String to safely retry requests without creating duplicates. Max 128 characters.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createCreditNoteHistory'."]:
    """Retrieve the history of a specific credit note.

    Use this tool to access and retrieve history records of a specific credit note by providing the CreditNoteID. This can be helpful for auditing or tracking changes made to a credit note over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/CreditNotes/{CreditNoteID}/History".format(  # noqa: UP032
            CreditNoteID=credit_note_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_xero_currencies(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str, "Xero identifier for the tenant. Required to access organization-specific data."
    ],
    filter_criteria: Annotated[
        str | None,
        "A string to filter the currencies based on specific criteria, such as currency code or name.",  # noqa: E501
    ] = None,
    order_by: Annotated[
        str | None,
        "Specify the element to order the currencies by. Accepts a string corresponding to an element in the currency data.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCurrencies'."]:
    """Retrieve currencies from your Xero organization.

    Use this tool to get a list of all currencies associated with your Xero organization. It is useful for financial tasks, reporting, or currency conversion needs."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Currencies",
        method="GET",
        params=remove_none_values({"where": filter_criteria, "order": order_by}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_expense_claims(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "The unique identifier for the Xero tenant required to specify which organization's data to retrieve.",  # noqa: E501
    ],
    filter_by_element: Annotated[
        str | None, "Apply a filter based on specific elements in the expense claims."
    ] = None,
    order_by: Annotated[
        str | None,
        "Specify the element by which to order the expense claims, such as date or amount.",
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Retrieve records created or modified since this timestamp in ISO 8601 format (e.g., '2023-10-04T00:00:00Z').",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getExpenseClaims'."]:
    """Fetches expense claims from Xero.

    This tool should be called to retrieve detailed expense claims data from Xero. It can be used to review or analyze expenses."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ExpenseClaims",
        method="GET",
        params=remove_none_values({"where": filter_by_element, "order": order_by}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_expense_claim(
    context: ToolContext,
    expense_claim_id: Annotated[
        str, "Unique identifier for an expense claim to retrieve its details."
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero tenant identifier for the specific business or organization you are retrieving the expense claim from.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getExpenseClaim'."]:
    """Retrieve details of a specific expense claim by ID.

    Use this tool to obtain details about a specific expense claim using its unique ID. This is useful for reviewing or verifying expense claims in your records."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ExpenseClaims/{ExpenseClaimID}".format(  # noqa: UP032
            ExpenseClaimID=expense_claim_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_expense_claim_history(
    context: ToolContext,
    expense_claim_id: Annotated[
        str, "Unique identifier for retrieving the specific expense claim history."
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the tenant. This is required to specify which tenant's data to access.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getExpenseClaimHistory'."]:
    """Retrieve the history of a specific expense claim.

    Use this tool to obtain history records for a specific expense claim using its ID."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ExpenseClaims/{ExpenseClaimID}/History".format(  # noqa: UP032
            ExpenseClaimID=expense_claim_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def add_expense_claim_history(
    context: ToolContext,
    expense_claim_id: Annotated[
        str, "Unique identifier for the specific expense claim to add a history record."
    ],
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for the Xero tenant. This is required to specify which tenant the expense claim history record is associated with.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string (max 128 characters) to safely retry requests without duplicating processing.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createExpenseClaimHistory'."]:
    """Creates a history record for an expense claim.

    Use this tool to add a record to the history of a specific expense claim. It should be called when there is a need to document a change or update related to an expense claim in the system."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ExpenseClaims/{ExpenseClaimID}/History".format(  # noqa: UP032
            ExpenseClaimID=expense_claim_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_invoices(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str, "Unique identifier for a Xero tenant to retrieve invoices specific to that tenant."
    ],
    filter_by_condition: Annotated[
        str | None,
        "Filter using a condition expression defined on any element, similar to a SQL WHERE clause.",  # noqa: E501
    ] = None,
    order_by: Annotated[
        str | None, "Specify the criteria for ordering invoices, such as date or amount."
    ] = None,
    invoice_ids: Annotated[
        list[str] | None, "Comma-separated list of Invoice IDs to filter results."
    ] = None,
    filter_by_invoice_numbers: Annotated[
        list[str] | None,
        "Filter results by providing a list of invoice numbers. Each item should be a string representing one invoice number.",  # noqa: E501
    ] = None,
    filter_contact_ids: Annotated[
        list[str] | None, "Comma-separated list of ContactIDs to filter invoices."
    ] = None,
    filter_by_statuses: Annotated[
        list[str] | None,
        "Filter invoices by a list of statuses for improved response times. Use explicit parameters instead of OR conditions.",  # noqa: E501
    ] = None,
    page_number: Annotated[
        int | None,
        "Specify the page number to retrieve. Up to 100 invoices per page can be returned.",
    ] = None,
    unit_decimal_places: Annotated[
        int | None,
        "Specify the number of decimal places for unit amounts, e.g., 4 for four decimal places.",
    ] = None,
    records_per_page: Annotated[
        int | None, "Specify the number of invoice records to retrieve per page."
    ] = None,
    search_term: Annotated[
        str | None,
        "A case-insensitive search parameter for fields like InvoiceNumber and Reference.",
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Return only records created or modified since this timestamp. Use the format 'YYYY-MM-DDTHH:MM:SS'.",  # noqa: E501
    ] = None,
    include_archived_invoices: Annotated[
        bool | None, "Set to true to include invoices with a status of ARCHIVED in the response."
    ] = None,
    filter_by_created_by_my_app: Annotated[
        bool | None, "Set to true to retrieve only invoices created by your app."
    ] = None,
    retrieve_summary_only: Annotated[
        bool | None,
        "Set to true to retrieve a smaller, lightweight version of the response for quicker API calls, excluding computation-heavy fields.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoices'."]:
    """Retrieve sales invoices or purchase bills from Xero.

    Use this tool to retrieve detailed information about sales invoices or purchase bills from Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices",
        method="GET",
        params=remove_none_values({
            "where": filter_by_condition,
            "order": order_by,
            "IDs": invoice_ids,
            "InvoiceNumbers": filter_by_invoice_numbers,
            "ContactIDs": filter_contact_ids,
            "Statuses": filter_by_statuses,
            "page": page_number,
            "includeArchived": include_archived_invoices,
            "createdByMyApp": filter_by_created_by_my_app,
            "unitdp": unit_decimal_places,
            "summaryOnly": retrieve_summary_only,
            "pageSize": records_per_page,
            "searchTerm": search_term,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_invoice_details(
    context: ToolContext,
    invoice_identifier: Annotated[str, "Unique identifier for the invoice to be retrieved."],
    xero_tenant_id: Annotated[
        str, "Xero identifier for the Tenant. Used to specify which tenant's invoice is retrieved."
    ],
    unit_decimal_places: Annotated[
        int | None,
        "Specify the number of decimal places to use for unit amounts, e.g., 4 for four decimal places.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoice'."]:
    """Retrieve a specific invoice using its unique ID.

    Use this tool to get detailed information about a specific sales invoice or purchase bill by providing its unique invoice ID. This can be helpful when checking invoice details in the Xero accounting system."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}".format(  # noqa: UP032
            InvoiceID=invoice_identifier
        ),
        method="GET",
        params=remove_none_values({"unitdp": unit_decimal_places}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_invoice_pdf(
    context: ToolContext,
    invoice_id: Annotated[str, "Unique identifier for the invoice to retrieve as a PDF from Xero."],
    tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the tenant. This is required to specify the account from which to retrieve the invoice PDF.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoiceAsPdf'."]:
    """Retrieve an invoice or purchase bill as a PDF.

    This tool retrieves an invoice or purchase bill in PDF format using the invoice ID. It is useful when you need a downloadable version of an invoice from Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}/pdf".format(  # noqa: UP032
            InvoiceID=invoice_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_invoice_attachments(
    context: ToolContext,
    invoice_id: Annotated[str, "Unique identifier for the invoice to retrieve attachments from."],
    tenant_identifier: Annotated[str, "Xero identifier for the Tenant that owns the invoice."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoiceAttachments'."]:
    """Retrieve attachments for a specific invoice or bill.

    This tool is used to obtain attachments related to a particular invoice or purchase bill from Xero. Call this tool when you need to access documents or files attached to a specific invoice."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}/Attachments".format(  # noqa: UP032
            InvoiceID=invoice_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_invoice_attachment_by_id(
    context: ToolContext,
    invoice_id: Annotated[
        str, "The unique identifier for the invoice to retrieve the attachment from."
    ],
    attachment_id: Annotated[str, "Unique identifier for the attachment object in Xero."],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. Required to specify the tenant from which the attachment is being retrieved.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file, e.g., image/jpg or application/pdf."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoiceAttachmentById'."]:
    """Retrieve a specific invoice attachment by ID.

    Use this tool to obtain a specific attachment from an invoice or purchase bill using its unique attachment ID in Xero. Call this tool when you need to access or review an attachment related to an invoice."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            InvoiceID=invoice_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_invoice_attachment(
    context: ToolContext,
    invoice_id: Annotated[
        str, "Unique identifier for the invoice from which to retrieve the attachment."
    ],
    attachment_file_name: Annotated[
        str,
        "Specify the exact name of the attachment to retrieve from the invoice or purchase bill.",
    ],
    tenant_identifier: Annotated[
        str, "Xero identifier for the Tenant to specify which organization's data to access."
    ],
    attachment_mime_type: Annotated[
        str,
        "The MIME type of the attachment file being retrieved, such as image/jpg or application/pdf.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoiceAttachmentByFileName'."]:
    """Retrieve an attachment from an invoice by filename.

    Use this tool to obtain a specific attachment from an invoice or purchase bill by specifying the filename."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}/Attachments/{FileName}".format(  # noqa: UP032
            InvoiceID=invoice_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_online_invoice_url(
    context: ToolContext,
    invoice_identifier: Annotated[
        str, "Unique identifier for the invoice to retrieve its online URL."
    ],
    xero_tenant_id: Annotated[
        str, "Xero tenant identifier needed to retrieve the correct online invoice."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOnlineInvoice'."]:
    """Retrieve a URL for viewing an online invoice.

    Use this tool to obtain a direct URL for accessing a specific online invoice based on its InvoiceID. The tool helps retrieve online invoice links for quick viewing and sharing."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}/OnlineInvoice".format(  # noqa: UP032
            InvoiceID=invoice_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_invoice_history(
    context: ToolContext,
    invoice_id: Annotated[str, "Unique identifier for the invoice to retrieve its history."],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. This is required to specify which tenant's data to access.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoiceHistory'."]:
    """Retrieve history of a specific invoice.

    Retrieves history records for a specific invoice using its Invoice ID. This tool is useful for tracking changes and updates made to an invoice over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}/History".format(  # noqa: UP032
            InvoiceID=invoice_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_invoice_history(
    context: ToolContext,
    invoice_id: Annotated[
        str,
        "Unique identifier for the invoice. This is required to create a history record for the specified invoice in Xero.",  # noqa: E501
    ],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Required for specifying which tenant the invoice history belongs to.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A string up to 128 characters to safely retry requests without duplicate processing.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createInvoiceHistory'."]:
    """Create a history record for a specific invoice.

    Use this tool to log a history record for a particular invoice in Xero. Ideal for tracking changes or adding comments to an invoice's history."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Invoices/{InvoiceID}/History".format(  # noqa: UP032
            InvoiceID=invoice_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_invoice_reminder_settings(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for the Xero tenant. This is required to access specific tenant data.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getInvoiceReminders'."]:
    """Retrieve invoice reminder settings from Xero.

    This tool retrieves the current settings for invoice reminders from Xero. It should be called when you need to check or manage how invoice reminders are configured."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/InvoiceReminders/Settings",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_items(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for a Xero tenant. Required to specify which tenant's data to retrieve.",  # noqa: E501
    ],
    filter_criteria: Annotated[
        str | None,
        "Filter items by specific criteria using any element such as field names or conditions.",
    ] = None,
    order_by_element: Annotated[
        str | None, "Specify the sorting order of items by any element, such as name or price."
    ] = None,
    unit_decimal_places: Annotated[
        int | None,
        "Defines the number of decimal places for unit amounts, e.g., 4 for four decimal places.",
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Fetch records created or modified since the provided timestamp (e.g., '2023-01-01T00:00:00Z').",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getItems'."]:
    """Retrieve items from Xero.

    This tool fetches a list of items from the Xero service, typically used for inventory or sales purposes."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Items",
        method="GET",
        params=remove_none_values({
            "where": filter_criteria,
            "order": order_by_element,
            "unitdp": unit_decimal_places,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_xero_item(
    context: ToolContext,
    item_identifier: Annotated[
        str,
        "The unique identifier for the item in Xero. This is required to retrieve specific item details.",  # noqa: E501
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. This is required to specify which tenant's data should be accessed.",  # noqa: E501
    ],
    use_unit_decimal_places: Annotated[
        int | None,
        "Specify the number of unit decimal places to use, e.g., 4 for four decimal places in unit amounts.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getItem'."]:
    """Retrieve a specific item from Xero using its ID.

    Call this tool when you need to fetch details about a particular item from Xero by providing its unique item ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Items/{ItemID}".format(ItemID=item_identifier),  # noqa: UP032
        method="GET",
        params=remove_none_values({"unitdp": use_unit_decimal_places}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.settings"]))
async def delete_inventory_item(
    context: ToolContext,
    item_id: Annotated[str, "Unique identifier for the item to be deleted."],
    tenant_identifier: Annotated[
        str, "The unique identifier for the Xero tenant to specify which tenant's data to access."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteItem'."]:
    """Delete a specific item from inventory.

    Use this tool to remove an item from the inventory based on its ItemID. Call this tool to manage inventory by deleting items that are no longer needed or available."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Items/{ItemID}".format(ItemID=item_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_item_history(
    context: ToolContext,
    item_id: Annotated[
        str, "Unique identifier for the item whose history you want to retrieve in Xero."
    ],
    xero_tenant_id: Annotated[
        str, "Provide the unique Xero identifier associated with the Tenant to access its data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getItemHistory'."]:
    """Retrieve history for a specific item from Xero.

    This tool retrieves the historical details of a specific item using its ItemID. Use it to access the change history or modifications made to an item within the Xero platform."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Items/{ItemID}/History".format(ItemID=item_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.settings"]))
async def create_item_history(
    context: ToolContext,
    item_id: Annotated[
        str, "Unique identifier for the item to create a history record for in Xero."
    ],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant, required to specify which tenant's item history is being updated.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique key to ensure request retrying without duplication, max 128 characters.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createItemHistory'."]:
    """Creates a history record for a specific item in Xero.

    This tool is used to create a history record for a specific item in Xero, allowing users to keep track of changes or updates made to an item."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Items/{ItemID}/History".format(ItemID=item_id),  # noqa: UP032
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.journals.read"]))
async def get_financial_journals(
    context: ToolContext,
    tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the tenant. Required to specify which tenant's journals are retrieved.",  # noqa: E501
    ],
    journal_number_offset: Annotated[
        int | None,
        "Specify the journal number offset. Journals with a number greater than this will be returned.",  # noqa: E501
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Return records created or modified since this timestamp. Use a string format like 'YYYY-MM-DDTHH:MM:SSZ'.",  # noqa: E501
    ] = None,
    retrieve_cash_basis_journals: Annotated[
        bool | None,
        "Set to true to retrieve journals on a cash basis. Defaults to false for accrual basis.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getJournals'."]:
    """Retrieve financial journal entries from Xero.

    Use this tool to access financial journal entries recorded in Xero. It should be called when detailed accounting journal information is needed for financial analysis or record-keeping."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Journals",
        method="GET",
        params=remove_none_values({
            "offset": journal_number_offset,
            "paymentsOnly": retrieve_cash_basis_journals,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.journals.read"]))
async def retrieve_specific_journal(
    context: ToolContext,
    journal_id: Annotated[str, "Unique identifier for the journal to be retrieved."],
    xero_tenant_identifier: Annotated[
        str,
        "A unique identifier for the Xero tenant. Required to specify which tenant's journal should be accessed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getJournal'."]:
    """Retrieve a specific journal using its unique ID.

    Call this tool to get detailed information about a particular journal by specifying its unique identifier. Useful for accessing specific journal entries in the Xero system."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Journals/{JournalID}".format(JournalID=journal_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.journals.read"]))
async def retrieve_journal_by_number(
    context: ToolContext,
    journal_number: Annotated[int, "The unique number identifying the journal entry to retrieve."],
    tenant_identifier: Annotated[
        str,
        "The unique identifier for a Xero tenant to specify the context for the journal retrieval.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getJournalByNumber'."]:
    """Retrieve a specific journal by its unique number.

    Use this tool to obtain detailed information about a particular journal entry using its unique journal number."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Journals/{JournalNumber}".format(  # noqa: UP032
            JournalNumber=journal_number
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_linked_transactions(
    context: ToolContext,
    tenant_identifier: Annotated[
        str,
        "The Xero identifier for a specific tenant. Required for identifying the tenant whose linked transactions are being retrieved.",  # noqa: E501
    ],
    page_number: Annotated[
        int | None, "Specify the page number to retrieve in paginated results, starting from 1."
    ] = None,
    linked_transaction_id: Annotated[
        str | None,
        "The Xero identifier for a Linked Transaction to retrieve specific billable expenses.",
    ] = None,
    source_transaction_id: Annotated[
        str | None,
        "Filter by SourceTransactionID to get linked transactions from a specific ACCPAY invoice.",
    ] = None,
    filter_by_contact_id: Annotated[
        str | None,
        "Filter results by the customer's ContactID to get linked transactions for a specific customer.",  # noqa: E501
    ] = None,
    filter_by_status: Annotated[
        str | None,
        "Filter linked transactions by status when combined with ContactID. Retrieves transactions associated with a customer based on this status.",  # noqa: E501
    ] = None,
    filter_by_target_transaction_id: Annotated[
        str | None,
        "Filter linked transactions by TargetTransactionID to get those allocated to a specific ACCREC invoice.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getLinkedTransactions'."]:
    """Retrieve linked transactions from Xero.

    Use this tool to get linked transactions, such as billable expenses, from the Xero platform. Call it when you need details about expenses that are linked or billable in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/LinkedTransactions",
        method="GET",
        params=remove_none_values({
            "page": page_number,
            "LinkedTransactionID": linked_transaction_id,
            "SourceTransactionID": source_transaction_id,
            "ContactID": filter_by_contact_id,
            "Status": filter_by_status,
            "TargetTransactionID": filter_by_target_transaction_id,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_linked_transaction(
    context: ToolContext,
    linked_transaction_id: Annotated[
        str, "Unique identifier for the linked transaction to be retrieved."
    ],
    tenant_id: Annotated[str, "Xero tenant identifier for accessing the correct organization."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getLinkedTransaction'."]:
    """Retrieve specific linked transaction details by ID.

    Use this tool to get detailed information about a specific linked transaction, such as billable expenses, using a unique transaction ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/LinkedTransactions/{LinkedTransactionID}".format(  # noqa: UP032
            LinkedTransactionID=linked_transaction_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def delete_linked_transaction(
    context: ToolContext,
    linked_transaction_id: Annotated[
        str, "Unique identifier for the linked transaction to be deleted."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Provide the unique Xero identifier for the tenant to specify the context of the deletion.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteLinkedTransaction'."]:
    """Delete a specific linked transaction.

    Use this tool to delete a specified linked transaction (billable expense) by providing the LinkedTransactionID. It should be called when there's a need to remove an existing linked expense from Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/LinkedTransactions/{LinkedTransactionID}".format(  # noqa: UP032
            LinkedTransactionID=linked_transaction_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_manual_journals(
    context: ToolContext,
    tenant_identifier: Annotated[
        str, "The unique Xero identifier for the Tenant to retrieve manual journals from."
    ],
    filter_criteria: Annotated[
        str | None, "Filter manual journals based on specified criteria, such as date or amount."
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specify the element to order the results by. Use field names like date, amount, etc.",
    ] = None,
    page_number: Annotated[
        int | None,
        "The page number to retrieve, e.g., page=1. Returns up to 100 manual journals per call.",
    ] = None,
    records_per_page: Annotated[
        int | None, "Specify the number of manual journal records to retrieve per page."
    ] = None,
    modified_since_timestamp: Annotated[
        str | None, "Retrieve records created or modified since this timestamp (ISO 8601 format)."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getManualJournals'."]:
    """Retrieve manual journals from Xero.

    Use this tool to get a list of manual journals from Xero, typically when needing insights into financial entries or audits."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ManualJournals",
        method="GET",
        params=remove_none_values({
            "where": filter_criteria,
            "order": order_by_element,
            "page": page_number,
            "pageSize": records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_manual_journal(
    context: ToolContext,
    manual_journal_id: Annotated[
        str, "Unique identifier for the manual journal you want to retrieve."
    ],
    xero_tenant_id: Annotated[
        str, "The unique identifier for a Xero tenant. Required to access tenant-specific data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getManualJournal'."]:
    """Retrieve details of a specific manual journal.

    Use this tool to obtain information about a particular manual journal by its ID. Ideal for users needing specific journal entry details from Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ManualJournals/{ManualJournalID}".format(  # noqa: UP032
            ManualJournalID=manual_journal_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_journal_attachments(
    context: ToolContext,
    manual_journal_id: Annotated[
        str, "The unique identifier for a specific manual journal to retrieve its attachments."
    ],
    tenant_id: Annotated[
        str, "The unique Xero identifier for the tenant to access the manual journal attachments."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getManualJournalAttachments'."]:
    """Retrieve attachments for a specific manual journal.

    Use this tool to retrieve attachments associated with a given manual journal in Xero. Ideal for accessing or reviewing documents linked to journal entries."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ManualJournals/{ManualJournalID}/Attachments".format(  # noqa: UP032
            ManualJournalID=manual_journal_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_journal_attachment(
    context: ToolContext,
    manual_journal_id: Annotated[
        str, "Unique identifier for the manual journal from which to retrieve the attachment."
    ],
    attachment_id: Annotated[
        str,
        "Provide the unique identifier for the attachment object to retrieve it from a manual journal.",  # noqa: E501
    ],
    xero_tenant_id: Annotated[
        str,
        "The unique Xero identifier for the tenant. Required to specify which tenant's data to access.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str,
        "Specify the mime type of the attachment (e.g., image/jpg, application/pdf) to retrieve.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getManualJournalAttachmentById'."]:
    """Retrieve a specific attachment from a manual journal using its ID.

    Use this tool to obtain a particular attachment linked to a specific manual journal by providing the unique attachment ID. Ideal for accessing relevant documents or files associated with journal entries."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ManualJournals/{ManualJournalID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            ManualJournalID=manual_journal_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_journal_attachment_by_filename(
    context: ToolContext,
    manual_journal_id: Annotated[
        str,
        "Unique identifier for the manual journal. Required to retrieve the specific attachment.",
    ],
    attachment_file_name: Annotated[
        str, "The name of the attachment file to retrieve from the manual journal."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "The unique identifier for the Xero tenant, used to specify the particular organization's data to access.",  # noqa: E501
    ],
    attachment_file_mime_type: Annotated[
        str, "The MIME type of the attachment file, such as image/jpeg or application/pdf."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getManualJournalAttachmentByFileName'."
]:
    """Retrieve a manual journal attachment by file name.

    Use this tool to get a specific attachment from a manual journal using its file name. It requires the manual journal ID and the file name to retrieve the attachment data."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ManualJournals/{ManualJournalID}/Attachments/{FileName}".format(  # noqa: UP032
            ManualJournalID=manual_journal_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_file_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_manual_journal_history(
    context: ToolContext,
    manual_journal_id: Annotated[
        str,
        "Unique identifier for the manual journal. Used to retrieve its historical details from Xero.",  # noqa: E501
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for a specific tenant. This is required to identify which tenant's data to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getManualJournalsHistory'."]:
    """Retrieve history for a specific manual journal.

    This tool fetches the historical details related to a specific manual journal by its ID from Xero, providing insights into past changes and actions."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ManualJournals/{ManualJournalID}/History".format(  # noqa: UP032
            ManualJournalID=manual_journal_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_journal_history_record(
    context: ToolContext,
    manual_journal_id: Annotated[str, "Unique identifier for a specific manual journal in Xero."],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant is required to specify which tenant's manual journal is being updated.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string, up to 128 characters, to safely retry requests without duplicate processing.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'createManualJournalHistoryRecord'."
]:
    """Creates a history record for a specific manual journal.

    Use this tool to log a new history entry for a specific manual journal in Xero."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/ManualJournals/{ManualJournalID}/History".format(  # noqa: UP032
            ManualJournalID=manual_journal_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_xero_organisation_details(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for the Xero tenant. This ID is required to specify which organisation's details to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrganisations'."]:
    """Retrieves Xero organisation details.

    Use this tool to obtain detailed information about organisations in Xero. Ideal for accessing organisation data when required."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Organisation",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_xero_organisation_actions(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str, "Xero identifier for the tenant to specify which organisation's actions to retrieve."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrganisationActions'."]:
    """Retrieve key actions allowed in Xero organisation.

    Use this tool to get a list of the key actions your application is allowed to perform within a connected Xero organisation. This helps in understanding the permissions available."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Organisation/Actions",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_cis_settings(
    context: ToolContext,
    organisation_id: Annotated[
        str, "The unique Xero identifier for the organisation to retrieve CIS settings for."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Required to specify which tenant's CIS settings to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrganisationCISSettings'."]:
    """Retrieve CIS settings for a Xero organisation.

    Use this tool to get the Construction Industry Scheme (CIS) settings for a specific organisation in Xero. Useful for managing or reviewing CIS compliance within the organisation."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Organisation/{OrganisationID}/CISSettings".format(  # noqa: UP032
            OrganisationID=organisation_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_overpayments(
    context: ToolContext,
    tenant_identifier: Annotated[
        str, "The unique identifier for the Xero tenant to retrieve overpayments for."
    ],
    filter_criteria: Annotated[
        str | None,
        'Filter overpayments by a specific element or condition. Use syntax like "Property=value" for filtering.',  # noqa: E501
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specify the element by which to order the retrieved overpayments. Accepts any valid field.",  # noqa: E501
    ] = None,
    page_number: Annotated[
        int | None,
        "The page number for retrieving overpayments. Up to 100 overpayments will be returned per page.",  # noqa: E501
    ] = None,
    unit_decimal_places: Annotated[
        int | None,
        "The number of decimal places to use for unit amounts. Accepts up to four decimals.",
    ] = None,
    records_per_page: Annotated[
        int | None,
        "Specify the number of records to retrieve per page. Determines the page size for the results.",  # noqa: E501
    ] = None,
    records_modified_since: Annotated[
        str | None,
        "Return records created or modified after the specified timestamp in ISO 8601 format.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOverpayments'."]:
    """Retrieve overpayments from the accounting system.

    Use this tool to access and retrieve a list of overpayments recorded in the Xero accounting system. This is useful for financial analysis and reconciliation."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Overpayments",
        method="GET",
        params=remove_none_values({
            "where": filter_criteria,
            "order": order_by_element,
            "page": page_number,
            "unitdp": unit_decimal_places,
            "pageSize": records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "If-Modified-Since": records_modified_since,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_specific_overpayment(
    context: ToolContext,
    overpayment_id: Annotated[
        str,
        "Unique identifier for the overpayment to be retrieved. This ID is required to fetch the specific details of the overpayment from Xero.",  # noqa: E501
    ],
    xero_tenant_identifier: Annotated[
        str,
        "The unique identifier for the Xero tenant. Required to specify which organization's data to access.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOverpayment'."]:
    """Retrieve details of a specific overpayment by ID.

    Use this tool to obtain information about a specific overpayment using its unique identifier. Ideal for accessing precise overpayment records within Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Overpayments/{OverpaymentID}".format(  # noqa: UP032
            OverpaymentID=overpayment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def delete_overpayment_allocation(
    context: ToolContext,
    overpayment_id: Annotated[str, "Unique identifier for a specific overpayment in Xero."],
    allocation_id: Annotated[str, "Unique identifier for the Allocation object to be deleted."],
    xero_tenant_identifier: Annotated[
        str, "Xero identifier for the tenant. Required to specify which tenant's data to access."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteOverpaymentAllocations'."]:
    """Delete an allocation from an overpayment in Xero.

    This tool deletes a specific allocation from an overpayment in the Xero system. Use this when you need to remove allocations linked to overpayments."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Overpayments/{OverpaymentID}/Allocations/{AllocationID}".format(  # noqa: UP032
            OverpaymentID=overpayment_id, AllocationID=allocation_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_overpayment_history(
    context: ToolContext,
    overpayment_id: Annotated[str, "Unique identifier for a specific overpayment in Xero."],
    xero_tenant_id: Annotated[
        str,
        "Unique identifier for the tenant in Xero. Used to specify which tenant's data to access.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOverpaymentHistory'."]:
    """Retrieve history records for a specific overpayment in Xero.

    Use this tool to obtain detailed history records related to a specific overpayment, identified by the Overpayment ID, within the Xero platform."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Overpayments/{OverpaymentID}/History".format(  # noqa: UP032
            OverpaymentID=overpayment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def record_overpayment_history(
    context: ToolContext,
    overpayment_id: Annotated[
        str, "Unique identifier for an overpayment that you want to create a history record for."
    ],
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for the Xero tenant. Required to specify which tenant to apply the overpayment history record to.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string (max 128 characters) for safely retrying requests without duplicate processing.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createOverpaymentHistory'."]:
    """Creates a history record for a specific overpayment.

    Use this tool to add a history record to an existing overpayment in Xero. It helps in tracking changes or notes related to overpayments."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Overpayments/{OverpaymentID}/History".format(  # noqa: UP032
            OverpaymentID=overpayment_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def fetch_invoice_payments(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. This is required to access the specific tenant's data.",
    ],
    filter_condition: Annotated[
        str | None, "Specify the filter condition for retrieving payments, based on any element."
    ] = None,
    order_by: Annotated[
        str | None, "Specify the order of payments by any element, such as date or amount."
    ] = None,
    page_number: Annotated[
        int | None,
        "The page number to retrieve, starting from 1. Up to 100 payments are returned per page.",
    ] = None,
    records_per_page: Annotated[
        int | None, "Specify the number of records to retrieve per page, up to a maximum of 100."
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Only records created or modified since this timestamp will be retrieved. Use ISO 8601 format (e.g., 'YYYY-MM-DDTHH:MM:SSZ').",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPayments'."]:
    """Retrieve payments for invoices and credit notes in Xero.

    Use this tool to fetch a list of payments associated with invoices and credit notes from Xero. It is useful for obtaining payment records for financial analysis or reconciliation purposes."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Payments",
        method="GET",
        params=remove_none_values({
            "where": filter_condition,
            "order": order_by,
            "page": page_number,
            "pageSize": records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_invoice_payment(
    context: ToolContext,
    payment_id: Annotated[
        str, "Unique identifier for the payment, used to retrieve specific payment details in Xero."
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the tenant. This is required to specify which organization's data to access.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPayment'."]:
    """Retrieve specific payment details using a payment ID.

    This tool retrieves details of a specific payment associated with invoices and credit notes using a unique payment ID. It should be called when there is a need to access information about a particular payment in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Payments/{PaymentID}".format(PaymentID=payment_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_payment_history(
    context: ToolContext,
    payment_identifier: Annotated[
        str, "Unique identifier for a specific payment to retrieve its history."
    ],
    tenant_identifier: Annotated[
        str, "Xero identifier for the tenant. Used to specify which tenant's data to access."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPaymentHistory'."]:
    """Retrieve the history records of a specific payment.

    Use this tool to obtain historical records related to a specific payment, including updates and changes made over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Payments/{PaymentID}/History".format(  # noqa: UP032
            PaymentID=payment_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_payment_history_record(
    context: ToolContext,
    payment_identifier: Annotated[str, "Unique identifier for a specific payment in Xero."],
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for the Xero tenant. This is required to specify which tenant's data the action applies to.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique key to safely retry requests and prevent duplicate processing. Maximum 128 characters.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createPaymentHistory'."]:
    """Create a history record for a specific payment.

    This tool is used to create a history record for a particular payment in Xero. It should be called when you want to document the history or add notes for a payment by its PaymentID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Payments/{PaymentID}/History".format(  # noqa: UP032
            PaymentID=payment_identifier
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["paymentservices"]))
async def retrieve_payment_services(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str,
        "Unique identifier for the Xero tenant. Required to retrieve specific payment services for the tenant.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPaymentServices'."]:
    """Retrieve available payment services from Xero.

    Use this tool to obtain a list of payment services available in Xero. It should be called when you need to access or display payment service options."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PaymentServices",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_prepayments(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the Tenant. Required for specifying which account's prepayments to retrieve.",  # noqa: E501
    ],
    filter_condition: Annotated[
        str | None, "Provide a filter condition to specify which prepayments to retrieve."
    ] = None,
    order_criteria: Annotated[
        str | None,
        "Specifies the order of elements. Use field names for custom sorting, such as 'Date ASC' or 'Amount DESC'.",  # noqa: E501
    ] = None,
    page_number: Annotated[
        int | None, "Specify the page number to retrieve, up to 100 prepayments per page."
    ] = None,
    unit_decimal_places: Annotated[
        int | None,
        "Specify the number of decimal places (e.g., 4) for unit amounts. Use for precise calculations.",  # noqa: E501
    ] = None,
    records_per_page: Annotated[
        int | None,
        "The number of prepayment records to retrieve per page. This controls how many results are returned in a single call.",  # noqa: E501
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Only return records created or modified since the specified timestamp (e.g., '2023-10-01T00:00:00Z').",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPrepayments'."]:
    """Retrieve prepayment details from Xero.

    Use this tool to fetch prepayment information from the Xero API, providing insights into prepayment transactions."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Prepayments",
        method="GET",
        params=remove_none_values({
            "where": filter_condition,
            "order": order_criteria,
            "page": page_number,
            "unitdp": unit_decimal_places,
            "pageSize": records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_prepayment_details(
    context: ToolContext,
    prepayment_id: Annotated[str, "The unique identifier for the prepayment you want to retrieve."],
    xero_tenant_id: Annotated[
        str,
        "The unique Xero identifier for the tenant. Required to retrieve specific prepayment data.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPrepayment'."]:
    """Retrieve details of a specified prepayment from Xero.

    Use this tool to obtain information on a specific prepayment by providing the PrepaymentID. Ideal for checking prepayment details within the Xero accounting system."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Prepayments/{PrepaymentID}".format(  # noqa: UP032
            PrepaymentID=prepayment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def delete_prepayment_allocation(
    context: ToolContext,
    prepayment_id: Annotated[
        str,
        "Unique identifier for a PrePayment. Required to specify which prepayment the allocation will be deleted from.",  # noqa: E501
    ],
    allocation_id: Annotated[
        str, "Unique identifier for the Allocation object to be deleted from a prepayment."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant in which the prepayment allocation deletion will occur.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deletePrepaymentAllocations'."]:
    """Delete an allocation from a prepayment in Xero.

    Use this tool to delete a specific allocation from a prepayment in Xero. This action is irreversible and should be used when a specific allocation needs to be removed."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Prepayments/{PrepaymentID}/Allocations/{AllocationID}".format(  # noqa: UP032
            PrepaymentID=prepayment_id, AllocationID=allocation_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_prepayment_history(
    context: ToolContext,
    prepayment_id: Annotated[str, "Unique identifier for the prepayment to retrieve its history."],
    xero_tenant_id: Annotated[
        str, "Unique identifier for the Xero tenant, required to access its data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPrepaymentHistory'."]:
    """Retrieve history for a specific prepayment.

    Use this tool to obtain the historical records associated with a specific prepayment in Xero."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Prepayments/{PrepaymentID}/History".format(  # noqa: UP032
            PrepaymentID=prepayment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_prepayment_history(
    context: ToolContext,
    prepayment_id: Annotated[
        str, "Unique identifier for the specific PrePayment to create a history record for."
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the Tenant. This is required to specify which tenant's data the prepayment history applies to.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string to safely retry requests without duplicate processing, up to 128 characters.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createPrepaymentHistory'."]:
    """Creates a history record for a specific prepayment.

    Call this tool to create a history entry for a given prepayment in Xero, specifying the prepayment ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Prepayments/{PrepaymentID}/History".format(  # noqa: UP032
            PrepaymentID=prepayment_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_purchase_orders(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str, "Unique identifier for the Xero tenant to access specific organization's data."
    ],
    filter_by_status: Annotated[
        str | None,
        "Filter purchase orders by status. Accepted values are: 'DRAFT', 'SUBMITTED', 'AUTHORISED', 'BILLED', 'DELETED'.",  # noqa: E501
    ] = None,
    filter_by_start_date: Annotated[
        str | None, "Specify the start date for filtering purchase orders. Use format 'YYYY-MM-DD'."
    ] = None,
    filter_by_end_date: Annotated[
        str | None, "Filter purchase orders by end date (format: YYYY-MM-DD)."
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specifies the element by which to sort the purchase orders, such as date or status. Accepts any valid field name.",  # noqa: E501
    ] = None,
    page_number: Annotated[
        int | None,
        "Specifies the page of results to retrieve. Increment to access subsequent pages of purchase orders.",  # noqa: E501
    ] = None,
    records_per_page: Annotated[
        int | None, "Specify the number of purchase order records to retrieve per page."
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Timestamp to filter records created or modified since this time. Use ISO 8601 format (e.g., '2023-01-01T00:00:00Z').",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPurchaseOrders'."]:
    """Retrieve purchase orders from Xero.

    Use this tool to obtain purchase orders from Xero. Call when you need a list of purchase orders with details such as order status, dates, and amounts."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders",
        method="GET",
        params=remove_none_values({
            "Status": filter_by_status,
            "DateFrom": filter_by_start_date,
            "DateTo": filter_by_end_date,
            "order": order_by_element,
            "page": page_number,
            "pageSize": records_per_page,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_purchase_order_pdf(
    context: ToolContext,
    purchase_order_id: Annotated[
        str, "Unique identifier for a purchase order to retrieve it as a PDF."
    ],
    tenant_identifier: Annotated[
        str,
        "The Xero identifier for the Tenant. Required to specify which tenant's data to access.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPurchaseOrderAsPdf'."]:
    """Retrieve a purchase order as a PDF using its ID.

    Use this tool to obtain a specific purchase order in PDF format by providing its unique ID. Useful for accessing purchase order details in a document format."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderID}/pdf".format(  # noqa: UP032
            PurchaseOrderID=purchase_order_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_purchase_order(
    context: ToolContext,
    purchase_order_id: Annotated[
        str,
        "Unique identifier for a purchase order. Required to retrieve specific purchase order details.",  # noqa: E501
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the tenant. This is required to specify which tenant's purchase order to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPurchaseOrder'."]:
    """Retrieve details of a specific purchase order by ID.

    Use this tool to obtain information about a particular purchase order by specifying its unique ID. Ideal for retrieving order details when managing inventory or processing transactions."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderID}".format(  # noqa: UP032
            PurchaseOrderID=purchase_order_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_purchase_order_by_number(
    context: ToolContext,
    purchase_order_number: Annotated[
        str, "Unique identifier for the purchase order to be fetched."
    ],
    xero_tenant_id: Annotated[
        str,
        "Unique identifier for the Xero tenant. Required to specify the account from which to retrieve the purchase order.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPurchaseOrderByNumber'."]:
    """Fetches a purchase order using its unique number.

    Use this tool to retrieve detailed information about a specific purchase order by providing its unique order number."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderNumber}".format(  # noqa: UP032
            PurchaseOrderNumber=purchase_order_number
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_purchase_order_history(
    context: ToolContext,
    purchase_order_id: Annotated[
        str, "Unique identifier for the purchase order to retrieve its history."
    ],
    tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant, required to specify which organization data belongs to.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPurchaseOrderHistory'."]:
    """Retrieve the history of a specific purchase order.

    Use this tool to obtain historical details for a specified purchase order by its ID. It provides insights into changes and updates made to the order over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderID}/History".format(  # noqa: UP032
            PurchaseOrderID=purchase_order_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_purchase_order_history(
    context: ToolContext,
    purchase_order_id: Annotated[
        str,
        "Unique identifier for a Purchase Order. Pass the specific ID for which a history record will be created.",  # noqa: E501
    ],
    tenant_identifier: Annotated[
        str, "The unique Xero identifier for the tenant. Required for API requests."
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique key to safely retry requests without duplicate processing; 128 character max.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createPurchaseOrderHistory'."]:
    """Create a history record for a purchase order.

    Use this tool to add a historical record to a specific purchase order when tracking changes or updates is necessary."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderID}/History".format(  # noqa: UP032
            PurchaseOrderID=purchase_order_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_purchase_order_attachments(
    context: ToolContext,
    purchase_order_id: Annotated[
        str, "Unique identifier for a purchase order to retrieve its attachments."
    ],
    xero_tenant_id: Annotated[
        str,
        "The unique Xero identifier for the tenant linked to the purchase order. Required to authenticate and access tenant-specific data.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPurchaseOrderAttachments'."]:
    """Retrieve attachments for a specific purchase order.

    This tool retrieves all attachments associated with a given purchase order in Xero. It should be called when you need to access or review files linked to a specific purchase order."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderID}/Attachments".format(  # noqa: UP032
            PurchaseOrderID=purchase_order_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def fetch_purchase_order_attachment(
    context: ToolContext,
    purchase_order_id: Annotated[
        str, "Unique identifier for a Purchase Order to retrieve a specific attachment."
    ],
    attachment_id: Annotated[str, "Unique identifier for the attachment object to be retrieved."],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the Tenant. This is required to specify which organization the request is for.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file to retrieve, e.g., image/jpg, application/pdf."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPurchaseOrderAttachmentById'."]:
    """Retrieve a specific attachment from a purchase order.

    Use this tool to obtain a specific attachment from a purchase order using the attachment's unique ID within the Xero platform."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            PurchaseOrderID=purchase_order_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_po_attachment_by_filename(
    context: ToolContext,
    purchase_order_id: Annotated[
        str, "Unique identifier for the purchase order you want to retrieve the attachment from."
    ],
    attachment_file_name: Annotated[
        str, "Name of the attachment file to be retrieved from the purchase order."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero unique identifier for the tenant organization. Required to specify which organization's data to retrieve.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file to retrieve, e.g., image/jpg or application/pdf."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getPurchaseOrderAttachmentByFileName'."
]:
    """Retrieve a purchase order attachment by filename.

    Use this tool to get a specific attachment from a purchase order in Xero by providing the filename. It's useful for accessing documents linked to purchase orders."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/PurchaseOrders/{PurchaseOrderID}/Attachments/{FileName}".format(  # noqa: UP032
            PurchaseOrderID=purchase_order_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_sales_quotes(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str, "Xero tenant identifier for accessing the specific account's data."
    ],
    filter_start_date: Annotated[
        str | None, "Filter quotes issued after a specified date in YYYY-MM-DD format."
    ] = None,
    filter_date_to: Annotated[
        str | None, "Filter for sales quotes before a specified date in YYYY-MM-DD format."
    ] = None,
    expiry_date_after: Annotated[
        str | None,
        "Filter to retrieve quotes expiring after the specified date. Format: YYYY-MM-DD.",
    ] = None,
    filter_expiry_date_before: Annotated[
        str | None, "Filter for quotes expiring before a specified date (YYYY-MM-DD)."
    ] = None,
    contact_id: Annotated[
        str | None, "Filter the sales quotes by specifying the contact ID to which they belong."
    ] = None,
    quote_status: Annotated[
        str | None, "Filter quotes by their status (e.g., DRAFT, SENT)."
    ] = None,
    page_number: Annotated[
        int | None,
        "The page number to retrieve, allowing pagination through quotes. Each page returns up to 100 quotes.",  # noqa: E501
    ] = None,
    order_by_element: Annotated[
        str | None, "Specify the element to order the sales quotes by."
    ] = None,
    quote_number_filter: Annotated[
        str | None, "Filter sales quotes by specifying the quote number (e.g., QU-0001)."
    ] = None,
    modified_since_timestamp: Annotated[
        str | None, "Retrieve records created or modified after this timestamp."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getQuotes'."]:
    """Retrieve sales quotes from Xero.

    This tool fetches sales quotes from Xero, providing details of quotes issued. Use it to obtain current sales quotations."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes",
        method="GET",
        params=remove_none_values({
            "DateFrom": filter_start_date,
            "DateTo": filter_date_to,
            "ExpiryDateFrom": expiry_date_after,
            "ExpiryDateTo": filter_expiry_date_before,
            "ContactID": contact_id,
            "Status": quote_status,
            "page": page_number,
            "order": order_by_element,
            "QuoteNumber": quote_number_filter,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_quote(
    context: ToolContext,
    quote_id: Annotated[str, "Unique identifier for a quote to retrieve its details."],
    xero_tenant_id: Annotated[
        str, "Provide the Xero identifier for the tenant to specify the account context."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getQuote'."]:
    """Retrieve details of a specific quote by ID.

    Call this tool to obtain detailed information about a specific quote using its unique QuoteID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes/{QuoteID}".format(QuoteID=quote_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_quote_history(
    context: ToolContext,
    quote_id: Annotated[str, "Unique identifier for the quote to retrieve its history records."],
    xero_tenant_identifier: Annotated[
        str,
        "The unique identifier for the Xero tenant. Required to specify which tenant's quote history to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getQuoteHistory'."]:
    """Retrieves history records of a specific quote.

    Use this tool to get the history records for a specific quote using its ID. Ideal for tracking changes and updates to the quote over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes/{QuoteID}/History".format(QuoteID=quote_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def add_quote_history(
    context: ToolContext,
    quote_identifier: Annotated[
        str, "Unique identifier for a quote to which the history will be added."
    ],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the tenant. Required for specifying the tenant within the Xero system.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "Unique key to safely retry requests and avoid duplicate processing (max 128 characters).",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createQuoteHistory'."]:
    """Creates a history record for a specific quote.

    Use this tool to add a history record to a specific quote in the Xero application. This is useful for tracking changes or updates made to a quote over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes/{QuoteID}/History".format(  # noqa: UP032
            QuoteID=quote_identifier
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_quote_pdf(
    context: ToolContext,
    quote_id: Annotated[str, "A unique identifier for the quote to retrieve as a PDF."],
    tenant_identifier: Annotated[
        str, "The unique Xero tenant identifier required to access the specific quote."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getQuoteAsPdf'."]:
    """Retrieve a specific quote as a PDF file using the quote ID.

    This tool fetches a specific quote as a PDF using its unique ID. Call this when you need to obtain the PDF version of a quote for viewing, sharing, or archiving."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes/{QuoteID}/pdf".format(QuoteID=quote_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_quote_attachments(
    context: ToolContext,
    quote_id: Annotated[str, "Unique identifier for a quote in Xero to retrieve its attachments."],
    tenant_identifier: Annotated[
        str, "The unique Xero tenant identifier required to retrieve the quote attachments."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getQuoteAttachments'."]:
    """Retrieve attachments for a specific quote in Xero.

    This tool retrieves all attachments related to a specified quote in Xero. It should be called when you need to access or view the files linked to a given quote ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes/{QuoteID}/Attachments".format(  # noqa: UP032
            QuoteID=quote_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_quote_attachment(
    context: ToolContext,
    quote_id: Annotated[
        str, "Unique identifier for a quote. Used to specify which quote the attachment belongs to."
    ],
    attachment_id: Annotated[
        str, "Unique identifier for the attachment object you wish to retrieve."
    ],
    xero_tenant_identifier: Annotated[
        str, "The unique Xero identifier for the tenant required to access the attachment."
    ],
    attachment_content_type: Annotated[
        str,
        "The MIME type of the attachment file to retrieve, such as image/jpeg or application/pdf.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getQuoteAttachmentById'."]:
    """Retrieve a specific attachment from a quote by ID.

    Use this tool to retrieve a specific attachment from a quote by providing the unique Quote ID and Attachment ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes/{QuoteID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            QuoteID=quote_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_content_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_quote_attachment_by_filename(
    context: ToolContext,
    quote_identifier: Annotated[
        str,
        "Unique identifier for a Quote. Use this to specify which quote's attachment you want to retrieve.",  # noqa: E501
    ],
    attachment_filename: Annotated[str, "Name of the attachment file to retrieve from the quote."],
    xero_tenant_identifier: Annotated[
        str, "Xero tenant's unique identifier. Required to specify which tenant's data to access."
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file (e.g., image/jpg, application/pdf)."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getQuoteAttachmentByFileName'."]:
    """Retrieve an attachment from a quote using filename.

    Call this tool to obtain a specific attachment from a quote by specifying the filename. Ideal for accessing quote-related documents stored in the Xero system."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Quotes/{QuoteID}/Attachments/{FileName}".format(  # noqa: UP032
            QuoteID=quote_identifier, FileName=attachment_filename
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_draft_expense_receipts(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for a Xero tenant. Used to specify which tenant's data to retrieve.",
    ],
    filter_condition: Annotated[
        str | None, "A string to filter draft expense receipts based on specified criteria."
    ] = None,
    order_receipts_by: Annotated[
        str | None,
        "Specify the attribute by which to order the receipts. For example, by date or amount.",
    ] = None,
    unit_decimal_places: Annotated[
        int | None,
        "Specifies the number of decimal places for unit amounts. For example, set to 4 for four decimal places.",  # noqa: E501
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "A timestamp to filter records updated or created since this date. Format should be in ISO 8601, e.g., '2023-10-10T00:00:00Z'.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReceipts'."]:
    """Retrieve draft expense claim receipts from Xero.

    This tool retrieves draft expense receipts for any user from Xero. It should be called when you need to access draft expense claims."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Receipts",
        method="GET",
        params=remove_none_values({
            "where": filter_condition,
            "order": order_receipts_by,
            "unitdp": unit_decimal_places,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_draft_expense_claim_receipt(
    context: ToolContext,
    receipt_id: Annotated[
        str, "The unique identifier for the draft expense claim receipt to retrieve."
    ],
    tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the tenant. Required to specify which organization's data is being accessed.",  # noqa: E501
    ],
    use_four_decimal_places: Annotated[
        int | None, "Set to true to use four decimal places for unit amounts, false for standard."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReceipt'."]:
    """Retrieve a draft expense claim receipt using its ID.

    Use this tool to retrieve detailed information about a specific draft expense claim receipt by providing its unique receipt ID. Useful for reviewing or processing draft receipts."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Receipts/{ReceiptID}".format(ReceiptID=receipt_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"unitdp": use_four_decimal_places}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_receipt_attachments(
    context: ToolContext,
    receipt_id: Annotated[
        str, "Unique identifier for the expense claim receipt to retrieve attachments."
    ],
    tenant_identifier: Annotated[
        str, "The unique Xero identifier for the tenant. Required to access tenant-specific data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReceiptAttachments'."]:
    """Retrieve attachments for a specific expense claim receipt.

    Use this tool to obtain all attachments related to a specific expense claim receipt by providing the receipt ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Receipts/{ReceiptID}/Attachments".format(  # noqa: UP032
            ReceiptID=receipt_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_receipt_attachment(
    context: ToolContext,
    receipt_id: Annotated[str, "Unique identifier for a receipt used to retrieve its attachment."],
    attachment_id: Annotated[
        str, "Unique identifier for the attachment object you want to retrieve."
    ],
    xero_tenant_id: Annotated[
        str, "Xero identifier for the Tenant. Required to specify which tenant's data to access."
    ],
    attachment_mime_type: Annotated[
        str, "Specify the MIME type of the attachment, e.g., 'image/jpg' or 'application/pdf'."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReceiptAttachmentById'."]:
    """Retrieve a specific attachment from an expense receipt.

    Use this tool to obtain a specific attachment from an expense claim receipt by providing the unique attachment ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Receipts/{ReceiptID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            ReceiptID=receipt_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def get_expense_receipt_attachment(
    context: ToolContext,
    receipt_id: Annotated[
        str,
        "The unique identifier for a specific expense receipt. This is used to locate the correct receipt attachment.",  # noqa: E501
    ],
    attachment_file_name: Annotated[
        str, "The name of the attachment to retrieve from the expense claim receipt."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Required to specify the organization context in Xero from which to retrieve the attachment.",  # noqa: E501
    ],
    attachment_mime_type: Annotated[
        str,
        "The MIME type of the attachment file, such as image/jpg or application/pdf, that you are retrieving from the receipt.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReceiptAttachmentByFileName'."]:
    """Retrieve an attachment from a receipt by file name.

    This tool retrieves a specific attachment from an expense claim receipt using the file name. It should be called when you need to access a specific attachment associated with a receipt in the Xero platform."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Receipts/{ReceiptID}/Attachments/{FileName}".format(  # noqa: UP032
            ReceiptID=receipt_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def retrieve_receipt_history(
    context: ToolContext,
    receipt_id: Annotated[str, "Unique identifier for the receipt to retrieve its history."],
    tenant_identifier: Annotated[
        str, "The unique Xero identifier for the tenant associated with the receipt."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReceiptHistory'."]:
    """Retrieve detailed history for a specific receipt.

    This tool retrieves the history record of a specific receipt from the Xero service. It should be called when users want to review or analyze the history or changes associated with a receipt."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Receipts/{ReceiptID}/History".format(  # noqa: UP032
            ReceiptID=receipt_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def record_receipt_history(
    context: ToolContext,
    receipt_id: Annotated[str, "Unique identifier for a receipt used to create a history record."],
    tenant_identifier: Annotated[
        str, "Xero tenant identifier required for creating the receipt history."
    ],
    idempotency_key: Annotated[
        str | None,
        "String up to 128 characters to safely retry requests without risk of duplication.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createReceiptHistory'."]:
    """Creates a history record for a specific receipt."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Receipts/{ReceiptID}/History".format(  # noqa: UP032
            ReceiptID=receipt_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_repeating_invoices(
    context: ToolContext,
    tenant_identifier: Annotated[
        str,
        "The unique identifier for the tenant in Xero. Required to retrieve specific tenant data.",
    ],
    filter_by_element: Annotated[
        str | None,
        "Filter invoices using a specific element condition. Use Xero's query language for filtering expressions.",  # noqa: E501
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specify the element to order the repeating invoices by. It accepts a string indicating the element to sort by.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRepeatingInvoices'."]:
    """Retrieve repeating invoices from Xero.

    Use this tool to get a list of repeating invoices from the Xero platform. It is helpful for managing and reviewing recurring billing information."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/RepeatingInvoices",
        method="GET",
        params=remove_none_values({"where": filter_by_element, "order": order_by_element}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_repeating_invoice(
    context: ToolContext,
    repeating_invoice_id: Annotated[
        str, "Unique identifier for the specific repeating invoice to retrieve."
    ],
    tenant_id: Annotated[
        str, "Xero tenant identifier required to access a specific tenant's data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRepeatingInvoice'."]:
    """Retrieve a specific repeating invoice using its unique ID.

    Use this tool to retrieve detailed information about a specific repeating invoice by providing its unique ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/RepeatingInvoices/{RepeatingInvoiceID}".format(  # noqa: UP032
            RepeatingInvoiceID=repeating_invoice_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_repeating_invoice_attachments(
    context: ToolContext,
    repeating_invoice_id: Annotated[
        str,
        "Unique identifier for a repeating invoice in Xero. Needed to retrieve the corresponding attachments.",  # noqa: E501
    ],
    xero_tenant_identifier: Annotated[
        str, "A unique identifier for the Xero tenant. Required to access specific tenant data."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRepeatingInvoiceAttachments'."]:
    """Retrieve attachments from a specified repeating invoice.

    This tool retrieves attachments from a specific repeating invoice in Xero. Use it to access files associated with recurring invoices."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/RepeatingInvoices/{RepeatingInvoiceID}/Attachments".format(  # noqa: UP032
            RepeatingInvoiceID=repeating_invoice_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_repeating_invoice_attachment_by_id(
    context: ToolContext,
    repeating_invoice_id: Annotated[
        str, "Unique identifier for a Repeating Invoice in Xero system."
    ],
    attachment_id: Annotated[
        str,
        "Unique identifier for the attachment object you want to retrieve from the repeating invoice.",  # noqa: E501
    ],
    xero_tenant_identifier: Annotated[
        str, "Xero identifier for the tenant needed to retrieve the repeating invoice attachment."
    ],
    attachment_mime_type: Annotated[
        str, "The MIME type of the attachment file, such as image/jpg or application/pdf."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getRepeatingInvoiceAttachmentById'."
]:
    """Retrieve a specific attachment from a repeating invoice.

    Use this tool to get a particular attachment from a specific repeating invoice in Xero."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/RepeatingInvoices/{RepeatingInvoiceID}/Attachments/{AttachmentID}".format(  # noqa: UP032
            RepeatingInvoiceID=repeating_invoice_id, AttachmentID=attachment_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.attachments", "accounting.attachments.read"]
    )
)
async def retrieve_repeating_invoice_attachment(
    context: ToolContext,
    repeating_invoice_id: Annotated[
        str,
        "Unique identifier for a specific repeating invoice. This is necessary to locate the invoice attachment.",  # noqa: E501
    ],
    attachment_file_name: Annotated[
        str, "The name of the attachment file you wish to retrieve from the repeating invoice."
    ],
    xero_tenant_identifier: Annotated[
        str, "Xero tenant ID needed to identify the specific organization in Xero."
    ],
    attachment_mime_type: Annotated[
        str,
        "Specify the MIME type of the attachment file to retrieve, such as image/jpg or application/pdf.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getRepeatingInvoiceAttachmentByFileName'."
]:
    """Retrieve a repeating invoice attachment by file name.

    Use this tool to obtain a specific attachment from a repeating invoice using the file name. Ideal for accessing invoice-related files directly from the system."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/RepeatingInvoices/{RepeatingInvoiceID}/Attachments/{FileName}".format(  # noqa: UP032
            RepeatingInvoiceID=repeating_invoice_id, FileName=attachment_file_name
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "contentType": attachment_mime_type,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.transactions.read", "accounting.transactions"]
    )
)
async def get_repeating_invoice_history(
    context: ToolContext,
    repeating_invoice_id: Annotated[
        str, "Unique identifier for the specific repeating invoice to retrieve history for."
    ],
    xero_tenant_id: Annotated[
        str, "The unique identifier for the Xero tenant associated with the repeating invoice."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRepeatingInvoiceHistory'."]:
    """Retrieve history record for a specific repeating invoice.

    Use this tool to access the historical details of a specified repeating invoice. Ideal for understanding past changes, updates, or notes associated with the invoice in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/RepeatingInvoices/{RepeatingInvoiceID}/History".format(  # noqa: UP032
            RepeatingInvoiceID=repeating_invoice_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.transactions"]))
async def create_repeating_invoice_history(
    context: ToolContext,
    repeating_invoice_id: Annotated[
        str, "Unique identifier for a Repeating Invoice to create a history record."
    ],
    tenant_identifier: Annotated[
        str, "Xero identifier for the tenant, required for accessing specific tenant data."
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string, max 128 characters, to safely retry requests without duplication.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createRepeatingInvoiceHistory'."]:
    """Creates a history record for a repeating invoice.

    Use this tool to create a history record for a specific repeating invoice in the Xero system. This is useful for maintaining a log of actions or updates associated with the invoice."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/RepeatingInvoices/{RepeatingInvoiceID}/History".format(  # noqa: UP032
            RepeatingInvoiceID=repeating_invoice_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero",
        scopes=["accounting.reports.tenninetynine.read", "accounting.reports.read"],
    )
)
async def retrieve1099_reports(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "The unique identifier for the tenant in Xero. Required to access the specific tenant's 1099 report data.",  # noqa: E501
    ],
    report_year: Annotated[
        str | None, "The year for which the 1099 report should be retrieved, in YYYY format."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportTenNinetyNine'."]:
    """Retrieves 1099 tax reports.

    Use this tool to obtain 1099 tax reports from the Xero accounting service. It provides necessary financial data related to 1099 forms."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/TenNinetyNine",
        method="GET",
        params=remove_none_values({"reportYear": report_year}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def get_aged_payables_report_by_contact(
    context: ToolContext,
    contact_identifier: Annotated[
        str, "Unique identifier for the contact to retrieve the aged payables report."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Required to specify which tenant's data is being accessed.",  # noqa: E501
    ],
    report_date: Annotated[
        str | None,
        "The specific date for the Aged Payables By Contact report in YYYY-MM-DD format.",
    ] = None,
    report_from_date: Annotated[
        str | None,
        "Specify the start date for filtering the report, in YYYY-MM-DD format (e.g. 2021-02-01).",
    ] = None,
    report_end_date: Annotated[
        str | None,
        "Filter the report by specifying the end date, formatted as YYYY-MM-DD (e.g., 2021-02-28).",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportAgedPayablesByContact'."]:
    """Retrieve aged payables report by contact.

    Use this tool to get a report on aged payables categorized by contact. It provides insights into outstanding payables over time."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/AgedPayablesByContact",
        method="GET",
        params=remove_none_values({
            "contactId": contact_identifier,
            "date": report_date,
            "fromDate": report_from_date,
            "toDate": report_end_date,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def get_aged_receivables_report_by_contact(
    context: ToolContext,
    contact_identifier: Annotated[
        str, "Unique identifier for a Contact to retrieve their aged receivables report."
    ],
    tenant_identifier: Annotated[
        str,
        "Unique Xero identifier for the Tenant. Required to specify which tenant's data to retrieve.",  # noqa: E501
    ],
    report_date: Annotated[
        str | None,
        "The specific date for which the aged receivables report by contact is generated.",
    ] = None,
    start_date_filter: Annotated[
        str | None, "Filter the report starting from this date (YYYY-MM-DD)."
    ] = None,
    filter_by_to_date: Annotated[
        str | None,
        "Specify the end date for filtering the aged receivables report, e.g., '2021-02-28'.",
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getReportAgedReceivablesByContact'."
]:
    """Retrieve aged receivables report by contact.

    Use this tool to get a detailed report of aged receivables, organized by contact, which helps in assessing outstanding debts for each contact."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/AgedReceivablesByContact",
        method="GET",
        params=remove_none_values({
            "contactId": contact_identifier,
            "date": report_date,
            "fromDate": start_date_filter,
            "toDate": filter_by_to_date,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def get_balance_sheet_report(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the Tenant. Used to specify which organization's data to retrieve in Xero.",  # noqa: E501
    ],
    report_date: Annotated[
        str | None,
        "The specific date for which to retrieve the Balance Sheet report. Format as YYYY-MM-DD.",
    ] = None,
    number_of_periods: Annotated[
        int | None, "The number of periods to include in the Balance Sheet report."
    ] = None,
    comparison_timeframe: Annotated[
        str | None, "The period size for comparison, e.g., MONTH, QUARTER, or YEAR."
    ] = None,
    balance_sheet_tracking_option_id_1: Annotated[
        str | None, "The first tracking option ID for generating the Balance Sheet report in Xero."
    ] = None,
    tracking_option_id_2: Annotated[
        str | None,
        "The tracking option ID for secondary categorization in the Balance Sheet report. This allows for filtering or segmentation based on a second tracking category within Xero.",  # noqa: E501
    ] = None,
    use_standard_layout: Annotated[
        bool | None, "Set to true to use the standard layout for the Balance Sheet report in Xero."
    ] = None,
    return_cash_basis: Annotated[
        bool | None, "Set to True to return the Balance Sheet report using a cash basis."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportBalanceSheet'."]:
    """Retrieve the balance sheet report from Xero.

    Fetches the balance sheet report, detailing financial positions. Useful for obtaining up-to-date financial summaries."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/BalanceSheet",
        method="GET",
        params=remove_none_values({
            "date": report_date,
            "periods": number_of_periods,
            "timeframe": comparison_timeframe,
            "trackingOptionID1": balance_sheet_tracking_option_id_1,
            "trackingOptionID2": tracking_option_id_2,
            "standardLayout": use_standard_layout,
            "paymentsOnly": return_cash_basis,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def get_bank_summary_report(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str,
        "Unique identifier for the Xero tenant. Required for accessing the relevant account data.",
    ],
    start_date_filter: Annotated[
        str | None,
        "Filter the report by the starting date, formatted as YYYY-MM-DD. For example, 2021-02-01.",
    ] = None,
    end_date_filter: Annotated[
        str | None, "Filter the report by the end date, formatted as YYYY-MM-DD, e.g., 2021-02-28."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportBankSummary'."]:
    """Retrieve bank summary reports from Xero.

    This tool fetches a bank summary report, providing a detailed overview of bank transactions and balances. Use it when you need to review financial summaries from Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/BankSummary",
        method="GET",
        params=remove_none_values({"fromDate": start_date_filter, "toDate": end_date_filter}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def retrieve_specific_report(
    context: ToolContext,
    report_id: Annotated[str, "Unique identifier for a specific report to be retrieved."],
    xero_tenant_id: Annotated[
        str,
        "Xero identifier for the Tenant. This is required to specify which tenant's data is being accessed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportFromId'."]:
    """Retrieve a specific report using a ReportID.

    This tool fetches a specific report from Xero using a unique ReportID. It should be called when detailed information about a particular report is needed."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/{ReportID}".format(ReportID=report_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def get_budget_summary_report(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "The unique Xero identifier for the tenant, required for authentication and data retrieval.",  # noqa: E501
    ],
    report_date: Annotated[
        str | None,
        "The specific date for the budget summary report in YYYY-MM-DD format, e.g., 2018-03-31.",
    ] = None,
    number_of_periods_to_compare: Annotated[
        int | None, "The number of periods for comparison, must be an integer between 1 and 12."
    ] = None,
    comparison_timeframe: Annotated[
        int | None,
        "Specify the period size for comparison: 1 for month, 3 for quarter, or 12 for year.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportBudgetSummary'."]:
    """Retrieves the budget summary report from Xero.

    This tool calls the Xero endpoint to obtain a detailed budget summary report. Use this when a financial summary of budget allocations is required."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/BudgetSummary",
        method="GET",
        params=remove_none_values({
            "date": report_date,
            "periods": number_of_periods_to_compare,
            "timeframe": comparison_timeframe,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def retrieve_executive_summary_report(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "The Xero identifier for the tenant. Required to specify which tenant's data should be retrieved.",  # noqa: E501
    ],
    report_date: Annotated[
        str | None,
        "The date for the Bank Summary report in the format YYYY-MM-DD (e.g., 2018-03-31).",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportExecutiveSummary'."]:
    """Retrieve an executive summary report for financial insights.

    Use this tool to get an executive summary report, which provides financial insights and key metrics for business decision-making."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/ExecutiveSummary",
        method="GET",
        params=remove_none_values({"date": report_date}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def retrieve_unique_reports_list(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str, "The unique identifier for the Xero tenant to retrieve reports for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsList'."]:
    """Retrieve a list of unique reports from Xero.

    Use this tool to obtain a list of an organization's unique reports from Xero, each requiring a UUID for fetching."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def get_profit_and_loss_report(
    context: ToolContext,
    tenant_identifier: Annotated[
        str,
        "The Xero identifier for the tenant. Required to specify which tenant's data to access.",
    ],
    from_date: Annotated[
        str | None, "Filter the report by the starting date in YYYY-MM-DD format, e.g., 2021-02-01."
    ] = None,
    end_date: Annotated[
        str | None, "Filter by the end date of the report in YYYY-MM-DD format, e.g., 2021-02-28."
    ] = None,
    number_of_comparison_periods: Annotated[
        int | None, "The number of periods to compare, must be an integer between 1 and 12."
    ] = None,
    comparison_timeframe: Annotated[
        str | None,
        "The period size to compare to for the report. Options are MONTH, QUARTER, or YEAR.",
    ] = None,
    tracking_category_id: Annotated[
        str | None,
        "The first tracking category ID for the Profit and Loss report filter. Expect a string representing the tracking category identifier.",  # noqa: E501
    ] = None,
    secondary_tracking_category_id: Annotated[
        str | None, "The ID of the second tracking category for the Profit and Loss report."
    ] = None,
    tracking_option_1_id: Annotated[
        str | None, "The identifier for the first tracking option in the Profit and Loss report."
    ] = None,
    tracking_option_id_2: Annotated[
        str | None,
        "The second tracking option identifier for filtering the Profit and Loss report.",
    ] = None,
    return_standard_layout: Annotated[
        bool | None, "Set to true to return the Profit and Loss report in the standard layout."
    ] = None,
    return_cash_basis_only: Annotated[
        bool | None, "Specify true to return the Profit and Loss report on a cash only basis."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportProfitAndLoss'."]:
    """Retrieve profit and loss report from Xero.

    Call this tool to obtain detailed profit and loss reports for financial analysis."""
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/ProfitAndLoss",
        method="GET",
        params=remove_none_values({
            "fromDate": from_date,
            "toDate": end_date,
            "periods": number_of_comparison_periods,
            "timeframe": comparison_timeframe,
            "trackingCategoryID": tracking_category_id,
            "trackingCategoryID2": secondary_tracking_category_id,
            "trackingOptionID": tracking_option_1_id,
            "trackingOptionID2": tracking_option_id_2,
            "standardLayout": return_standard_layout,
            "paymentsOnly": return_cash_basis_only,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.reports.read"]))
async def get_trial_balance_report(
    context: ToolContext,
    tenant_identifier: Annotated[
        str, "The unique identifier for the Xero tenant to retrieve the trial balance report for."
    ],
    report_date: Annotated[
        str | None, "The specific date for the Trial Balance report in YYYY-MM-DD format."
    ] = None,
    return_cash_basis_only: Annotated[
        bool | None,
        "Set to true to return the trial balance report on a cash-only basis, false for accrual.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportTrialBalance'."]:
    """Fetches the trial balance report from Xero.

    Use this tool to retrieve the trial balance report, which provides detailed financial information."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Reports/TrialBalance",
        method="GET",
        params=remove_none_values({"date": report_date, "paymentsOnly": return_cash_basis_only}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.settings"]))
async def set_financial_setup(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str, "Xero tenant ID required to identify the specific tenant for the request."
    ],
    financial_setup_details: Annotated[
        dict[
            str,
            dict[str, int]
            | list[dict[str, bool | str | list[dict[str, str]]]]
            | list[dict[str, float | str | list[dict[str, float | str]]]],
        ],
        "JSON object containing accounts, conversion balances, and a conversion date for setting up the financial chart in Xero.",  # noqa: E501
    ],
    idempotency_key: Annotated[
        str | None,
        "A unique string up to 128 characters to safely retry requests without duplicating processing.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postSetup'."]:
    """Sets up the financial chart of accounts and conversion details.

    Use this tool to set up the chart of accounts, conversion date, and conversion balances in Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Setup",
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Idempotency-Key": idempotency_key,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({"requestBody": financial_setup_details}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_tax_rates(
    context: ToolContext,
    xero_tenant_id: Annotated[
        str,
        "A unique identifier for the Xero tenant. This is required to access tenant-specific data.",
    ],
    filter_by_element: Annotated[
        str | None,
        "Apply a filter to the tax rates by specifying an element condition (e.g. 'Status==\"ACTIVE\"').",  # noqa: E501
    ] = None,
    order_by_element: Annotated[
        str | None,
        "Specify the element to order the tax rates by. Provide any valid field or attribute name.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTaxRates'."]:
    """Retrieve tax rates from Xero.

    Use this tool to obtain the current tax rates available in Xero. It should be called when you need up-to-date tax rate information for financial calculations or reporting."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/TaxRates",
        method="GET",
        params=remove_none_values({"where": filter_by_element, "order": order_by_element}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_tax_rate_by_tax_type(
    context: ToolContext,
    tax_type_code: Annotated[str, "A valid TaxType code used to retrieve the specific tax rate."],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. Required to specify which tenant's data is being accessed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTaxRateByTaxType'."]:
    """Retrieve a specific tax rate using a TaxType code.

    Use this tool to obtain a particular tax rate by providing a specific TaxType code. It is useful for retrieving tax rates in financial calculations or reports."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/TaxRates/{TaxType}".format(TaxType=tax_type_code),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_tracking_categories(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "Unique identifier for the Xero tenant. Required to specify the tenant from which tracking categories should be retrieved.",  # noqa: E501
    ],
    filter_conditions: Annotated[
        str | None, "String to filter tracking categories by specific conditions."
    ] = None,
    order_by_element: Annotated[
        str | None, "Specify the element to order the tracking categories and options by."
    ] = None,
    include_archived_categories: Annotated[
        bool | None,
        "Set to true to include categories and options with a status of ARCHIVED in the response.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTrackingCategories'."]:
    """Retrieve tracking categories and options from Xero.

    Use this tool to get tracking categories and their options from Xero. Useful for financial tracking and categorization tasks."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/TrackingCategories",
        method="GET",
        params=remove_none_values({
            "where": filter_conditions,
            "order": order_by_element,
            "includeArchived": include_archived_categories,
        }),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def get_tracking_category(
    context: ToolContext,
    tracking_category_id: Annotated[
        str, "Unique identifier for the tracking category to retrieve details for."
    ],
    xero_tenant_id: Annotated[
        str,
        "A string representing the Xero identifier for the tenant. Required to access tenant-specific data.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTrackingCategory'."]:
    """Retrieve tracking category details using its unique ID.

    Use this tool to obtain specific details about a tracking category and its options by providing a unique tracking category ID."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackingCategoryID}".format(  # noqa: UP032
            TrackingCategoryID=tracking_category_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.settings"]))
async def remove_tracking_category(
    context: ToolContext,
    tracking_category_id: Annotated[
        str, "Unique identifier for the tracking category to be deleted in Xero."
    ],
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the tenant. Required to specify which tenant's tracking category to delete.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTrackingCategory'."]:
    """Deletes a specific tracking category from Xero.

    Use this tool to delete a particular tracking category identified by its ID in the Xero accounting system."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackingCategoryID}".format(  # noqa: UP032
            TrackingCategoryID=tracking_category_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.settings"]))
async def delete_tracking_option(
    context: ToolContext,
    tracking_category_id: Annotated[
        str,
        "Unique identifier for the tracking category to specify which category the option will be deleted from.",  # noqa: E501
    ],
    tracking_option_id: Annotated[
        str, "Unique identifier for a tracking option to be deleted in Xero."
    ],
    xero_tenant_id: Annotated[
        str,
        "The unique identifier for a Xero tenant. This specifies which tenant's data will be affected.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTrackingOptions'."]:
    """Deletes a specific tracking category option in Xero.

    Use this tool to delete a specific tracking option from a selected tracking category in Xero. Useful for managing and updating your tracking categories when certain options are no longer needed."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackingCategoryID}/Options/{TrackingOptionID}".format(  # noqa: UP032
            TrackingCategoryID=tracking_category_id, TrackingOptionID=tracking_option_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_id,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_xero_users(
    context: ToolContext,
    xero_tenant_identifier: Annotated[
        str,
        "Xero identifier for the specific tenant. This is required to specify the tenant for which users are to be retrieved.",  # noqa: E501
    ],
    filter_by_criteria: Annotated[
        str | None, "A string to filter users based on specific criteria in Xero."
    ] = None,
    order_by_element: Annotated[
        str | None, "Specify the element to order the retrieved users by, such as name or date."
    ] = None,
    modified_since_timestamp: Annotated[
        str | None,
        "Return only records created or modified since this timestamp, formatted as an ISO 8601 string.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUsers'."]:
    """Retrieve users from the Xero platform.

    Call this tool to fetch a list of users from the Xero platform when user information or management is required."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Users",
        method="GET",
        params=remove_none_values({"where": filter_by_criteria, "order": order_by_element}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "If-Modified-Since": modified_since_timestamp,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(
    requires_auth=OAuth2(
        id="arcade-xero", scopes=["accounting.settings", "accounting.settings.read"]
    )
)
async def retrieve_specific_user(
    context: ToolContext,
    user_identifier: Annotated[str, "Unique identifier for a User in Xero system."],
    xero_tenant_identifier: Annotated[
        str, "Xero identifier for the Tenant. Use this to specify which tenant the user belongs to."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUser'."]:
    """Retrieve details of a specific user from Xero.

    Use this tool to obtain information about a specific user by providing their UserID. It is called when user details from Xero are needed."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/api.xro/2.0/Users/{UserID}".format(UserID=user_identifier),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/json",
            "xero-tenant-id": xero_tenant_identifier,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero", scopes=["accounting.settings.read"]))
async def get_connected_tenants(
    context: ToolContext,
    filter_auth_event_id: Annotated[
        str | None,
        "A string used to filter the results by a specific authEventId, narrowing down the connections returned.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getConnections'."]:
    """Fetch active Tenants connections from Xero organization.

    Use this tool to retrieve a list of active connections associated with your Xero organization. It should be called when verifying or reviewing the connections currently established with Xero."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/Connections",
        method="GET",
        params=remove_none_values({"authEventId": filter_auth_event_id}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-xero"))
async def delete_tenant_connection(
    context: ToolContext,
    tenant_connection_id: Annotated[
        str, "Unique identifier for the Xero connection to be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteConnection'."]:
    """Delete a specified Xero connection using its ID.

    This tool is used to delete a connection from the Xero platform by specifying the connection ID. It should be called when a user wants to remove a particular connection from their Xero account."""  # noqa: E501
    response = await make_request(
        url="https://api.xero.com/Connections/{id}".format(id=tenant_connection_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}
