"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from apideck_unify import models, utils
from apideck_unify._hooks import HookContext
from apideck_unify.types import Nullable, OptionalNullable, UNSET
from apideck_unify.utils import get_security_from_env
from apideck_unify.utils.unmarshal_json_response import unmarshal_json_response
from datetime import date
from jsonpath import JSONPath
from typing import Any, Dict, List, Mapping, Optional, Union


class Projects(BaseSDK):
    def list(
        self,
        *,
        raw: Optional[bool] = False,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        filter_: Optional[
            Union[models.ProjectsFilter, models.ProjectsFilterTypedDict]
        ] = None,
        sort: Optional[Union[models.ProjectsSort, models.ProjectsSortTypedDict]] = None,
        pass_through: Optional[Dict[str, Any]] = None,
        fields: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.AccountingProjectsAllResponse]:
        r"""List projects

        List projects

        :param raw: Include raw response. Mostly used for debugging purposes
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param cursor: Cursor to start from. You can find cursors for next/previous pages in the meta.cursors property of the response.
        :param limit: Number of results to return. Minimum 1, Maximum 200, Default 20
        :param filter_: Apply filters
        :param sort: Apply sorting
        :param pass_through: Optional unmapped key/values that will be passed through to downstream as query parameters. Ie: ?pass_through[search]=leads becomes ?search=leads
        :param fields: The 'fields' parameter allows API users to specify the fields they want to include in the API response. If this parameter is not present, the API will return all available fields. If this parameter is present, only the fields specified in the comma-separated string will be included in the response. Nested properties can also be requested by using a dot notation. <br /><br />Example: `fields=name,email,addresses.city`<br /><br />In the example above, the response will only include the fields \"name\", \"email\" and \"addresses.city\". If any other fields are available, they will be excluded.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsAllRequest(
            raw=raw,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            cursor=cursor,
            limit=limit,
            filter_=utils.get_pydantic_model(filter_, Optional[models.ProjectsFilter]),
            sort=utils.get_pydantic_model(sort, Optional[models.ProjectsSort]),
            pass_through=pass_through,
            fields=fields,
        )

        req = self._build_request(
            method="GET",
            path="/accounting/projects",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsAllGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsAll",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.AccountingProjectsAllResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])
            next_cursor = JSONPath("$.meta.cursors.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.list(
                raw=raw,
                consumer_id=consumer_id,
                app_id=app_id,
                service_id=service_id,
                cursor=next_cursor,
                limit=limit,
                filter_=filter_,
                sort=sort,
                pass_through=pass_through,
                fields=fields,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsAllResponse(
                get_projects_response=unmarshal_json_response(
                    Optional[models.GetProjectsResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsAllResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )

        raise models.APIError("Unexpected response received", http_res)

    async def list_async(
        self,
        *,
        raw: Optional[bool] = False,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        filter_: Optional[
            Union[models.ProjectsFilter, models.ProjectsFilterTypedDict]
        ] = None,
        sort: Optional[Union[models.ProjectsSort, models.ProjectsSortTypedDict]] = None,
        pass_through: Optional[Dict[str, Any]] = None,
        fields: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.AccountingProjectsAllResponse]:
        r"""List projects

        List projects

        :param raw: Include raw response. Mostly used for debugging purposes
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param cursor: Cursor to start from. You can find cursors for next/previous pages in the meta.cursors property of the response.
        :param limit: Number of results to return. Minimum 1, Maximum 200, Default 20
        :param filter_: Apply filters
        :param sort: Apply sorting
        :param pass_through: Optional unmapped key/values that will be passed through to downstream as query parameters. Ie: ?pass_through[search]=leads becomes ?search=leads
        :param fields: The 'fields' parameter allows API users to specify the fields they want to include in the API response. If this parameter is not present, the API will return all available fields. If this parameter is present, only the fields specified in the comma-separated string will be included in the response. Nested properties can also be requested by using a dot notation. <br /><br />Example: `fields=name,email,addresses.city`<br /><br />In the example above, the response will only include the fields \"name\", \"email\" and \"addresses.city\". If any other fields are available, they will be excluded.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsAllRequest(
            raw=raw,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            cursor=cursor,
            limit=limit,
            filter_=utils.get_pydantic_model(filter_, Optional[models.ProjectsFilter]),
            sort=utils.get_pydantic_model(sort, Optional[models.ProjectsSort]),
            pass_through=pass_through,
            fields=fields,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounting/projects",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsAllGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsAll",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.AccountingProjectsAllResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])
            next_cursor = JSONPath("$.meta.cursors.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.list(
                raw=raw,
                consumer_id=consumer_id,
                app_id=app_id,
                service_id=service_id,
                cursor=next_cursor,
                limit=limit,
                filter_=filter_,
                sort=sort,
                pass_through=pass_through,
                fields=fields,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsAllResponse(
                get_projects_response=unmarshal_json_response(
                    Optional[models.GetProjectsResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsAllResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )

        raise models.APIError("Unexpected response received", http_res)

    def create(
        self,
        *,
        name: str,
        raw: Optional[bool] = False,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        display_id: OptionalNullable[str] = UNSET,
        reference_id: OptionalNullable[str] = UNSET,
        description: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.ProjectProjectStatus] = UNSET,
        active: OptionalNullable[bool] = UNSET,
        project_type: OptionalNullable[models.ProjectType] = UNSET,
        priority: OptionalNullable[models.Priority] = UNSET,
        completion_percentage: OptionalNullable[float] = UNSET,
        start_date: OptionalNullable[date] = UNSET,
        end_date: OptionalNullable[date] = UNSET,
        customer: OptionalNullable[
            Union[models.LinkedCustomerInput, models.LinkedCustomerInputTypedDict]
        ] = UNSET,
        department: OptionalNullable[
            Union[models.ProjectDepartment, models.ProjectDepartmentTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        owner_id: OptionalNullable[str] = UNSET,
        parent_project: OptionalNullable[
            Union[models.ParentProject, models.ParentProjectTypedDict]
        ] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        budget_amount: OptionalNullable[float] = UNSET,
        approved_amount: OptionalNullable[float] = UNSET,
        budget_hours: OptionalNullable[float] = UNSET,
        hourly_rate: OptionalNullable[float] = UNSET,
        billing_method: OptionalNullable[models.BillingMethod] = UNSET,
        is_billable: OptionalNullable[bool] = True,
        phase: OptionalNullable[models.ProjectPhase] = UNSET,
        tax_rate: Optional[
            Union[models.LinkedTaxRateInput, models.LinkedTaxRateInputTypedDict]
        ] = None,
        tracking_categories: OptionalNullable[
            Union[
                List[Nullable[models.LinkedTrackingCategory]],
                List[Nullable[models.LinkedTrackingCategoryTypedDict]],
            ]
        ] = UNSET,
        tags: Optional[List[str]] = None,
        notes: OptionalNullable[str] = UNSET,
        contract_number: OptionalNullable[str] = UNSET,
        profit_margin: OptionalNullable[float] = UNSET,
        schedule_status: OptionalNullable[models.ScheduleStatus] = UNSET,
        addresses: Optional[
            Union[List[models.Address], List[models.AddressTypedDict]]
        ] = None,
        team_size: OptionalNullable[int] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        row_version: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsAddResponse:
        r"""Create project

        Create project

        :param name: Name of the project
        :param raw: Include raw response. Mostly used for debugging purposes
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param display_id: User-friendly project identifier
        :param reference_id: External reference identifier for the project
        :param description: Detailed description of the project
        :param status: Current status of the project
        :param active: Indicates whether the project is currently active or inactive
        :param project_type: Type or category of the project
        :param priority: Priority level of the project
        :param completion_percentage: Percentage of project completion (0-100)
        :param start_date: Start date of the project
        :param end_date: Expected or actual end date of the project
        :param customer: The customer this entity is linked to.
        :param department: Department or organizational unit associated with the project
        :param company_id: The company ID the transaction belongs to
        :param owner_id: ID of the user who owns/manages this project
        :param parent_project: Parent project if this is a subproject
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param budget_amount: Total budgeted amount for the project
        :param approved_amount: Approved budget amount for the project
        :param budget_hours: Total budgeted hours for the project
        :param hourly_rate: Default hourly rate for project work
        :param billing_method: Method used for billing this project
        :param is_billable: Indicates if the project is billable to the customer
        :param phase: Current phase of the project lifecycle
        :param tax_rate:
        :param tracking_categories: A list of linked tracking categories.
        :param tags: Tags associated with the project
        :param notes: Additional notes about the project
        :param contract_number: Contract or agreement number associated with the project
        :param profit_margin: Expected profit margin percentage for the project
        :param schedule_status: Current status of project schedule compared to plan
        :param addresses: An array of addresses associated with the project (billing, job site, etc.)
        :param team_size: Number of team members assigned to the project
        :param custom_fields:
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsAddRequest(
            raw=raw,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            project=models.ProjectInput(
                name=name,
                display_id=display_id,
                reference_id=reference_id,
                description=description,
                status=status,
                active=active,
                project_type=project_type,
                priority=priority,
                completion_percentage=completion_percentage,
                start_date=start_date,
                end_date=end_date,
                customer=utils.get_pydantic_model(
                    customer, OptionalNullable[models.LinkedCustomerInput]
                ),
                department=utils.get_pydantic_model(
                    department, OptionalNullable[models.ProjectDepartment]
                ),
                company_id=company_id,
                owner_id=owner_id,
                parent_project=utils.get_pydantic_model(
                    parent_project, OptionalNullable[models.ParentProject]
                ),
                currency=currency,
                budget_amount=budget_amount,
                approved_amount=approved_amount,
                budget_hours=budget_hours,
                hourly_rate=hourly_rate,
                billing_method=billing_method,
                is_billable=is_billable,
                phase=phase,
                tax_rate=utils.get_pydantic_model(
                    tax_rate, Optional[models.LinkedTaxRateInput]
                ),
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[Nullable[models.LinkedTrackingCategory]]],
                ),
                tags=tags,
                notes=notes,
                contract_number=contract_number,
                profit_margin=profit_margin,
                schedule_status=schedule_status,
                addresses=utils.get_pydantic_model(
                    addresses, Optional[List[models.Address]]
                ),
                team_size=team_size,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                row_version=row_version,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/accounting/projects",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsAddGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.project, False, False, "json", models.ProjectInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsAdd",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.AccountingProjectsAddResponse(
                create_project_response=unmarshal_json_response(
                    Optional[models.CreateProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsAddResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)

    async def create_async(
        self,
        *,
        name: str,
        raw: Optional[bool] = False,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        display_id: OptionalNullable[str] = UNSET,
        reference_id: OptionalNullable[str] = UNSET,
        description: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.ProjectProjectStatus] = UNSET,
        active: OptionalNullable[bool] = UNSET,
        project_type: OptionalNullable[models.ProjectType] = UNSET,
        priority: OptionalNullable[models.Priority] = UNSET,
        completion_percentage: OptionalNullable[float] = UNSET,
        start_date: OptionalNullable[date] = UNSET,
        end_date: OptionalNullable[date] = UNSET,
        customer: OptionalNullable[
            Union[models.LinkedCustomerInput, models.LinkedCustomerInputTypedDict]
        ] = UNSET,
        department: OptionalNullable[
            Union[models.ProjectDepartment, models.ProjectDepartmentTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        owner_id: OptionalNullable[str] = UNSET,
        parent_project: OptionalNullable[
            Union[models.ParentProject, models.ParentProjectTypedDict]
        ] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        budget_amount: OptionalNullable[float] = UNSET,
        approved_amount: OptionalNullable[float] = UNSET,
        budget_hours: OptionalNullable[float] = UNSET,
        hourly_rate: OptionalNullable[float] = UNSET,
        billing_method: OptionalNullable[models.BillingMethod] = UNSET,
        is_billable: OptionalNullable[bool] = True,
        phase: OptionalNullable[models.ProjectPhase] = UNSET,
        tax_rate: Optional[
            Union[models.LinkedTaxRateInput, models.LinkedTaxRateInputTypedDict]
        ] = None,
        tracking_categories: OptionalNullable[
            Union[
                List[Nullable[models.LinkedTrackingCategory]],
                List[Nullable[models.LinkedTrackingCategoryTypedDict]],
            ]
        ] = UNSET,
        tags: Optional[List[str]] = None,
        notes: OptionalNullable[str] = UNSET,
        contract_number: OptionalNullable[str] = UNSET,
        profit_margin: OptionalNullable[float] = UNSET,
        schedule_status: OptionalNullable[models.ScheduleStatus] = UNSET,
        addresses: Optional[
            Union[List[models.Address], List[models.AddressTypedDict]]
        ] = None,
        team_size: OptionalNullable[int] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        row_version: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsAddResponse:
        r"""Create project

        Create project

        :param name: Name of the project
        :param raw: Include raw response. Mostly used for debugging purposes
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param display_id: User-friendly project identifier
        :param reference_id: External reference identifier for the project
        :param description: Detailed description of the project
        :param status: Current status of the project
        :param active: Indicates whether the project is currently active or inactive
        :param project_type: Type or category of the project
        :param priority: Priority level of the project
        :param completion_percentage: Percentage of project completion (0-100)
        :param start_date: Start date of the project
        :param end_date: Expected or actual end date of the project
        :param customer: The customer this entity is linked to.
        :param department: Department or organizational unit associated with the project
        :param company_id: The company ID the transaction belongs to
        :param owner_id: ID of the user who owns/manages this project
        :param parent_project: Parent project if this is a subproject
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param budget_amount: Total budgeted amount for the project
        :param approved_amount: Approved budget amount for the project
        :param budget_hours: Total budgeted hours for the project
        :param hourly_rate: Default hourly rate for project work
        :param billing_method: Method used for billing this project
        :param is_billable: Indicates if the project is billable to the customer
        :param phase: Current phase of the project lifecycle
        :param tax_rate:
        :param tracking_categories: A list of linked tracking categories.
        :param tags: Tags associated with the project
        :param notes: Additional notes about the project
        :param contract_number: Contract or agreement number associated with the project
        :param profit_margin: Expected profit margin percentage for the project
        :param schedule_status: Current status of project schedule compared to plan
        :param addresses: An array of addresses associated with the project (billing, job site, etc.)
        :param team_size: Number of team members assigned to the project
        :param custom_fields:
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsAddRequest(
            raw=raw,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            project=models.ProjectInput(
                name=name,
                display_id=display_id,
                reference_id=reference_id,
                description=description,
                status=status,
                active=active,
                project_type=project_type,
                priority=priority,
                completion_percentage=completion_percentage,
                start_date=start_date,
                end_date=end_date,
                customer=utils.get_pydantic_model(
                    customer, OptionalNullable[models.LinkedCustomerInput]
                ),
                department=utils.get_pydantic_model(
                    department, OptionalNullable[models.ProjectDepartment]
                ),
                company_id=company_id,
                owner_id=owner_id,
                parent_project=utils.get_pydantic_model(
                    parent_project, OptionalNullable[models.ParentProject]
                ),
                currency=currency,
                budget_amount=budget_amount,
                approved_amount=approved_amount,
                budget_hours=budget_hours,
                hourly_rate=hourly_rate,
                billing_method=billing_method,
                is_billable=is_billable,
                phase=phase,
                tax_rate=utils.get_pydantic_model(
                    tax_rate, Optional[models.LinkedTaxRateInput]
                ),
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[Nullable[models.LinkedTrackingCategory]]],
                ),
                tags=tags,
                notes=notes,
                contract_number=contract_number,
                profit_margin=profit_margin,
                schedule_status=schedule_status,
                addresses=utils.get_pydantic_model(
                    addresses, Optional[List[models.Address]]
                ),
                team_size=team_size,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                row_version=row_version,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/accounting/projects",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsAddGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.project, False, False, "json", models.ProjectInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsAdd",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.AccountingProjectsAddResponse(
                create_project_response=unmarshal_json_response(
                    Optional[models.CreateProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsAddResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)

    def get(
        self,
        *,
        id: str,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsOneResponse:
        r"""Get project

        Get project

        :param id: ID of the record you are acting upon.
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsOneRequest(
            id=id,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            raw=raw,
        )

        req = self._build_request(
            method="GET",
            path="/accounting/projects/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsOneGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsOne",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsOneResponse(
                get_project_response=unmarshal_json_response(
                    Optional[models.GetProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsOneResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)

    async def get_async(
        self,
        *,
        id: str,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsOneResponse:
        r"""Get project

        Get project

        :param id: ID of the record you are acting upon.
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsOneRequest(
            id=id,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            raw=raw,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounting/projects/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsOneGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsOne",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsOneResponse(
                get_project_response=unmarshal_json_response(
                    Optional[models.GetProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsOneResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)

    def update(
        self,
        *,
        id: str,
        name: str,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        display_id: OptionalNullable[str] = UNSET,
        reference_id: OptionalNullable[str] = UNSET,
        description: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.ProjectProjectStatus] = UNSET,
        active: OptionalNullable[bool] = UNSET,
        project_type: OptionalNullable[models.ProjectType] = UNSET,
        priority: OptionalNullable[models.Priority] = UNSET,
        completion_percentage: OptionalNullable[float] = UNSET,
        start_date: OptionalNullable[date] = UNSET,
        end_date: OptionalNullable[date] = UNSET,
        customer: OptionalNullable[
            Union[models.LinkedCustomerInput, models.LinkedCustomerInputTypedDict]
        ] = UNSET,
        department: OptionalNullable[
            Union[models.ProjectDepartment, models.ProjectDepartmentTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        owner_id: OptionalNullable[str] = UNSET,
        parent_project: OptionalNullable[
            Union[models.ParentProject, models.ParentProjectTypedDict]
        ] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        budget_amount: OptionalNullable[float] = UNSET,
        approved_amount: OptionalNullable[float] = UNSET,
        budget_hours: OptionalNullable[float] = UNSET,
        hourly_rate: OptionalNullable[float] = UNSET,
        billing_method: OptionalNullable[models.BillingMethod] = UNSET,
        is_billable: OptionalNullable[bool] = True,
        phase: OptionalNullable[models.ProjectPhase] = UNSET,
        tax_rate: Optional[
            Union[models.LinkedTaxRateInput, models.LinkedTaxRateInputTypedDict]
        ] = None,
        tracking_categories: OptionalNullable[
            Union[
                List[Nullable[models.LinkedTrackingCategory]],
                List[Nullable[models.LinkedTrackingCategoryTypedDict]],
            ]
        ] = UNSET,
        tags: Optional[List[str]] = None,
        notes: OptionalNullable[str] = UNSET,
        contract_number: OptionalNullable[str] = UNSET,
        profit_margin: OptionalNullable[float] = UNSET,
        schedule_status: OptionalNullable[models.ScheduleStatus] = UNSET,
        addresses: Optional[
            Union[List[models.Address], List[models.AddressTypedDict]]
        ] = None,
        team_size: OptionalNullable[int] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        row_version: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsUpdateResponse:
        r"""Update project

        Update project

        :param id: ID of the record you are acting upon.
        :param name: Name of the project
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param display_id: User-friendly project identifier
        :param reference_id: External reference identifier for the project
        :param description: Detailed description of the project
        :param status: Current status of the project
        :param active: Indicates whether the project is currently active or inactive
        :param project_type: Type or category of the project
        :param priority: Priority level of the project
        :param completion_percentage: Percentage of project completion (0-100)
        :param start_date: Start date of the project
        :param end_date: Expected or actual end date of the project
        :param customer: The customer this entity is linked to.
        :param department: Department or organizational unit associated with the project
        :param company_id: The company ID the transaction belongs to
        :param owner_id: ID of the user who owns/manages this project
        :param parent_project: Parent project if this is a subproject
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param budget_amount: Total budgeted amount for the project
        :param approved_amount: Approved budget amount for the project
        :param budget_hours: Total budgeted hours for the project
        :param hourly_rate: Default hourly rate for project work
        :param billing_method: Method used for billing this project
        :param is_billable: Indicates if the project is billable to the customer
        :param phase: Current phase of the project lifecycle
        :param tax_rate:
        :param tracking_categories: A list of linked tracking categories.
        :param tags: Tags associated with the project
        :param notes: Additional notes about the project
        :param contract_number: Contract or agreement number associated with the project
        :param profit_margin: Expected profit margin percentage for the project
        :param schedule_status: Current status of project schedule compared to plan
        :param addresses: An array of addresses associated with the project (billing, job site, etc.)
        :param team_size: Number of team members assigned to the project
        :param custom_fields:
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsUpdateRequest(
            id=id,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            raw=raw,
            project=models.ProjectInput(
                name=name,
                display_id=display_id,
                reference_id=reference_id,
                description=description,
                status=status,
                active=active,
                project_type=project_type,
                priority=priority,
                completion_percentage=completion_percentage,
                start_date=start_date,
                end_date=end_date,
                customer=utils.get_pydantic_model(
                    customer, OptionalNullable[models.LinkedCustomerInput]
                ),
                department=utils.get_pydantic_model(
                    department, OptionalNullable[models.ProjectDepartment]
                ),
                company_id=company_id,
                owner_id=owner_id,
                parent_project=utils.get_pydantic_model(
                    parent_project, OptionalNullable[models.ParentProject]
                ),
                currency=currency,
                budget_amount=budget_amount,
                approved_amount=approved_amount,
                budget_hours=budget_hours,
                hourly_rate=hourly_rate,
                billing_method=billing_method,
                is_billable=is_billable,
                phase=phase,
                tax_rate=utils.get_pydantic_model(
                    tax_rate, Optional[models.LinkedTaxRateInput]
                ),
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[Nullable[models.LinkedTrackingCategory]]],
                ),
                tags=tags,
                notes=notes,
                contract_number=contract_number,
                profit_margin=profit_margin,
                schedule_status=schedule_status,
                addresses=utils.get_pydantic_model(
                    addresses, Optional[List[models.Address]]
                ),
                team_size=team_size,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                row_version=row_version,
            ),
        )

        req = self._build_request(
            method="PATCH",
            path="/accounting/projects/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsUpdateGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.project, False, False, "json", models.ProjectInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsUpdate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsUpdateResponse(
                update_project_response=unmarshal_json_response(
                    Optional[models.UpdateProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsUpdateResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)

    async def update_async(
        self,
        *,
        id: str,
        name: str,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        display_id: OptionalNullable[str] = UNSET,
        reference_id: OptionalNullable[str] = UNSET,
        description: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.ProjectProjectStatus] = UNSET,
        active: OptionalNullable[bool] = UNSET,
        project_type: OptionalNullable[models.ProjectType] = UNSET,
        priority: OptionalNullable[models.Priority] = UNSET,
        completion_percentage: OptionalNullable[float] = UNSET,
        start_date: OptionalNullable[date] = UNSET,
        end_date: OptionalNullable[date] = UNSET,
        customer: OptionalNullable[
            Union[models.LinkedCustomerInput, models.LinkedCustomerInputTypedDict]
        ] = UNSET,
        department: OptionalNullable[
            Union[models.ProjectDepartment, models.ProjectDepartmentTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        owner_id: OptionalNullable[str] = UNSET,
        parent_project: OptionalNullable[
            Union[models.ParentProject, models.ParentProjectTypedDict]
        ] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        budget_amount: OptionalNullable[float] = UNSET,
        approved_amount: OptionalNullable[float] = UNSET,
        budget_hours: OptionalNullable[float] = UNSET,
        hourly_rate: OptionalNullable[float] = UNSET,
        billing_method: OptionalNullable[models.BillingMethod] = UNSET,
        is_billable: OptionalNullable[bool] = True,
        phase: OptionalNullable[models.ProjectPhase] = UNSET,
        tax_rate: Optional[
            Union[models.LinkedTaxRateInput, models.LinkedTaxRateInputTypedDict]
        ] = None,
        tracking_categories: OptionalNullable[
            Union[
                List[Nullable[models.LinkedTrackingCategory]],
                List[Nullable[models.LinkedTrackingCategoryTypedDict]],
            ]
        ] = UNSET,
        tags: Optional[List[str]] = None,
        notes: OptionalNullable[str] = UNSET,
        contract_number: OptionalNullable[str] = UNSET,
        profit_margin: OptionalNullable[float] = UNSET,
        schedule_status: OptionalNullable[models.ScheduleStatus] = UNSET,
        addresses: Optional[
            Union[List[models.Address], List[models.AddressTypedDict]]
        ] = None,
        team_size: OptionalNullable[int] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        row_version: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsUpdateResponse:
        r"""Update project

        Update project

        :param id: ID of the record you are acting upon.
        :param name: Name of the project
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param display_id: User-friendly project identifier
        :param reference_id: External reference identifier for the project
        :param description: Detailed description of the project
        :param status: Current status of the project
        :param active: Indicates whether the project is currently active or inactive
        :param project_type: Type or category of the project
        :param priority: Priority level of the project
        :param completion_percentage: Percentage of project completion (0-100)
        :param start_date: Start date of the project
        :param end_date: Expected or actual end date of the project
        :param customer: The customer this entity is linked to.
        :param department: Department or organizational unit associated with the project
        :param company_id: The company ID the transaction belongs to
        :param owner_id: ID of the user who owns/manages this project
        :param parent_project: Parent project if this is a subproject
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param budget_amount: Total budgeted amount for the project
        :param approved_amount: Approved budget amount for the project
        :param budget_hours: Total budgeted hours for the project
        :param hourly_rate: Default hourly rate for project work
        :param billing_method: Method used for billing this project
        :param is_billable: Indicates if the project is billable to the customer
        :param phase: Current phase of the project lifecycle
        :param tax_rate:
        :param tracking_categories: A list of linked tracking categories.
        :param tags: Tags associated with the project
        :param notes: Additional notes about the project
        :param contract_number: Contract or agreement number associated with the project
        :param profit_margin: Expected profit margin percentage for the project
        :param schedule_status: Current status of project schedule compared to plan
        :param addresses: An array of addresses associated with the project (billing, job site, etc.)
        :param team_size: Number of team members assigned to the project
        :param custom_fields:
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsUpdateRequest(
            id=id,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            raw=raw,
            project=models.ProjectInput(
                name=name,
                display_id=display_id,
                reference_id=reference_id,
                description=description,
                status=status,
                active=active,
                project_type=project_type,
                priority=priority,
                completion_percentage=completion_percentage,
                start_date=start_date,
                end_date=end_date,
                customer=utils.get_pydantic_model(
                    customer, OptionalNullable[models.LinkedCustomerInput]
                ),
                department=utils.get_pydantic_model(
                    department, OptionalNullable[models.ProjectDepartment]
                ),
                company_id=company_id,
                owner_id=owner_id,
                parent_project=utils.get_pydantic_model(
                    parent_project, OptionalNullable[models.ParentProject]
                ),
                currency=currency,
                budget_amount=budget_amount,
                approved_amount=approved_amount,
                budget_hours=budget_hours,
                hourly_rate=hourly_rate,
                billing_method=billing_method,
                is_billable=is_billable,
                phase=phase,
                tax_rate=utils.get_pydantic_model(
                    tax_rate, Optional[models.LinkedTaxRateInput]
                ),
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[Nullable[models.LinkedTrackingCategory]]],
                ),
                tags=tags,
                notes=notes,
                contract_number=contract_number,
                profit_margin=profit_margin,
                schedule_status=schedule_status,
                addresses=utils.get_pydantic_model(
                    addresses, Optional[List[models.Address]]
                ),
                team_size=team_size,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                row_version=row_version,
            ),
        )

        req = self._build_request_async(
            method="PATCH",
            path="/accounting/projects/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsUpdateGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.project, False, False, "json", models.ProjectInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsUpdate",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsUpdateResponse(
                update_project_response=unmarshal_json_response(
                    Optional[models.UpdateProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsUpdateResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)

    def delete(
        self,
        *,
        id: str,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsDeleteResponse:
        r"""Delete project

        Delete project

        :param id: ID of the record you are acting upon.
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsDeleteRequest(
            id=id,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            raw=raw,
        )

        req = self._build_request(
            method="DELETE",
            path="/accounting/projects/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsDeleteGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsDelete",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsDeleteResponse(
                delete_project_response=unmarshal_json_response(
                    Optional[models.DeleteProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsDeleteResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)

    async def delete_async(
        self,
        *,
        id: str,
        consumer_id: Optional[str] = None,
        app_id: Optional[str] = None,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingProjectsDeleteResponse:
        r"""Delete project

        Delete project

        :param id: ID of the record you are acting upon.
        :param consumer_id: ID of the consumer which you want to get or push data from
        :param app_id: The ID of your Unify application
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.AccountingProjectsDeleteRequest(
            id=id,
            consumer_id=consumer_id,
            app_id=app_id,
            service_id=service_id,
            raw=raw,
        )

        req = self._build_request_async(
            method="DELETE",
            path="/accounting/projects/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingProjectsDeleteGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 900000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="accounting.projectsDelete",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingProjectsDeleteResponse(
                delete_project_response=unmarshal_json_response(
                    Optional[models.DeleteProjectResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.BadRequestResponseData, http_res
            )
            raise models.BadRequestResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                models.UnauthorizedResponseData, http_res
            )
            raise models.UnauthorizedResponse(response_data, http_res)
        if utils.match_response(http_res, "402", "application/json"):
            response_data = unmarshal_json_response(
                models.PaymentRequiredResponseData, http_res
            )
            raise models.PaymentRequiredResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                models.NotFoundResponseData, http_res
            )
            raise models.NotFoundResponse(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.UnprocessableResponseData, http_res
            )
            raise models.UnprocessableResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingProjectsDeleteResponse(
                unexpected_error_response=unmarshal_json_response(
                    Optional[models.UnexpectedErrorResponse], http_res
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        raise models.APIError("Unexpected response received", http_res)
