diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1269f909f..1eec10e9f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.6.0" + ".": "4.7.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 7309c957c..a0aad2266 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 118 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/metronome/metronome-f7e0e0ddfc48af411be9cceb4ff2f2902fd49e10a0e37375e291c2a06a6ddf6d.yml -openapi_spec_hash: 51a0820e0399b218d44af30e9e0cb2da -config_hash: e73a5fed3fb2fc458b2cd21b1e3e7b91 +configured_endpoints: 115 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/metronome/metronome-f12f505faf40d5f25d74c0b5a417e2b36c7f3f9621a0e23acd3d6ec4c615443e.yml +openapi_spec_hash: 5c1f13896608a69feebd8855703b76df +config_hash: 6bd82f310398d5d47bcfeb8d7ed150b3 diff --git a/CHANGELOG.md b/CHANGELOG.md index a804df984..b8f55dd10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 4.7.0 (2026-05-29) + +Full Changelog: [v4.6.0...v4.7.0](https://github.com/Metronome-Industries/metronome-python/compare/v4.6.0...v4.7.0) + +### Features + +* [LAUNCH-2814] editContract returns full edit in the response ([918e37c](https://github.com/Metronome-Industries/metronome-python/commit/918e37cf7c332247cbee157cfd027e9fe544b323)) +* [orch-1860] remove all deprecated `/payments/*` endpoints from API ([18e35ff](https://github.com/Metronome-Industries/metronome-python/commit/18e35ffc40321d898069710cca6beccc8de0bd8d)) +* create contract returns contract data ([d389dd3](https://github.com/Metronome-Industries/metronome-python/commit/d389dd34fb1fba3845e269efc7ba9e51c761840c)) +* nikku-orch-1723-update-create-contract ([55828d8](https://github.com/Metronome-Industries/metronome-python/commit/55828d8566c304e7ca8a5333dc45b3611e3c9298)) + + +### Chores + +* (internal) Add threshold balance specifier to contract create & edit, package create and both contract and package retrievals ([69b5ffe](https://github.com/Metronome-Industries/metronome-python/commit/69b5ffeeefbfccad8d0ee40d5e0abe8fff254bfc)) + ## 4.6.0 (2026-05-18) Full Changelog: [v4.5.0...v4.6.0](https://github.com/Metronome-Industries/metronome-python/compare/v4.5.0...v4.6.0) diff --git a/api.md b/api.md index 2f36e2f4c..b651bace5 100644 --- a/api.md +++ b/api.md @@ -558,20 +558,6 @@ Methods: - client.v1.packages.archive(\*\*params) -> PackageArchiveResponse - client.v1.packages.list_contracts_on_package(\*\*params) -> SyncCursorPage[PackageListContractsOnPackageResponse] -## Payments - -Types: - -```python -from metronome.types.v1 import Payment, PaymentStatus, PaymentAttemptResponse, PaymentCancelResponse -``` - -Methods: - -- client.v1.payments.list(\*\*params) -> SyncBodyCursorPage[Payment] -- client.v1.payments.attempt(\*\*params) -> PaymentAttemptResponse -- client.v1.payments.cancel(\*\*params) -> PaymentCancelResponse - ## Settings Types: diff --git a/pyproject.toml b/pyproject.toml index ba1a95514..1b6a2d3b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "metronome-sdk" -version = "4.6.0" +version = "4.7.0" description = "The official Python library for the metronome API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/metronome/_version.py b/src/metronome/_version.py index 70296be17..befc4d1fa 100644 --- a/src/metronome/_version.py +++ b/src/metronome/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "metronome" -__version__ = "4.6.0" # x-release-please-version +__version__ = "4.7.0" # x-release-please-version diff --git a/src/metronome/resources/v1/__init__.py b/src/metronome/resources/v1/__init__.py index 1319a76f6..6dbefad8d 100644 --- a/src/metronome/resources/v1/__init__.py +++ b/src/metronome/resources/v1/__init__.py @@ -48,14 +48,6 @@ PackagesResourceWithStreamingResponse, AsyncPackagesResourceWithStreamingResponse, ) -from .payments import ( - PaymentsResource, - AsyncPaymentsResource, - PaymentsResourceWithRawResponse, - AsyncPaymentsResourceWithRawResponse, - PaymentsResourceWithStreamingResponse, - AsyncPaymentsResourceWithStreamingResponse, -) from .services import ( ServicesResource, AsyncServicesResource, @@ -222,12 +214,6 @@ "AsyncPackagesResourceWithRawResponse", "PackagesResourceWithStreamingResponse", "AsyncPackagesResourceWithStreamingResponse", - "PaymentsResource", - "AsyncPaymentsResource", - "PaymentsResourceWithRawResponse", - "AsyncPaymentsResourceWithRawResponse", - "PaymentsResourceWithStreamingResponse", - "AsyncPaymentsResourceWithStreamingResponse", "SettingsResource", "AsyncSettingsResource", "SettingsResourceWithRawResponse", diff --git a/src/metronome/resources/v1/contracts/contracts.py b/src/metronome/resources/v1/contracts/contracts.py index a2b334919..a18ba1bb4 100644 --- a/src/metronome/resources/v1/contracts/contracts.py +++ b/src/metronome/resources/v1/contracts/contracts.py @@ -153,6 +153,7 @@ def create( scheduled_charges: Iterable[contract_create_params.ScheduledCharge] | Omit = omit, scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit, spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit, + spend_trackers: Iterable[contract_create_params.SpendTracker] | Omit = omit, subscriptions: Iterable[contract_create_params.Subscription] | Omit = omit, total_contract_value: float | Omit = omit, transition: contract_create_params.Transition | Omit = omit, @@ -335,6 +336,9 @@ def create( after a Contract has been created. If this field is omitted, charges will appear on a separate invoice from usage charges. + spend_trackers: Spend trackers to attach to this contract. Aliases must be unique within a + contract. + subscriptions: Optional list of [subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/) to add to the contract. @@ -385,6 +389,7 @@ def create( "scheduled_charges": scheduled_charges, "scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices, "spend_threshold_configuration": spend_threshold_configuration, + "spend_trackers": spend_trackers, "subscriptions": subscriptions, "total_contract_value": total_contract_value, "transition": transition, @@ -1520,6 +1525,7 @@ async def create( scheduled_charges: Iterable[contract_create_params.ScheduledCharge] | Omit = omit, scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit, spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit, + spend_trackers: Iterable[contract_create_params.SpendTracker] | Omit = omit, subscriptions: Iterable[contract_create_params.Subscription] | Omit = omit, total_contract_value: float | Omit = omit, transition: contract_create_params.Transition | Omit = omit, @@ -1702,6 +1708,9 @@ async def create( after a Contract has been created. If this field is omitted, charges will appear on a separate invoice from usage charges. + spend_trackers: Spend trackers to attach to this contract. Aliases must be unique within a + contract. + subscriptions: Optional list of [subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/) to add to the contract. @@ -1752,6 +1761,7 @@ async def create( "scheduled_charges": scheduled_charges, "scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices, "spend_threshold_configuration": spend_threshold_configuration, + "spend_trackers": spend_trackers, "subscriptions": subscriptions, "total_contract_value": total_contract_value, "transition": transition, diff --git a/src/metronome/resources/v1/packages.py b/src/metronome/resources/v1/packages.py index e560f8818..ba9abd01c 100644 --- a/src/metronome/resources/v1/packages.py +++ b/src/metronome/resources/v1/packages.py @@ -81,6 +81,7 @@ def create( scheduled_charges: Iterable[package_create_params.ScheduledCharge] | Omit = omit, scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit, spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit, + spend_trackers: Iterable[package_create_params.SpendTracker] | Omit = omit, subscriptions: Iterable[package_create_params.Subscription] | Omit = omit, uniqueness_key: str | Omit = omit, usage_statement_schedule: package_create_params.UsageStatementSchedule | Omit = omit, @@ -197,6 +198,7 @@ def create( "scheduled_charges": scheduled_charges, "scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices, "spend_threshold_configuration": spend_threshold_configuration, + "spend_trackers": spend_trackers, "subscriptions": subscriptions, "uniqueness_key": uniqueness_key, "usage_statement_schedule": usage_statement_schedule, @@ -365,10 +367,9 @@ def list_contracts_on_package( ### **Usage guidelines:** - Use the **`starting_at`**, **`covering_date`**, - and **`include_archived`** parameters to filter the list of returned contracts. - For example, to list only currently active contracts, - pass **`covering_date`** equal to the current time. + Use the **`starting_at`**, **`covering_date`**, and **`include_archived`** + parameters to filter the list of returned contracts. For example, to list only + currently active contracts, pass **`covering_date`** equal to the current time. Args: limit: Max number of results that should be returned @@ -464,6 +465,7 @@ async def create( scheduled_charges: Iterable[package_create_params.ScheduledCharge] | Omit = omit, scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit, spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit, + spend_trackers: Iterable[package_create_params.SpendTracker] | Omit = omit, subscriptions: Iterable[package_create_params.Subscription] | Omit = omit, uniqueness_key: str | Omit = omit, usage_statement_schedule: package_create_params.UsageStatementSchedule | Omit = omit, @@ -580,6 +582,7 @@ async def create( "scheduled_charges": scheduled_charges, "scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices, "spend_threshold_configuration": spend_threshold_configuration, + "spend_trackers": spend_trackers, "subscriptions": subscriptions, "uniqueness_key": uniqueness_key, "usage_statement_schedule": usage_statement_schedule, @@ -748,10 +751,9 @@ def list_contracts_on_package( ### **Usage guidelines:** - Use the **`starting_at`**, **`covering_date`**, - and **`include_archived`** parameters to filter the list of returned contracts. - For example, to list only currently active contracts, - pass **`covering_date`** equal to the current time. + Use the **`starting_at`**, **`covering_date`**, and **`include_archived`** + parameters to filter the list of returned contracts. For example, to list only + currently active contracts, pass **`covering_date`** equal to the current time. Args: limit: Max number of results that should be returned diff --git a/src/metronome/resources/v1/payments.py b/src/metronome/resources/v1/payments.py deleted file mode 100644 index d53ed34f0..000000000 --- a/src/metronome/resources/v1/payments.py +++ /dev/null @@ -1,409 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List - -import httpx - -from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform, async_maybe_transform -from ..._compat import cached_property -from ...types.v1 import payment_list_params, payment_cancel_params, payment_attempt_params -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...pagination import SyncBodyCursorPage, AsyncBodyCursorPage -from ..._base_client import AsyncPaginator, make_request_options -from ...types.v1.payment import Payment -from ...types.v1.payment_status import PaymentStatus -from ...types.v1.payment_cancel_response import PaymentCancelResponse -from ...types.v1.payment_attempt_response import PaymentAttemptResponse - -__all__ = ["PaymentsResource", "AsyncPaymentsResource"] - - -class PaymentsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> PaymentsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/Metronome-Industries/metronome-python#accessing-raw-response-data-eg-headers - """ - return PaymentsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> PaymentsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/Metronome-Industries/metronome-python#with_streaming_response - """ - return PaymentsResourceWithStreamingResponse(self) - - def list( - self, - *, - customer_id: str, - invoice_id: str, - limit: int | Omit = omit, - next_page: str | Omit = omit, - statuses: List[PaymentStatus] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncBodyCursorPage[Payment]: - """ - Fetch all payment attempts for the given invoice. - - Args: - limit: The maximum number of payments to return. Defaults to 25. - - next_page: The next page token from a previous response. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/v1/payments/list", - page=SyncBodyCursorPage[Payment], - body=maybe_transform( - { - "customer_id": customer_id, - "invoice_id": invoice_id, - "limit": limit, - "next_page": next_page, - "statuses": statuses, - }, - payment_list_params.PaymentListParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=Payment, - method="post", - ) - - def attempt( - self, - *, - customer_id: str, - invoice_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> PaymentAttemptResponse: - """ - Trigger a new attempt by canceling any existing attempts for this invoice and - creating a new Payment. This will trigger another attempt to charge the - Customer's configured Payment Gateway. Payment can only be attempted if all of - the following are true: - - - The Metronome Invoice is finalized - - PLG Invoicing is configured for the Customer - - You cannot attempt payments for invoices that have already been `paid` or - `voided`. - - Attempting to payment on an ineligible Invoice or Customer will result in a - `400` response. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/v1/payments/attempt", - body=maybe_transform( - { - "customer_id": customer_id, - "invoice_id": invoice_id, - }, - payment_attempt_params.PaymentAttemptParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=PaymentAttemptResponse, - ) - - def cancel( - self, - *, - customer_id: str, - invoice_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> PaymentCancelResponse: - """ - Cancel an existing payment attempt for an invoice. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/v1/payments/cancel", - body=maybe_transform( - { - "customer_id": customer_id, - "invoice_id": invoice_id, - }, - payment_cancel_params.PaymentCancelParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=PaymentCancelResponse, - ) - - -class AsyncPaymentsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncPaymentsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/Metronome-Industries/metronome-python#accessing-raw-response-data-eg-headers - """ - return AsyncPaymentsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncPaymentsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/Metronome-Industries/metronome-python#with_streaming_response - """ - return AsyncPaymentsResourceWithStreamingResponse(self) - - def list( - self, - *, - customer_id: str, - invoice_id: str, - limit: int | Omit = omit, - next_page: str | Omit = omit, - statuses: List[PaymentStatus] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[Payment, AsyncBodyCursorPage[Payment]]: - """ - Fetch all payment attempts for the given invoice. - - Args: - limit: The maximum number of payments to return. Defaults to 25. - - next_page: The next page token from a previous response. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get_api_list( - "/v1/payments/list", - page=AsyncBodyCursorPage[Payment], - body=maybe_transform( - { - "customer_id": customer_id, - "invoice_id": invoice_id, - "limit": limit, - "next_page": next_page, - "statuses": statuses, - }, - payment_list_params.PaymentListParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=Payment, - method="post", - ) - - async def attempt( - self, - *, - customer_id: str, - invoice_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> PaymentAttemptResponse: - """ - Trigger a new attempt by canceling any existing attempts for this invoice and - creating a new Payment. This will trigger another attempt to charge the - Customer's configured Payment Gateway. Payment can only be attempted if all of - the following are true: - - - The Metronome Invoice is finalized - - PLG Invoicing is configured for the Customer - - You cannot attempt payments for invoices that have already been `paid` or - `voided`. - - Attempting to payment on an ineligible Invoice or Customer will result in a - `400` response. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/v1/payments/attempt", - body=await async_maybe_transform( - { - "customer_id": customer_id, - "invoice_id": invoice_id, - }, - payment_attempt_params.PaymentAttemptParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=PaymentAttemptResponse, - ) - - async def cancel( - self, - *, - customer_id: str, - invoice_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> PaymentCancelResponse: - """ - Cancel an existing payment attempt for an invoice. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/v1/payments/cancel", - body=await async_maybe_transform( - { - "customer_id": customer_id, - "invoice_id": invoice_id, - }, - payment_cancel_params.PaymentCancelParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=PaymentCancelResponse, - ) - - -class PaymentsResourceWithRawResponse: - def __init__(self, payments: PaymentsResource) -> None: - self._payments = payments - - self.list = to_raw_response_wrapper( - payments.list, - ) - self.attempt = to_raw_response_wrapper( - payments.attempt, - ) - self.cancel = to_raw_response_wrapper( - payments.cancel, - ) - - -class AsyncPaymentsResourceWithRawResponse: - def __init__(self, payments: AsyncPaymentsResource) -> None: - self._payments = payments - - self.list = async_to_raw_response_wrapper( - payments.list, - ) - self.attempt = async_to_raw_response_wrapper( - payments.attempt, - ) - self.cancel = async_to_raw_response_wrapper( - payments.cancel, - ) - - -class PaymentsResourceWithStreamingResponse: - def __init__(self, payments: PaymentsResource) -> None: - self._payments = payments - - self.list = to_streamed_response_wrapper( - payments.list, - ) - self.attempt = to_streamed_response_wrapper( - payments.attempt, - ) - self.cancel = to_streamed_response_wrapper( - payments.cancel, - ) - - -class AsyncPaymentsResourceWithStreamingResponse: - def __init__(self, payments: AsyncPaymentsResource) -> None: - self._payments = payments - - self.list = async_to_streamed_response_wrapper( - payments.list, - ) - self.attempt = async_to_streamed_response_wrapper( - payments.attempt, - ) - self.cancel = async_to_streamed_response_wrapper( - payments.cancel, - ) diff --git a/src/metronome/resources/v1/v1.py b/src/metronome/resources/v1/v1.py index b8d60cfaf..33b0cc629 100644 --- a/src/metronome/resources/v1/v1.py +++ b/src/metronome/resources/v1/v1.py @@ -42,14 +42,6 @@ PackagesResourceWithStreamingResponse, AsyncPackagesResourceWithStreamingResponse, ) -from .payments import ( - PaymentsResource, - AsyncPaymentsResource, - PaymentsResourceWithRawResponse, - AsyncPaymentsResourceWithRawResponse, - PaymentsResourceWithStreamingResponse, - AsyncPaymentsResourceWithStreamingResponse, -) from .services import ( ServicesResource, AsyncServicesResource, @@ -226,10 +218,6 @@ def contracts(self) -> ContractsResource: def packages(self) -> PackagesResource: return PackagesResource(self._client) - @cached_property - def payments(self) -> PaymentsResource: - return PaymentsResource(self._client) - @cached_property def settings(self) -> SettingsResource: """ @@ -347,10 +335,6 @@ def contracts(self) -> AsyncContractsResource: def packages(self) -> AsyncPackagesResource: return AsyncPackagesResource(self._client) - @cached_property - def payments(self) -> AsyncPaymentsResource: - return AsyncPaymentsResource(self._client) - @cached_property def settings(self) -> AsyncSettingsResource: """ @@ -471,10 +455,6 @@ def contracts(self) -> ContractsResourceWithRawResponse: def packages(self) -> PackagesResourceWithRawResponse: return PackagesResourceWithRawResponse(self._v1.packages) - @cached_property - def payments(self) -> PaymentsResourceWithRawResponse: - return PaymentsResourceWithRawResponse(self._v1.payments) - @cached_property def settings(self) -> SettingsResourceWithRawResponse: """ @@ -576,10 +556,6 @@ def contracts(self) -> AsyncContractsResourceWithRawResponse: def packages(self) -> AsyncPackagesResourceWithRawResponse: return AsyncPackagesResourceWithRawResponse(self._v1.packages) - @cached_property - def payments(self) -> AsyncPaymentsResourceWithRawResponse: - return AsyncPaymentsResourceWithRawResponse(self._v1.payments) - @cached_property def settings(self) -> AsyncSettingsResourceWithRawResponse: """ @@ -681,10 +657,6 @@ def contracts(self) -> ContractsResourceWithStreamingResponse: def packages(self) -> PackagesResourceWithStreamingResponse: return PackagesResourceWithStreamingResponse(self._v1.packages) - @cached_property - def payments(self) -> PaymentsResourceWithStreamingResponse: - return PaymentsResourceWithStreamingResponse(self._v1.payments) - @cached_property def settings(self) -> SettingsResourceWithStreamingResponse: """ @@ -786,10 +758,6 @@ def contracts(self) -> AsyncContractsResourceWithStreamingResponse: def packages(self) -> AsyncPackagesResourceWithStreamingResponse: return AsyncPackagesResourceWithStreamingResponse(self._v1.packages) - @cached_property - def payments(self) -> AsyncPaymentsResourceWithStreamingResponse: - return AsyncPaymentsResourceWithStreamingResponse(self._v1.payments) - @cached_property def settings(self) -> AsyncSettingsResourceWithStreamingResponse: """ diff --git a/src/metronome/resources/v2/contracts.py b/src/metronome/resources/v2/contracts.py index 2c1630c08..b8333eb73 100644 --- a/src/metronome/resources/v2/contracts.py +++ b/src/metronome/resources/v2/contracts.py @@ -225,11 +225,13 @@ def edit( add_revenue_system_configuration_update: contract_edit_params.AddRevenueSystemConfigurationUpdate | Omit = omit, add_scheduled_charges: Iterable[contract_edit_params.AddScheduledCharge] | Omit = omit, add_spend_threshold_configuration: SpendThresholdConfigurationV2 | Omit = omit, + add_spend_trackers: Iterable[contract_edit_params.AddSpendTracker] | Omit = omit, add_subscriptions: Iterable[contract_edit_params.AddSubscription] | Omit = omit, allow_contract_ending_before_finalized_invoice: bool | Omit = omit, archive_commits: Iterable[contract_edit_params.ArchiveCommit] | Omit = omit, archive_credits: Iterable[contract_edit_params.ArchiveCredit] | Omit = omit, archive_scheduled_charges: Iterable[contract_edit_params.ArchiveScheduledCharge] | Omit = omit, + archive_spend_trackers: SequenceNotStr[str] | Omit = omit, remove_overrides: Iterable[contract_edit_params.RemoveOverride] | Omit = omit, uniqueness_key: str | Omit = omit, update_commits: Iterable[contract_edit_params.UpdateCommit] | Omit = omit, @@ -290,6 +292,9 @@ def edit( adding a revenue system configuration to a contract that does not already have one. + add_spend_trackers: Spend trackers to add to this contract. Aliases must be unique within a + contract. + add_subscriptions: Optional list of [subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/) to add to the contract. @@ -305,6 +310,8 @@ def edit( archive_scheduled_charges: IDs of scheduled charges to archive + archive_spend_trackers: Aliases of spend trackers to archive. + remove_overrides: IDs of overrides to remove uniqueness_key: Optional uniqueness key to prevent duplicate contract edits. @@ -354,11 +361,13 @@ def edit( "add_revenue_system_configuration_update": add_revenue_system_configuration_update, "add_scheduled_charges": add_scheduled_charges, "add_spend_threshold_configuration": add_spend_threshold_configuration, + "add_spend_trackers": add_spend_trackers, "add_subscriptions": add_subscriptions, "allow_contract_ending_before_finalized_invoice": allow_contract_ending_before_finalized_invoice, "archive_commits": archive_commits, "archive_credits": archive_credits, "archive_scheduled_charges": archive_scheduled_charges, + "archive_spend_trackers": archive_spend_trackers, "remove_overrides": remove_overrides, "uniqueness_key": uniqueness_key, "update_commits": update_commits, @@ -837,11 +846,13 @@ async def edit( add_revenue_system_configuration_update: contract_edit_params.AddRevenueSystemConfigurationUpdate | Omit = omit, add_scheduled_charges: Iterable[contract_edit_params.AddScheduledCharge] | Omit = omit, add_spend_threshold_configuration: SpendThresholdConfigurationV2 | Omit = omit, + add_spend_trackers: Iterable[contract_edit_params.AddSpendTracker] | Omit = omit, add_subscriptions: Iterable[contract_edit_params.AddSubscription] | Omit = omit, allow_contract_ending_before_finalized_invoice: bool | Omit = omit, archive_commits: Iterable[contract_edit_params.ArchiveCommit] | Omit = omit, archive_credits: Iterable[contract_edit_params.ArchiveCredit] | Omit = omit, archive_scheduled_charges: Iterable[contract_edit_params.ArchiveScheduledCharge] | Omit = omit, + archive_spend_trackers: SequenceNotStr[str] | Omit = omit, remove_overrides: Iterable[contract_edit_params.RemoveOverride] | Omit = omit, uniqueness_key: str | Omit = omit, update_commits: Iterable[contract_edit_params.UpdateCommit] | Omit = omit, @@ -902,6 +913,9 @@ async def edit( adding a revenue system configuration to a contract that does not already have one. + add_spend_trackers: Spend trackers to add to this contract. Aliases must be unique within a + contract. + add_subscriptions: Optional list of [subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/) to add to the contract. @@ -917,6 +931,8 @@ async def edit( archive_scheduled_charges: IDs of scheduled charges to archive + archive_spend_trackers: Aliases of spend trackers to archive. + remove_overrides: IDs of overrides to remove uniqueness_key: Optional uniqueness key to prevent duplicate contract edits. @@ -966,11 +982,13 @@ async def edit( "add_revenue_system_configuration_update": add_revenue_system_configuration_update, "add_scheduled_charges": add_scheduled_charges, "add_spend_threshold_configuration": add_spend_threshold_configuration, + "add_spend_trackers": add_spend_trackers, "add_subscriptions": add_subscriptions, "allow_contract_ending_before_finalized_invoice": allow_contract_ending_before_finalized_invoice, "archive_commits": archive_commits, "archive_credits": archive_credits, "archive_scheduled_charges": archive_scheduled_charges, + "archive_spend_trackers": archive_spend_trackers, "remove_overrides": remove_overrides, "uniqueness_key": uniqueness_key, "update_commits": update_commits, diff --git a/src/metronome/types/shared/commit.py b/src/metronome/types/shared/commit.py index 7aae25236..301a6cee7 100644 --- a/src/metronome/types/shared/commit.py +++ b/src/metronome/types/shared/commit.py @@ -31,6 +31,7 @@ "LedgerPostpaidCommitManualLedgerEntry", "LedgerPostpaidCommitExpirationLedgerEntry", "RolledOverFrom", + "SpendTrackerAttributes", "SubscriptionConfig", "SubscriptionConfigApplySeatIncreaseConfig", ] @@ -234,6 +235,16 @@ class RolledOverFrom(BaseModel): contract_id: str +class SpendTrackerAttributes(BaseModel): + """Optional attributes controlling how this commit interacts with spend trackers.""" + + counts_as_discounted: bool + """ + If true, this commit is included in spend trackers with discounted set to + DISCOUNTED_ONLY + """ + + class SubscriptionConfigApplySeatIncreaseConfig(BaseModel): is_prorated: bool """Indicates whether a mid-period seat increase should be prorated.""" @@ -355,6 +366,9 @@ class Commit(BaseModel): specifiers to contribute to a commit's or credit's drawdown. """ + spend_tracker_attributes: Optional[SpendTrackerAttributes] = None + """Optional attributes controlling how this commit interacts with spend trackers.""" + subscription_config: Optional[SubscriptionConfig] = None """ The subscription configuration for this commit, if it was generated from a diff --git a/src/metronome/types/shared/contract.py b/src/metronome/types/shared/contract.py index 5a4f386ac..8641a1848 100644 --- a/src/metronome/types/shared/contract.py +++ b/src/metronome/types/shared/contract.py @@ -16,7 +16,15 @@ from .spend_threshold_configuration import SpendThresholdConfiguration from .prepaid_balance_threshold_configuration import PrepaidBalanceThresholdConfiguration -__all__ = ["Contract", "Amendment", "AmendmentResellerRoyalty", "CustomerBillingProviderConfiguration"] +__all__ = [ + "Contract", + "Amendment", + "AmendmentResellerRoyalty", + "CustomerBillingProviderConfiguration", + "SpendTracker", + "SpendTrackerApplicableSpendSpecifier", + "SpendTrackerAccumulatedSpend", +] class AmendmentResellerRoyalty(BaseModel): @@ -104,6 +112,35 @@ class CustomerBillingProviderConfiguration(BaseModel): """ +class SpendTrackerApplicableSpendSpecifier(BaseModel): + sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]] + + spend_type: Literal["COMMIT_PURCHASE"] + + discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None + + +class SpendTrackerAccumulatedSpend(BaseModel): + amount: float + + period_ending_before: datetime + + period_starting_at: datetime + + +class SpendTracker(BaseModel): + alias: str + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier] + + credit_type_id: str + + reset_frequency: Literal["BILLING_PERIOD"] + + accumulated_spend: Optional[SpendTrackerAccumulatedSpend] = None + + class Contract(BaseModel): id: str @@ -143,6 +180,9 @@ class Contract(BaseModel): spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None + spend_trackers: Optional[List[SpendTracker]] = None + """Spend trackers attached to this contract.""" + subscriptions: Optional[List[Subscription]] = None """List of subscriptions on the contract.""" diff --git a/src/metronome/types/shared/contract_v2.py b/src/metronome/types/shared/contract_v2.py index 2da2efae6..e117360d5 100644 --- a/src/metronome/types/shared/contract_v2.py +++ b/src/metronome/types/shared/contract_v2.py @@ -41,6 +41,7 @@ "CommitLedgerPostpaidCommitManualLedgerEntry", "CommitLedgerPostpaidCommitExpirationLedgerEntry", "CommitRolledOverFrom", + "CommitSpendTrackerAttributes", "Override", "OverrideOverrideSpecifier", "OverrideOverwriteRate", @@ -82,6 +83,9 @@ "RecurringCreditContract", "ResellerRoyalty", "ResellerRoyaltySegment", + "SpendTracker", + "SpendTrackerApplicableSpendSpecifier", + "SpendTrackerAccumulatedSpend", "Subscription", "SubscriptionBillingPeriods", "SubscriptionBillingPeriodsCurrent", @@ -293,6 +297,16 @@ class CommitRolledOverFrom(BaseModel): contract_id: str +class CommitSpendTrackerAttributes(BaseModel): + """Optional attributes controlling how this commit interacts with spend trackers.""" + + counts_as_discounted: bool + """ + If true, this commit is included in spend trackers with discounted set to + DISCOUNTED_ONLY + """ + + class Commit(BaseModel): id: str @@ -387,6 +401,9 @@ class Commit(BaseModel): specifiers to contribute to a commit's or credit's drawdown. """ + spend_tracker_attributes: Optional[CommitSpendTrackerAttributes] = None + """Optional attributes controlling how this commit interacts with spend trackers.""" + subscription_config: Optional[RecurringCommitSubscriptionConfig] = None """Attach a subscription to the recurring commit/credit.""" @@ -1079,6 +1096,35 @@ class ResellerRoyalty(BaseModel): segments: List[ResellerRoyaltySegment] +class SpendTrackerApplicableSpendSpecifier(BaseModel): + sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]] + + spend_type: Literal["COMMIT_PURCHASE"] + + discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None + + +class SpendTrackerAccumulatedSpend(BaseModel): + amount: float + + period_ending_before: datetime + + period_starting_at: datetime + + +class SpendTracker(BaseModel): + alias: str + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier] + + credit_type_id: str + + reset_frequency: Literal["BILLING_PERIOD"] + + accumulated_spend: Optional[SpendTrackerAccumulatedSpend] = None + + class SubscriptionBillingPeriodsCurrent(BaseModel): ending_before: datetime @@ -1288,6 +1334,9 @@ class ContractV2(BaseModel): spend_threshold_configuration: Optional[SpendThresholdConfigurationV2] = None + spend_trackers: Optional[List[SpendTracker]] = None + """Spend trackers attached to this contract.""" + subscriptions: Optional[List[Subscription]] = None """List of subscriptions on the contract.""" diff --git a/src/metronome/types/shared/contract_without_amendments.py b/src/metronome/types/shared/contract_without_amendments.py index 5a92c019f..b16406ad3 100644 --- a/src/metronome/types/shared/contract_without_amendments.py +++ b/src/metronome/types/shared/contract_without_amendments.py @@ -35,6 +35,9 @@ "RecurringCreditProduct", "RecurringCreditContract", "ResellerRoyalty", + "SpendTracker", + "SpendTrackerApplicableSpendSpecifier", + "SpendTrackerAccumulatedSpend", "UsageFilter", "UsageFilterUpdate", ] @@ -306,6 +309,35 @@ class ResellerRoyalty(BaseModel): reseller_contract_value: Optional[float] = None +class SpendTrackerApplicableSpendSpecifier(BaseModel): + sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]] + + spend_type: Literal["COMMIT_PURCHASE"] + + discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None + + +class SpendTrackerAccumulatedSpend(BaseModel): + amount: float + + period_ending_before: datetime + + period_starting_at: datetime + + +class SpendTracker(BaseModel): + alias: str + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier] + + credit_type_id: str + + reset_frequency: Literal["BILLING_PERIOD"] + + accumulated_spend: Optional[SpendTrackerAccumulatedSpend] = None + + class UsageFilterUpdate(BaseModel): group_key: str @@ -387,6 +419,9 @@ class ContractWithoutAmendments(BaseModel): spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None + spend_trackers: Optional[List[SpendTracker]] = None + """Spend trackers attached to this contract.""" + total_contract_value: Optional[float] = None """This field's availability is dependent on your client's configuration.""" diff --git a/src/metronome/types/shared/prepaid_balance_threshold_configuration.py b/src/metronome/types/shared/prepaid_balance_threshold_configuration.py index 776c0f479..b8bb84c42 100644 --- a/src/metronome/types/shared/prepaid_balance_threshold_configuration.py +++ b/src/metronome/types/shared/prepaid_balance_threshold_configuration.py @@ -1,13 +1,22 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional +from typing_extensions import Literal from ..._models import BaseModel from .payment_gate_config import PaymentGateConfig from .base_threshold_commit import BaseThresholdCommit from .commit_specifier_input import CommitSpecifierInput -__all__ = ["PrepaidBalanceThresholdConfiguration", "Commit", "DiscountConfiguration"] +__all__ = [ + "PrepaidBalanceThresholdConfiguration", + "Commit", + "DiscountConfiguration", + "DiscountConfigurationCap", + "ThresholdBalanceSpecifier", + "ThresholdBalanceSpecifierExclude", + "ThresholdBalanceSpecifierExcludeCustomFieldFilter", +] class Commit(BaseThresholdCommit): @@ -34,6 +43,18 @@ class Commit(BaseThresholdCommit): """ +class DiscountConfigurationCap(BaseModel): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" + + class DiscountConfiguration(BaseModel): payment_fraction: float """ @@ -42,6 +63,32 @@ class DiscountConfiguration(BaseModel): (a 15% discount). """ + cap: Optional[DiscountConfigurationCap] = None + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + + +class ThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel): + entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"] + + key: str + + value: str + + +class ThresholdBalanceSpecifierExclude(BaseModel): + custom_field_filters: List[ThresholdBalanceSpecifierExcludeCustomFieldFilter] + """ + If provided, balances with all the custom fields will not be considered when + evaluating threshold billing + """ + + +class ThresholdBalanceSpecifier(BaseModel): + exclude: List[ThresholdBalanceSpecifierExclude] + class PrepaidBalanceThresholdConfiguration(BaseModel): commit: Commit @@ -72,3 +119,5 @@ class PrepaidBalanceThresholdConfiguration(BaseModel): """ discount_configuration: Optional[DiscountConfiguration] = None + + threshold_balance_specifiers: Optional[List[ThresholdBalanceSpecifier]] = None diff --git a/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py b/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py index 8539dbf65..8402dfd29 100644 --- a/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py +++ b/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py @@ -1,13 +1,22 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional +from typing_extensions import Literal from ..._models import BaseModel from .base_threshold_commit import BaseThresholdCommit from .commit_specifier_input import CommitSpecifierInput from .payment_gate_config_v2 import PaymentGateConfigV2 -__all__ = ["PrepaidBalanceThresholdConfigurationV2", "Commit", "DiscountConfiguration"] +__all__ = [ + "PrepaidBalanceThresholdConfigurationV2", + "Commit", + "DiscountConfiguration", + "DiscountConfigurationCap", + "ThresholdBalanceSpecifier", + "ThresholdBalanceSpecifierExclude", + "ThresholdBalanceSpecifierExcludeCustomFieldFilter", +] class Commit(BaseThresholdCommit): @@ -36,6 +45,18 @@ class Commit(BaseThresholdCommit): """ +class DiscountConfigurationCap(BaseModel): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" + + class DiscountConfiguration(BaseModel): payment_fraction: float """ @@ -44,6 +65,28 @@ class DiscountConfiguration(BaseModel): (a 15% discount). """ + cap: Optional[DiscountConfigurationCap] = None + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + + +class ThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel): + entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"] + + key: str + + value: str + + +class ThresholdBalanceSpecifierExclude(BaseModel): + custom_field_filters: List[ThresholdBalanceSpecifierExcludeCustomFieldFilter] + + +class ThresholdBalanceSpecifier(BaseModel): + exclude: List[ThresholdBalanceSpecifierExclude] + class PrepaidBalanceThresholdConfigurationV2(BaseModel): commit: Commit @@ -74,3 +117,5 @@ class PrepaidBalanceThresholdConfigurationV2(BaseModel): """ discount_configuration: Optional[DiscountConfiguration] = None + + threshold_balance_specifiers: Optional[List[ThresholdBalanceSpecifier]] = None diff --git a/src/metronome/types/shared/spend_threshold_configuration.py b/src/metronome/types/shared/spend_threshold_configuration.py index ae78995e3..95935c490 100644 --- a/src/metronome/types/shared/spend_threshold_configuration.py +++ b/src/metronome/types/shared/spend_threshold_configuration.py @@ -6,7 +6,19 @@ from .payment_gate_config import PaymentGateConfig from .base_threshold_commit import BaseThresholdCommit -__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration"] +__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration", "DiscountConfigurationCap"] + + +class DiscountConfigurationCap(BaseModel): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" class DiscountConfiguration(BaseModel): @@ -17,6 +29,12 @@ class DiscountConfiguration(BaseModel): (a 15% discount). """ + cap: Optional[DiscountConfigurationCap] = None + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + class SpendThresholdConfiguration(BaseModel): commit: BaseThresholdCommit diff --git a/src/metronome/types/shared/spend_threshold_configuration_v2.py b/src/metronome/types/shared/spend_threshold_configuration_v2.py index 91816c963..fc3e94911 100644 --- a/src/metronome/types/shared/spend_threshold_configuration_v2.py +++ b/src/metronome/types/shared/spend_threshold_configuration_v2.py @@ -6,7 +6,19 @@ from .base_threshold_commit import BaseThresholdCommit from .payment_gate_config_v2 import PaymentGateConfigV2 -__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration"] +__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration", "DiscountConfigurationCap"] + + +class DiscountConfigurationCap(BaseModel): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" class DiscountConfiguration(BaseModel): @@ -17,6 +29,12 @@ class DiscountConfiguration(BaseModel): (a 15% discount). """ + cap: Optional[DiscountConfigurationCap] = None + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + class SpendThresholdConfigurationV2(BaseModel): commit: BaseThresholdCommit diff --git a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py index 974698132..5da85c457 100644 --- a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py +++ b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py @@ -3,14 +3,22 @@ from __future__ import annotations from typing import Iterable -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict from ..._types import SequenceNotStr from .payment_gate_config import PaymentGateConfig from .base_threshold_commit import BaseThresholdCommit from .commit_specifier_input import CommitSpecifierInput -__all__ = ["PrepaidBalanceThresholdConfiguration", "Commit", "DiscountConfiguration"] +__all__ = [ + "PrepaidBalanceThresholdConfiguration", + "Commit", + "DiscountConfiguration", + "DiscountConfigurationCap", + "ThresholdBalanceSpecifier", + "ThresholdBalanceSpecifierExclude", + "ThresholdBalanceSpecifierExcludeCustomFieldFilter", +] class Commit(BaseThresholdCommit, total=False): @@ -37,6 +45,18 @@ class Commit(BaseThresholdCommit, total=False): """ +class DiscountConfigurationCap(TypedDict, total=False): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: Required[float] + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: Required[str] + """Alias of the spend tracker this cap is measured against.""" + + class DiscountConfiguration(TypedDict, total=False): payment_fraction: Required[float] """ @@ -45,6 +65,32 @@ class DiscountConfiguration(TypedDict, total=False): (a 15% discount). """ + cap: DiscountConfigurationCap + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + + +class ThresholdBalanceSpecifierExcludeCustomFieldFilter(TypedDict, total=False): + entity: Required[Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]] + + key: Required[str] + + value: Required[str] + + +class ThresholdBalanceSpecifierExclude(TypedDict, total=False): + custom_field_filters: Required[Iterable[ThresholdBalanceSpecifierExcludeCustomFieldFilter]] + """ + If provided, balances with all the custom fields will not be considered when + evaluating threshold billing + """ + + +class ThresholdBalanceSpecifier(TypedDict, total=False): + exclude: Required[Iterable[ThresholdBalanceSpecifierExclude]] + class PrepaidBalanceThresholdConfiguration(TypedDict, total=False): commit: Required[Commit] @@ -75,3 +121,5 @@ class PrepaidBalanceThresholdConfiguration(TypedDict, total=False): """ discount_configuration: DiscountConfiguration + + threshold_balance_specifiers: Iterable[ThresholdBalanceSpecifier] diff --git a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py index 27c36c1fd..0230b6f7e 100644 --- a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py +++ b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py @@ -3,14 +3,22 @@ from __future__ import annotations from typing import Iterable -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict from ..._types import SequenceNotStr from .base_threshold_commit import BaseThresholdCommit from .commit_specifier_input import CommitSpecifierInput from .payment_gate_config_v2 import PaymentGateConfigV2 -__all__ = ["PrepaidBalanceThresholdConfigurationV2", "Commit", "DiscountConfiguration"] +__all__ = [ + "PrepaidBalanceThresholdConfigurationV2", + "Commit", + "DiscountConfiguration", + "DiscountConfigurationCap", + "ThresholdBalanceSpecifier", + "ThresholdBalanceSpecifierExclude", + "ThresholdBalanceSpecifierExcludeCustomFieldFilter", +] class Commit(BaseThresholdCommit, total=False): @@ -39,6 +47,18 @@ class Commit(BaseThresholdCommit, total=False): """ +class DiscountConfigurationCap(TypedDict, total=False): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: Required[float] + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: Required[str] + """Alias of the spend tracker this cap is measured against.""" + + class DiscountConfiguration(TypedDict, total=False): payment_fraction: Required[float] """ @@ -47,6 +67,28 @@ class DiscountConfiguration(TypedDict, total=False): (a 15% discount). """ + cap: DiscountConfigurationCap + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + + +class ThresholdBalanceSpecifierExcludeCustomFieldFilter(TypedDict, total=False): + entity: Required[Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]] + + key: Required[str] + + value: Required[str] + + +class ThresholdBalanceSpecifierExclude(TypedDict, total=False): + custom_field_filters: Required[Iterable[ThresholdBalanceSpecifierExcludeCustomFieldFilter]] + + +class ThresholdBalanceSpecifier(TypedDict, total=False): + exclude: Required[Iterable[ThresholdBalanceSpecifierExclude]] + class PrepaidBalanceThresholdConfigurationV2(TypedDict, total=False): commit: Required[Commit] @@ -77,3 +119,5 @@ class PrepaidBalanceThresholdConfigurationV2(TypedDict, total=False): """ discount_configuration: DiscountConfiguration + + threshold_balance_specifiers: Iterable[ThresholdBalanceSpecifier] diff --git a/src/metronome/types/shared_params/spend_threshold_configuration.py b/src/metronome/types/shared_params/spend_threshold_configuration.py index 349a76d04..afa808498 100644 --- a/src/metronome/types/shared_params/spend_threshold_configuration.py +++ b/src/metronome/types/shared_params/spend_threshold_configuration.py @@ -7,7 +7,19 @@ from .payment_gate_config import PaymentGateConfig from .base_threshold_commit import BaseThresholdCommit -__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration"] +__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration", "DiscountConfigurationCap"] + + +class DiscountConfigurationCap(TypedDict, total=False): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: Required[float] + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: Required[str] + """Alias of the spend tracker this cap is measured against.""" class DiscountConfiguration(TypedDict, total=False): @@ -18,6 +30,12 @@ class DiscountConfiguration(TypedDict, total=False): (a 15% discount). """ + cap: DiscountConfigurationCap + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + class SpendThresholdConfiguration(TypedDict, total=False): commit: Required[BaseThresholdCommit] diff --git a/src/metronome/types/shared_params/spend_threshold_configuration_v2.py b/src/metronome/types/shared_params/spend_threshold_configuration_v2.py index a577d4399..ce39da95d 100644 --- a/src/metronome/types/shared_params/spend_threshold_configuration_v2.py +++ b/src/metronome/types/shared_params/spend_threshold_configuration_v2.py @@ -7,7 +7,19 @@ from .base_threshold_commit import BaseThresholdCommit from .payment_gate_config_v2 import PaymentGateConfigV2 -__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration"] +__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration", "DiscountConfigurationCap"] + + +class DiscountConfigurationCap(TypedDict, total=False): + """ + If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period. + """ + + amount: Required[float] + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: Required[str] + """Alias of the spend tracker this cap is measured against.""" class DiscountConfiguration(TypedDict, total=False): @@ -18,6 +30,12 @@ class DiscountConfiguration(TypedDict, total=False): (a 15% discount). """ + cap: DiscountConfigurationCap + """ + If provided, the discount stops applying once the spend tracker has accumulated + this much spend in the billing period. + """ + class SpendThresholdConfigurationV2(TypedDict, total=False): commit: Required[BaseThresholdCommit] diff --git a/src/metronome/types/v1/__init__.py b/src/metronome/types/v1/__init__.py index 3430b56ed..12b28d369 100644 --- a/src/metronome/types/v1/__init__.py +++ b/src/metronome/types/v1/__init__.py @@ -2,10 +2,8 @@ from __future__ import annotations -from .payment import Payment as Payment from .customer import Customer as Customer from .plan_detail import PlanDetail as PlanDetail -from .payment_status import PaymentStatus as PaymentStatus from .customer_detail import CustomerDetail as CustomerDetail from .plan_list_params import PlanListParams as PlanListParams from .usage_list_params import UsageListParams as UsageListParams @@ -14,7 +12,6 @@ from .credit_ledger_entry import CreditLedgerEntry as CreditLedgerEntry from .invoice_void_params import InvoiceVoidParams as InvoiceVoidParams from .package_list_params import PackageListParams as PackageListParams -from .payment_list_params import PaymentListParams as PaymentListParams from .usage_ingest_params import UsageIngestParams as UsageIngestParams from .usage_list_response import UsageListResponse as UsageListResponse from .usage_search_params import UsageSearchParams as UsageSearchParams @@ -27,7 +24,6 @@ from .invoice_void_response import InvoiceVoidResponse as InvoiceVoidResponse from .package_create_params import PackageCreateParams as PackageCreateParams from .package_list_response import PackageListResponse as PackageListResponse -from .payment_cancel_params import PaymentCancelParams as PaymentCancelParams from .service_list_response import ServiceListResponse as ServiceListResponse from .usage_search_response import UsageSearchResponse as UsageSearchResponse from .alert_archive_response import AlertArchiveResponse as AlertArchiveResponse @@ -35,14 +31,12 @@ from .contract_list_response import ContractListResponse as ContractListResponse from .customer_create_params import CustomerCreateParams as CustomerCreateParams from .package_archive_params import PackageArchiveParams as PackageArchiveParams -from .payment_attempt_params import PaymentAttemptParams as PaymentAttemptParams from .audit_log_list_response import AuditLogListResponse as AuditLogListResponse from .contract_amend_response import ContractAmendResponse as ContractAmendResponse from .contract_archive_params import ContractArchiveParams as ContractArchiveParams from .customer_archive_params import CustomerArchiveParams as CustomerArchiveParams from .package_create_response import PackageCreateResponse as PackageCreateResponse from .package_retrieve_params import PackageRetrieveParams as PackageRetrieveParams -from .payment_cancel_response import PaymentCancelResponse as PaymentCancelResponse from .contract_create_response import ContractCreateResponse as ContractCreateResponse from .contract_retrieve_params import ContractRetrieveParams as ContractRetrieveParams from .credit_grant_edit_params import CreditGrantEditParams as CreditGrantEditParams @@ -51,7 +45,6 @@ from .customer_create_response import CustomerCreateResponse as CustomerCreateResponse from .customer_set_name_params import CustomerSetNameParams as CustomerSetNameParams from .package_archive_response import PackageArchiveResponse as PackageArchiveResponse -from .payment_attempt_response import PaymentAttemptResponse as PaymentAttemptResponse from .plan_list_charges_params import PlanListChargesParams as PlanListChargesParams from .pricing_unit_list_params import PricingUnitListParams as PricingUnitListParams from .contract_archive_response import ContractArchiveResponse as ContractArchiveResponse diff --git a/src/metronome/types/v1/contract_amend_params.py b/src/metronome/types/v1/contract_amend_params.py index 0b32c3718..59c22ccb0 100644 --- a/src/metronome/types/v1/contract_amend_params.py +++ b/src/metronome/types/v1/contract_amend_params.py @@ -20,6 +20,7 @@ "CommitInvoiceSchedule", "CommitInvoiceScheduleRecurringSchedule", "CommitInvoiceScheduleScheduleItem", + "CommitSpendTrackerAttributes", "Credit", "CreditAccessSchedule", "CreditAccessScheduleScheduleItem", @@ -194,6 +195,16 @@ class CommitInvoiceSchedule(TypedDict, total=False): """Either provide amount or provide both unit_price and quantity.""" +class CommitSpendTrackerAttributes(TypedDict, total=False): + """Optional attributes for spend tracker integration. Immutable after creation.""" + + counts_as_discounted: Required[bool] + """ + If true, this commit will be included in spend trackers with discounted set to + DISCOUNTED_ONLY + """ + + class Commit(TypedDict, total=False): product_id: Required[str] @@ -265,6 +276,9 @@ class Commit(TypedDict, total=False): be used together with `applicable_product_ids` or `applicable_product_tags`. """ + spend_tracker_attributes: CommitSpendTrackerAttributes + """Optional attributes for spend tracker integration. Immutable after creation.""" + temporary_id: str """ A temporary ID for the commit that can be used to reference the commit for diff --git a/src/metronome/types/v1/contract_create_params.py b/src/metronome/types/v1/contract_create_params.py index 58ab3fc7a..9d9354ebf 100644 --- a/src/metronome/types/v1/contract_create_params.py +++ b/src/metronome/types/v1/contract_create_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Dict, Union, Iterable, Optional +from typing import Dict, List, Union, Iterable, Optional from datetime import datetime from typing_extensions import Literal, Required, Annotated, TypedDict @@ -24,6 +24,7 @@ "CommitInvoiceSchedule", "CommitInvoiceScheduleRecurringSchedule", "CommitInvoiceScheduleScheduleItem", + "CommitSpendTrackerAttributes", "Credit", "CreditAccessSchedule", "CreditAccessScheduleScheduleItem", @@ -58,6 +59,8 @@ "ScheduledChargeSchedule", "ScheduledChargeScheduleRecurringSchedule", "ScheduledChargeScheduleScheduleItem", + "SpendTracker", + "SpendTrackerApplicableSpendSpecifier", "Subscription", "SubscriptionProration", "SubscriptionSubscriptionRate", @@ -167,6 +170,12 @@ class ContractCreateParams(TypedDict, total=False): spend_threshold_configuration: SpendThresholdConfiguration + spend_trackers: Iterable[SpendTracker] + """Spend trackers to attach to this contract. + + Aliases must be unique within a contract. + """ + subscriptions: Iterable[Subscription] """ Optional list of @@ -324,6 +333,16 @@ class CommitInvoiceSchedule(TypedDict, total=False): """Either provide amount or provide both unit_price and quantity.""" +class CommitSpendTrackerAttributes(TypedDict, total=False): + """Optional attributes for spend tracker integration. Immutable after creation.""" + + counts_as_discounted: Required[bool] + """ + If true, this commit will be included in spend trackers with discounted set to + DISCOUNTED_ONLY + """ + + class Commit(TypedDict, total=False): product_id: Required[str] @@ -395,6 +414,9 @@ class Commit(TypedDict, total=False): be used together with `applicable_product_ids` or `applicable_product_tags`. """ + spend_tracker_attributes: CommitSpendTrackerAttributes + """Optional attributes for spend tracker integration. Immutable after creation.""" + temporary_id: str """ A temporary ID for the commit that can be used to reference the commit for @@ -1242,6 +1264,26 @@ class ScheduledCharge(TypedDict, total=False): """This field's availability is dependent on your client's configuration.""" +class SpendTrackerApplicableSpendSpecifier(TypedDict, total=False): + sources: Required[List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]] + + spend_type: Required[Literal["COMMIT_PURCHASE"]] + + discounted: Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"] + """Filter by whether the spend was discounted. Defaults to ANY if omitted.""" + + +class SpendTracker(TypedDict, total=False): + alias: Required[str] + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: Required[Iterable[SpendTrackerApplicableSpendSpecifier]] + + credit_type_id: Required[str] + + reset_frequency: Required[Literal["BILLING_PERIOD"]] + + class SubscriptionProration(TypedDict, total=False): invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"] """ diff --git a/src/metronome/types/v1/contract_create_response.py b/src/metronome/types/v1/contract_create_response.py index 4e97367b9..26bff00a5 100644 --- a/src/metronome/types/v1/contract_create_response.py +++ b/src/metronome/types/v1/contract_create_response.py @@ -1,10 +1,432 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Dict, List, Optional +from datetime import datetime +from typing_extensions import Literal + from ..._models import BaseModel -from ..shared.id import ID +from ..shared.commit import Commit +from ..shared.credit import Credit +from ..shared.override import Override +from ..shared.subscription import Subscription +from ..shared.commit_specifier import CommitSpecifier +from ..shared.scheduled_charge import ScheduledCharge +from ..shared.hierarchy_configuration import HierarchyConfiguration +from ..shared.spend_threshold_configuration import SpendThresholdConfiguration +from ..shared.commit_hierarchy_configuration import CommitHierarchyConfiguration +from ..shared.recurring_commit_subscription_config import RecurringCommitSubscriptionConfig +from ..shared.prepaid_balance_threshold_configuration import PrepaidBalanceThresholdConfiguration + +__all__ = [ + "ContractCreateResponse", + "Data", + "DataContract", + "DataContractTransition", + "DataContractUsageFilter", + "DataContractUsageStatementSchedule", + "DataContractCustomerBillingProviderConfiguration", + "DataContractHasMore", + "DataContractRecurringCommit", + "DataContractRecurringCommitAccessAmount", + "DataContractRecurringCommitCommitDuration", + "DataContractRecurringCommitProduct", + "DataContractRecurringCommitContract", + "DataContractRecurringCommitInvoiceAmount", + "DataContractRecurringCredit", + "DataContractRecurringCreditAccessAmount", + "DataContractRecurringCreditCommitDuration", + "DataContractRecurringCreditProduct", + "DataContractRecurringCreditContract", +] + + +class DataContractTransition(BaseModel): + from_contract_id: str + + to_contract_id: str + + type: Literal["SUPERSEDE", "RENEWAL"] + + +class DataContractUsageFilter(BaseModel): + group_key: str + + group_values: List[str] + + starting_at: datetime + + ending_before: Optional[datetime] = None + + +class DataContractUsageStatementSchedule(BaseModel): + billing_anchor_date: datetime + """Contract usage statements follow a selected cadence based on this date.""" + + frequency: Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"] + + +class DataContractCustomerBillingProviderConfiguration(BaseModel): + """The billing provider configuration associated with the contract.""" + + id: Optional[str] = None + + billing_provider: Optional[ + Literal[ + "aws_marketplace", + "stripe", + "netsuite", + "custom", + "azure_marketplace", + "quickbooks_online", + "workday", + "gcp_marketplace", + "metronome", + ] + ] = None + + delivery_method: Optional[Literal["direct_to_billing_provider", "aws_sqs", "tackle", "aws_sns"]] = None + + +class DataContractHasMore(BaseModel): + """Indicates whether there are more items than the limit for this endpoint. + + Use the respective list endpoints to get the full lists. + """ + + commits: bool + """Whether there are more commits on this contract than the limit for this + endpoint. + + Use the /contracts/customerCommits/list endpoint to get the full list of + commits. + """ + + credits: bool + """Whether there are more credits on this contract than the limit for this + endpoint. + + Use the /contracts/customerCredits/list endpoint to get the full list of + credits. + """ + + +class DataContractRecurringCommitAccessAmount(BaseModel): + """The amount of commit to grant.""" + + credit_type_id: str + + unit_price: float + + quantity: Optional[float] = None + + +class DataContractRecurringCommitCommitDuration(BaseModel): + """The amount of time the created commits will be valid for""" + + value: float + + unit: Optional[Literal["PERIODS"]] = None + + +class DataContractRecurringCommitProduct(BaseModel): + id: str + + name: str + + +class DataContractRecurringCommitContract(BaseModel): + id: str + + +class DataContractRecurringCommitInvoiceAmount(BaseModel): + """The amount the customer should be billed for the commit. Not required.""" + + credit_type_id: str + + quantity: float + + unit_price: float + + +class DataContractRecurringCommit(BaseModel): + id: str + + access_amount: DataContractRecurringCommitAccessAmount + """The amount of commit to grant.""" + + commit_duration: DataContractRecurringCommitCommitDuration + """The amount of time the created commits will be valid for""" + + priority: float + """Will be passed down to the individual commits""" + + product: DataContractRecurringCommitProduct + + rate_type: Literal["COMMIT_RATE", "LIST_RATE"] + """Whether the created commits will use the commit rate or list rate""" + + starting_at: datetime + """Determines the start time for the first commit""" + + applicable_product_ids: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + applicable_product_tags: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + contract: Optional[DataContractRecurringCommitContract] = None + + description: Optional[str] = None + """Will be passed down to the individual commits""" + + ending_before: Optional[datetime] = None + """Determines when the contract will stop creating recurring commits. Optional""" + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for recurring commit/credit hierarchy access control""" + + invoice_amount: Optional[DataContractRecurringCommitInvoiceAmount] = None + """The amount the customer should be billed for the commit. Not required.""" + + name: Optional[str] = None + """Displayed on invoices. Will be passed through to the individual commits""" + + netsuite_sales_order_id: Optional[str] = None + """Will be passed down to the individual commits""" + + proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None + """Determines whether the first and last commit will be prorated. + + If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and + last commits). + """ + + recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None + """The frequency at which the recurring commits will be created. + + If not provided: - The commits will be created on the usage invoice frequency. + If provided: - The period defined in the duration will correspond to this + frequency. - Commits will be created aligned with the recurring commit's + starting_at rather than the usage invoice dates. + """ + + rollover_fraction: Optional[float] = None + """Will be passed down to the individual commits. + + This controls how much of an individual unexpired commit will roll over upon + contract transition. Must be between 0 and 1. + """ + + specifiers: Optional[List[CommitSpecifier]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. + """ + + subscription_config: Optional[RecurringCommitSubscriptionConfig] = None + """Attach a subscription to the recurring commit/credit.""" + + +class DataContractRecurringCreditAccessAmount(BaseModel): + """The amount of commit to grant.""" + + credit_type_id: str + + unit_price: float + + quantity: Optional[float] = None + + +class DataContractRecurringCreditCommitDuration(BaseModel): + """The amount of time the created commits will be valid for""" + + value: float + + unit: Optional[Literal["PERIODS"]] = None + + +class DataContractRecurringCreditProduct(BaseModel): + id: str + + name: str + + +class DataContractRecurringCreditContract(BaseModel): + id: str + + +class DataContractRecurringCredit(BaseModel): + id: str + + access_amount: DataContractRecurringCreditAccessAmount + """The amount of commit to grant.""" + + commit_duration: DataContractRecurringCreditCommitDuration + """The amount of time the created commits will be valid for""" + + priority: float + """Will be passed down to the individual commits""" + + product: DataContractRecurringCreditProduct + + rate_type: Literal["COMMIT_RATE", "LIST_RATE"] + """Whether the created commits will use the commit rate or list rate""" + + starting_at: datetime + """Determines the start time for the first commit""" + + applicable_product_ids: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + applicable_product_tags: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + contract: Optional[DataContractRecurringCreditContract] = None + + description: Optional[str] = None + """Will be passed down to the individual commits""" + + ending_before: Optional[datetime] = None + """Determines when the contract will stop creating recurring commits. Optional""" + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for recurring commit/credit hierarchy access control""" + + name: Optional[str] = None + """Displayed on invoices. Will be passed through to the individual commits""" + + netsuite_sales_order_id: Optional[str] = None + """Will be passed down to the individual commits""" + + proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None + """Determines whether the first and last commit will be prorated. + + If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and + last commits). + """ + + recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None + """The frequency at which the recurring commits will be created. + + If not provided: - The commits will be created on the usage invoice frequency. + If provided: - The period defined in the duration will correspond to this + frequency. - Commits will be created aligned with the recurring commit's + starting_at rather than the usage invoice dates. + """ + + rollover_fraction: Optional[float] = None + """Will be passed down to the individual commits. + + This controls how much of an individual unexpired commit will roll over upon + contract transition. Must be between 0 and 1. + """ + + specifiers: Optional[List[CommitSpecifier]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. + """ + + subscription_config: Optional[RecurringCommitSubscriptionConfig] = None + """Attach a subscription to the recurring commit/credit.""" + + +class DataContract(BaseModel): + """The created contract.""" + + id: str + + commits: List[Commit] + + created_at: datetime + + created_by: str + + customer_id: str + + overrides: List[Override] + + scheduled_charges: List[ScheduledCharge] + + starting_at: datetime + + transitions: List[DataContractTransition] + + usage_filter: List[DataContractUsageFilter] + + usage_statement_schedule: DataContractUsageStatementSchedule + + credits: Optional[List[Credit]] = None + + custom_fields: Optional[Dict[str, str]] = None + """Custom fields to be added eg. { "key1": "value1", "key2": "value2" }""" + + customer_billing_provider_configuration: Optional[DataContractCustomerBillingProviderConfiguration] = None + """The billing provider configuration associated with the contract.""" + + ending_before: Optional[datetime] = None + + has_more: Optional[DataContractHasMore] = None + """Indicates whether there are more items than the limit for this endpoint. + + Use the respective list endpoints to get the full lists. + """ + + hierarchy_configuration: Optional[HierarchyConfiguration] = None + """ + Either a **parent** configuration with a list of children or a **child** + configuration with a single parent. + """ + + multiplier_override_prioritization: Optional[Literal["LOWEST_MULTIPLIER", "EXPLICIT"]] = None + """ + Defaults to LOWEST_MULTIPLIER, which applies the greatest discount to list + prices automatically. EXPLICIT prioritization requires specifying priorities for + each multiplier; the one with the lowest priority value will be prioritized + first. + """ + + name: Optional[str] = None + + net_payment_terms_days: Optional[float] = None + + package_id: Optional[str] = None + """ID of the package this contract was created from, if applicable.""" + + prepaid_balance_threshold_configuration: Optional[PrepaidBalanceThresholdConfiguration] = None + + rate_card_id: Optional[str] = None + + recurring_commits: Optional[List[DataContractRecurringCommit]] = None + + recurring_credits: Optional[List[DataContractRecurringCredit]] = None + + scheduled_charges_on_usage_invoices: Optional[Literal["ALL"]] = None + """ + Determines which scheduled and commit charges to consolidate onto the Contract's + usage invoice. The charge's `timestamp` must match the usage invoice's + `ending_before` date for consolidation to occur. This field cannot be modified + after a Contract has been created. If this field is omitted, charges will appear + on a separate invoice from usage charges. + """ + + spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None + + subscriptions: Optional[List[Subscription]] = None + """List of subscriptions on the contract.""" + + uniqueness_key: Optional[str] = None + """Optional uniqueness key to prevent duplicate contract creations.""" + + +class Data(BaseModel): + id: str -__all__ = ["ContractCreateResponse"] + contract: Optional[DataContract] = None + """The created contract.""" class ContractCreateResponse(BaseModel): - data: ID + data: Data diff --git a/src/metronome/types/v1/package_create_params.py b/src/metronome/types/v1/package_create_params.py index 240c57410..4817854a9 100644 --- a/src/metronome/types/v1/package_create_params.py +++ b/src/metronome/types/v1/package_create_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Dict, Union, Iterable +from typing import Dict, List, Union, Iterable from datetime import datetime from typing_extensions import Literal, Required, Annotated, TypedDict @@ -55,6 +55,8 @@ "ScheduledChargeSchedule", "ScheduledChargeScheduleScheduleItem", "ScheduledChargeScheduleScheduleItemDateOffset", + "SpendTracker", + "SpendTrackerApplicableSpendSpecifier", "Subscription", "SubscriptionProration", "SubscriptionSubscriptionRate", @@ -128,6 +130,8 @@ class PackageCreateParams(TypedDict, total=False): spend_threshold_configuration: SpendThresholdConfiguration + spend_trackers: Iterable[SpendTracker] + subscriptions: Iterable[Subscription] uniqueness_key: str @@ -912,6 +916,26 @@ class ScheduledCharge(TypedDict, total=False): """displayed on invoices""" +class SpendTrackerApplicableSpendSpecifier(TypedDict, total=False): + sources: Required[List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]] + + spend_type: Required[Literal["COMMIT_PURCHASE"]] + + discounted: Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"] + """Filter by whether the spend was discounted. Defaults to ANY if omitted.""" + + +class SpendTracker(TypedDict, total=False): + alias: Required[str] + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: Required[Iterable[SpendTrackerApplicableSpendSpecifier]] + + credit_type_id: Required[str] + + reset_frequency: Required[Literal["BILLING_PERIOD"]] + + class SubscriptionProration(TypedDict, total=False): invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"] """ diff --git a/src/metronome/types/v1/package_list_response.py b/src/metronome/types/v1/package_list_response.py index 0953958a0..08620fee9 100644 --- a/src/metronome/types/v1/package_list_response.py +++ b/src/metronome/types/v1/package_list_response.py @@ -59,6 +59,8 @@ "RecurringCreditDuration", "RecurringCreditSubscriptionConfig", "RecurringCreditSubscriptionConfigApplySeatIncreaseConfig", + "SpendTracker", + "SpendTrackerApplicableSpendSpecifier", "Subscription", "SubscriptionProration", "SubscriptionSubscriptionRate", @@ -645,6 +647,25 @@ class RecurringCredit(BaseModel): """Attach a subscription to the recurring commit/credit.""" +class SpendTrackerApplicableSpendSpecifier(BaseModel): + sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]] + + spend_type: Literal["COMMIT_PURCHASE"] + + discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None + + +class SpendTracker(BaseModel): + alias: str + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier] + + credit_type_id: str + + reset_frequency: Literal["BILLING_PERIOD"] + + class SubscriptionProration(BaseModel): invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"] @@ -800,6 +821,8 @@ class PackageListResponse(BaseModel): spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None + spend_trackers: Optional[List[SpendTracker]] = None + subscriptions: Optional[List[Subscription]] = None uniqueness_key: Optional[str] = None diff --git a/src/metronome/types/v1/package_retrieve_response.py b/src/metronome/types/v1/package_retrieve_response.py index c6b5ca4c0..7d73c1721 100644 --- a/src/metronome/types/v1/package_retrieve_response.py +++ b/src/metronome/types/v1/package_retrieve_response.py @@ -60,6 +60,8 @@ "DataRecurringCreditDuration", "DataRecurringCreditSubscriptionConfig", "DataRecurringCreditSubscriptionConfigApplySeatIncreaseConfig", + "DataSpendTracker", + "DataSpendTrackerApplicableSpendSpecifier", "DataSubscription", "DataSubscriptionProration", "DataSubscriptionSubscriptionRate", @@ -646,6 +648,25 @@ class DataRecurringCredit(BaseModel): """Attach a subscription to the recurring commit/credit.""" +class DataSpendTrackerApplicableSpendSpecifier(BaseModel): + sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]] + + spend_type: Literal["COMMIT_PURCHASE"] + + discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None + + +class DataSpendTracker(BaseModel): + alias: str + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: List[DataSpendTrackerApplicableSpendSpecifier] + + credit_type_id: str + + reset_frequency: Literal["BILLING_PERIOD"] + + class DataSubscriptionProration(BaseModel): invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"] @@ -801,6 +822,8 @@ class Data(BaseModel): spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None + spend_trackers: Optional[List[DataSpendTracker]] = None + subscriptions: Optional[List[DataSubscription]] = None uniqueness_key: Optional[str] = None diff --git a/src/metronome/types/v1/payment.py b/src/metronome/types/v1/payment.py deleted file mode 100644 index ce3aab66a..000000000 --- a/src/metronome/types/v1/payment.py +++ /dev/null @@ -1,72 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import datetime -from typing_extensions import Literal - -from ..._models import BaseModel -from .payment_status import PaymentStatus -from ..shared.credit_type_data import CreditTypeData - -__all__ = ["Payment", "PaymentGateway", "PaymentGatewayStripe", "PaymentGatewayStripeError", "RevenueSystemPayment"] - - -class PaymentGatewayStripeError(BaseModel): - code: Optional[str] = None - - decline_code: Optional[str] = None - - type: Optional[str] = None - - -class PaymentGatewayStripe(BaseModel): - payment_intent_id: str - - error: Optional[PaymentGatewayStripeError] = None - - payment_method_id: Optional[str] = None - - -class PaymentGateway(BaseModel): - stripe: PaymentGatewayStripe - - type: Literal["stripe"] - - -class RevenueSystemPayment(BaseModel): - revenue_system_provider: str - - sync_status: str - - error_message: Optional[str] = None - """The error message from the revenue system, if available.""" - - revenue_system_external_payment_id: Optional[str] = None - - -class Payment(BaseModel): - id: str - - amount: Optional[float] = None - - amount_paid: Optional[float] = None - - contract_id: Optional[str] = None - - created_at: Optional[datetime] = None - - customer_id: Optional[str] = None - - error_message: Optional[str] = None - - fiat_credit_type: Optional[CreditTypeData] = None - - invoice_id: Optional[str] = None - - payment_gateway: Optional[PaymentGateway] = None - - revenue_system_payments: Optional[List[RevenueSystemPayment]] = None - - status: Optional[PaymentStatus] = None - - updated_at: Optional[datetime] = None diff --git a/src/metronome/types/v1/payment_attempt_params.py b/src/metronome/types/v1/payment_attempt_params.py deleted file mode 100644 index 1579e3a16..000000000 --- a/src/metronome/types/v1/payment_attempt_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["PaymentAttemptParams"] - - -class PaymentAttemptParams(TypedDict, total=False): - customer_id: Required[str] - - invoice_id: Required[str] diff --git a/src/metronome/types/v1/payment_attempt_response.py b/src/metronome/types/v1/payment_attempt_response.py deleted file mode 100644 index 52c45c158..000000000 --- a/src/metronome/types/v1/payment_attempt_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .payment import Payment -from ..._models import BaseModel - -__all__ = ["PaymentAttemptResponse"] - - -class PaymentAttemptResponse(BaseModel): - data: Payment diff --git a/src/metronome/types/v1/payment_cancel_params.py b/src/metronome/types/v1/payment_cancel_params.py deleted file mode 100644 index b3666f14d..000000000 --- a/src/metronome/types/v1/payment_cancel_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["PaymentCancelParams"] - - -class PaymentCancelParams(TypedDict, total=False): - customer_id: Required[str] - - invoice_id: Required[str] diff --git a/src/metronome/types/v1/payment_cancel_response.py b/src/metronome/types/v1/payment_cancel_response.py deleted file mode 100644 index 12305d77b..000000000 --- a/src/metronome/types/v1/payment_cancel_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .payment import Payment -from ..._models import BaseModel - -__all__ = ["PaymentCancelResponse"] - - -class PaymentCancelResponse(BaseModel): - data: Payment diff --git a/src/metronome/types/v1/payment_list_params.py b/src/metronome/types/v1/payment_list_params.py deleted file mode 100644 index e9a9fe8ea..000000000 --- a/src/metronome/types/v1/payment_list_params.py +++ /dev/null @@ -1,24 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List -from typing_extensions import Required, TypedDict - -from .payment_status import PaymentStatus - -__all__ = ["PaymentListParams"] - - -class PaymentListParams(TypedDict, total=False): - customer_id: Required[str] - - invoice_id: Required[str] - - limit: int - """The maximum number of payments to return. Defaults to 25.""" - - next_page: str - """The next page token from a previous response.""" - - statuses: List[PaymentStatus] diff --git a/src/metronome/types/v1/payment_status.py b/src/metronome/types/v1/payment_status.py deleted file mode 100644 index f348de544..000000000 --- a/src/metronome/types/v1/payment_status.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal, TypeAlias - -__all__ = ["PaymentStatus"] - -PaymentStatus: TypeAlias = Literal["pending", "requires_intervention", "paid", "canceled"] diff --git a/src/metronome/types/v2/contract_edit_params.py b/src/metronome/types/v2/contract_edit_params.py index 2eed1710e..caa52466e 100644 --- a/src/metronome/types/v2/contract_edit_params.py +++ b/src/metronome/types/v2/contract_edit_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Dict, Union, Iterable, Optional +from typing import Dict, List, Union, Iterable, Optional from datetime import datetime from typing_extensions import Literal, Required, Annotated, TypedDict @@ -30,6 +30,7 @@ "AddCommitPaymentGateConfig", "AddCommitPaymentGateConfigPrecalculatedTaxConfig", "AddCommitPaymentGateConfigStripeConfig", + "AddCommitSpendTrackerAttributes", "AddCredit", "AddCreditAccessSchedule", "AddCreditAccessScheduleScheduleItem", @@ -63,6 +64,8 @@ "AddScheduledChargeSchedule", "AddScheduledChargeScheduleRecurringSchedule", "AddScheduledChargeScheduleScheduleItem", + "AddSpendTracker", + "AddSpendTrackerApplicableSpendSpecifier", "AddSubscription", "AddSubscriptionProration", "AddSubscriptionSubscriptionRate", @@ -88,6 +91,10 @@ "UpdatePrepaidBalanceThresholdConfiguration", "UpdatePrepaidBalanceThresholdConfigurationCommit", "UpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration", + "UpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap", + "UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier", + "UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude", + "UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter", "UpdateRecurringCommit", "UpdateRecurringCommitAccessAmount", "UpdateRecurringCommitInvoiceAmount", @@ -100,6 +107,7 @@ "UpdateScheduledChargeInvoiceScheduleUpdateScheduleItem", "UpdateSpendThresholdConfiguration", "UpdateSpendThresholdConfigurationDiscountConfiguration", + "UpdateSpendThresholdConfigurationDiscountConfigurationCap", "UpdateSubscription", "UpdateSubscriptionQuantityManagementModeUpdate", "UpdateSubscriptionQuantityManagementModeUpdateSeatConfig", @@ -156,6 +164,12 @@ class ContractEditParams(TypedDict, total=False): add_spend_threshold_configuration: SpendThresholdConfigurationV2 + add_spend_trackers: Iterable[AddSpendTracker] + """Spend trackers to add to this contract. + + Aliases must be unique within a contract. + """ + add_subscriptions: Iterable[AddSubscription] """ Optional list of @@ -180,6 +194,9 @@ class ContractEditParams(TypedDict, total=False): archive_scheduled_charges: Iterable[ArchiveScheduledCharge] """IDs of scheduled charges to archive""" + archive_spend_trackers: SequenceNotStr[str] + """Aliases of spend trackers to archive.""" + remove_overrides: Iterable[RemoveOverride] """IDs of overrides to remove""" @@ -451,6 +468,16 @@ class AddCommitPaymentGateConfig(TypedDict, total=False): """ +class AddCommitSpendTrackerAttributes(TypedDict, total=False): + """Optional attributes for spend tracker integration. Immutable after creation.""" + + counts_as_discounted: Required[bool] + """ + If true, this commit will be included in spend trackers with discounted set to + DISCOUNTED_ONLY + """ + + class AddCommit(TypedDict, total=False): product_id: Required[str] @@ -527,6 +554,9 @@ class AddCommit(TypedDict, total=False): body of `specifiers`. """ + spend_tracker_attributes: AddCommitSpendTrackerAttributes + """Optional attributes for spend tracker integration. Immutable after creation.""" + temporary_id: str """ A temporary ID for the commit that can be used to reference the commit for @@ -1323,6 +1353,26 @@ class AddScheduledCharge(TypedDict, total=False): """This field's availability is dependent on your client's configuration.""" +class AddSpendTrackerApplicableSpendSpecifier(TypedDict, total=False): + sources: Required[List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]] + + spend_type: Required[Literal["COMMIT_PURCHASE"]] + + discounted: Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"] + """Filter by whether the spend was discounted. Defaults to ANY if omitted.""" + + +class AddSpendTracker(TypedDict, total=False): + alias: Required[str] + """Human-readable identifier, unique per contract.""" + + applicable_spend_specifiers: Required[Iterable[AddSpendTrackerApplicableSpendSpecifier]] + + credit_type_id: Required[str] + + reset_frequency: Required[Literal["BILLING_PERIOD"]] + + class AddSubscriptionProration(TypedDict, total=False): invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"] """ @@ -1643,7 +1693,20 @@ class UpdatePrepaidBalanceThresholdConfigurationCommit(UpdateBaseThresholdCommit """ +class UpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap(TypedDict, total=False): + """Update the discount cap. Set to null to remove an existing cap.""" + + amount: Required[float] + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: Required[str] + """Alias of the spend tracker this cap is measured against.""" + + class UpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(TypedDict, total=False): + cap: Optional[UpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap] + """Update the discount cap. Set to null to remove an existing cap.""" + payment_fraction: Optional[float] """ The fraction of the original amount that the customer pays after applying the @@ -1652,6 +1715,26 @@ class UpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(TypedDict, """ +class UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter( + TypedDict, total=False +): + entity: Required[Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]] + + key: Required[str] + + value: Required[str] + + +class UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude(TypedDict, total=False): + custom_field_filters: Required[ + Iterable[UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter] + ] + + +class UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier(TypedDict, total=False): + exclude: Required[Iterable[UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude]] + + class UpdatePrepaidBalanceThresholdConfiguration(TypedDict, total=False): commit: UpdatePrepaidBalanceThresholdConfigurationCommit @@ -1682,6 +1765,10 @@ class UpdatePrepaidBalanceThresholdConfiguration(TypedDict, total=False): be initiated. """ + threshold_balance_specifiers: Optional[ + Iterable[UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier] + ] + class UpdateRecurringCommitAccessAmount(TypedDict, total=False): quantity: float @@ -1773,7 +1860,20 @@ class UpdateScheduledCharge(TypedDict, total=False): netsuite_sales_order_id: Optional[str] +class UpdateSpendThresholdConfigurationDiscountConfigurationCap(TypedDict, total=False): + """Update the discount cap. Set to null to remove an existing cap.""" + + amount: Required[float] + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: Required[str] + """Alias of the spend tracker this cap is measured against.""" + + class UpdateSpendThresholdConfigurationDiscountConfiguration(TypedDict, total=False): + cap: Optional[UpdateSpendThresholdConfigurationDiscountConfigurationCap] + """Update the discount cap. Set to null to remove an existing cap.""" + payment_fraction: Optional[float] """ The fraction of the original amount that the customer pays after applying the diff --git a/src/metronome/types/v2/contract_edit_response.py b/src/metronome/types/v2/contract_edit_response.py index c6d671161..843ed332f 100644 --- a/src/metronome/types/v2/contract_edit_response.py +++ b/src/metronome/types/v2/contract_edit_response.py @@ -1,10 +1,1475 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Dict, List, Optional +from datetime import datetime +from typing_extensions import Literal + from ..._models import BaseModel -from ..shared.id import ID +from ..shared.tier import Tier +from ..shared.discount import Discount +from ..shared.pro_service import ProService +from ..shared.override_tier import OverrideTier +from ..shared.commit_specifier import CommitSpecifier +from ..shared.credit_type_data import CreditTypeData +from ..shared.schedule_duration import ScheduleDuration +from ..shared.commit_specifier_input import CommitSpecifierInput +from ..shared.payment_gate_config_v2 import PaymentGateConfigV2 +from ..shared.schedule_point_in_time import SchedulePointInTime +from ..shared.update_base_threshold_commit import UpdateBaseThresholdCommit +from ..shared.commit_hierarchy_configuration import CommitHierarchyConfiguration +from ..shared.spend_threshold_configuration_v2 import SpendThresholdConfigurationV2 +from ..shared.recurring_commit_subscription_config import RecurringCommitSubscriptionConfig +from ..shared.prepaid_balance_threshold_configuration_v2 import PrepaidBalanceThresholdConfigurationV2 + +__all__ = [ + "ContractEditResponse", + "Data", + "DataEdit", + "DataEditAddCommit", + "DataEditAddCommitProduct", + "DataEditAddCommitInvoiceSchedule", + "DataEditAddCommitInvoiceScheduleScheduleItem", + "DataEditAddCredit", + "DataEditAddCreditProduct", + "DataEditAddOverride", + "DataEditAddOverrideOverrideSpecifier", + "DataEditAddOverrideOverwriteRate", + "DataEditAddOverrideProduct", + "DataEditAddRecurringCommit", + "DataEditAddRecurringCommitAccessAmount", + "DataEditAddRecurringCommitCommitDuration", + "DataEditAddRecurringCommitProduct", + "DataEditAddRecurringCommitContract", + "DataEditAddRecurringCommitInvoiceAmount", + "DataEditAddRecurringCredit", + "DataEditAddRecurringCreditAccessAmount", + "DataEditAddRecurringCreditCommitDuration", + "DataEditAddRecurringCreditProduct", + "DataEditAddRecurringCreditContract", + "DataEditAddResellerRoyalty", + "DataEditAddScheduledCharge", + "DataEditAddScheduledChargeProduct", + "DataEditAddSubscription", + "DataEditAddSubscriptionBillingPeriods", + "DataEditAddSubscriptionBillingPeriodsCurrent", + "DataEditAddSubscriptionBillingPeriodsNext", + "DataEditAddSubscriptionBillingPeriodsPrevious", + "DataEditAddSubscriptionProration", + "DataEditAddSubscriptionQuantitySchedule", + "DataEditAddSubscriptionSubscriptionRate", + "DataEditAddSubscriptionSubscriptionRateProduct", + "DataEditAddSubscriptionSeatConfig", + "DataEditAddUsageFilter", + "DataEditArchiveCommit", + "DataEditArchiveCredit", + "DataEditArchiveScheduledCharge", + "DataEditRemoveOverride", + "DataEditUpdateCommit", + "DataEditUpdateCommitAccessSchedule", + "DataEditUpdateCommitAccessScheduleAddScheduleItem", + "DataEditUpdateCommitAccessScheduleRemoveScheduleItem", + "DataEditUpdateCommitAccessScheduleUpdateScheduleItem", + "DataEditUpdateCommitInvoiceSchedule", + "DataEditUpdateCommitInvoiceScheduleAddScheduleItem", + "DataEditUpdateCommitInvoiceScheduleRemoveScheduleItem", + "DataEditUpdateCommitInvoiceScheduleUpdateScheduleItem", + "DataEditUpdateCredit", + "DataEditUpdateCreditAccessSchedule", + "DataEditUpdateCreditAccessScheduleAddScheduleItem", + "DataEditUpdateCreditAccessScheduleRemoveScheduleItem", + "DataEditUpdateCreditAccessScheduleUpdateScheduleItem", + "DataEditUpdateDiscount", + "DataEditUpdateDiscountSchedule", + "DataEditUpdateDiscountScheduleRecurringSchedule", + "DataEditUpdateDiscountScheduleScheduleItem", + "DataEditUpdatePrepaidBalanceThresholdConfiguration", + "DataEditUpdatePrepaidBalanceThresholdConfigurationCommit", + "DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration", + "DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap", + "DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier", + "DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude", + "DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter", + "DataEditUpdateRecurringCommit", + "DataEditUpdateRecurringCommitAccessAmount", + "DataEditUpdateRecurringCommitInvoiceAmount", + "DataEditUpdateRecurringCredit", + "DataEditUpdateRecurringCreditAccessAmount", + "DataEditUpdateRefundInvoice", + "DataEditUpdateScheduledCharge", + "DataEditUpdateScheduledChargeInvoiceSchedule", + "DataEditUpdateScheduledChargeInvoiceScheduleAddScheduleItem", + "DataEditUpdateScheduledChargeInvoiceScheduleRemoveScheduleItem", + "DataEditUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem", + "DataEditUpdateSpendThresholdConfiguration", + "DataEditUpdateSpendThresholdConfigurationDiscountConfiguration", + "DataEditUpdateSpendThresholdConfigurationDiscountConfigurationCap", + "DataEditUpdateSubscription", + "DataEditUpdateSubscriptionQuantityUpdate", + "DataEditUpdateSubscriptionSeatUpdates", + "DataEditUpdateSubscriptionSeatUpdatesAddSeatID", + "DataEditUpdateSubscriptionSeatUpdatesAddUnassignedSeat", + "DataEditUpdateSubscriptionSeatUpdatesRemoveSeatID", + "DataEditUpdateSubscriptionSeatUpdatesRemoveUnassignedSeat", +] + + +class DataEditAddCommitProduct(BaseModel): + id: str + + name: str + + +class DataEditAddCommitInvoiceScheduleScheduleItem(BaseModel): + id: str + + timestamp: datetime + + amount: Optional[float] = None + + invoice_id: Optional[str] = None + + quantity: Optional[float] = None + + unit_price: Optional[float] = None + + +class DataEditAddCommitInvoiceSchedule(BaseModel): + """The schedule that the customer will be invoiced for this commit.""" + + credit_type: Optional[CreditTypeData] = None + + do_not_invoice: Optional[bool] = None + """If true, this schedule will not generate an invoice.""" + + schedule_items: Optional[List[DataEditAddCommitInvoiceScheduleScheduleItem]] = None + + +class DataEditAddCommit(BaseModel): + id: str + + product: DataEditAddCommitProduct + + type: Literal["PREPAID", "POSTPAID"] + + access_schedule: Optional[ScheduleDuration] = None + """ + The schedule that the customer will gain access to the credits purposed with + this commit. + """ + + applicable_product_ids: Optional[List[str]] = None + + applicable_product_tags: Optional[List[str]] = None + + description: Optional[str] = None + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for commit hierarchy access control""" + + invoice_schedule: Optional[DataEditAddCommitInvoiceSchedule] = None + """The schedule that the customer will be invoiced for this commit.""" + + name: Optional[str] = None + + netsuite_sales_order_id: Optional[str] = None + """This field's availability is dependent on your client's configuration.""" + + priority: Optional[float] = None + """ + If multiple credits or commits are applicable, the one with the lower priority + will apply first. + """ + + rate_type: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None + + rollover_fraction: Optional[float] = None + + salesforce_opportunity_id: Optional[str] = None + """This field's availability is dependent on your client's configuration.""" + + specifiers: Optional[List[CommitSpecifierInput]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. This field cannot + be used together with `applicable_product_ids` or `applicable_product_tags`. + Instead, to target usage by product or product tag, pass those values in the + body of `specifiers`. + """ + + +class DataEditAddCreditProduct(BaseModel): + id: str + + name: str + + +class DataEditAddCredit(BaseModel): + id: str + + product: DataEditAddCreditProduct + + type: Literal["CREDIT"] + + access_schedule: Optional[ScheduleDuration] = None + """The schedule that the customer will gain access to the credits.""" + + applicable_product_ids: Optional[List[str]] = None + + applicable_product_tags: Optional[List[str]] = None + + description: Optional[str] = None + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for recurring credit hierarchy access control""" + + name: Optional[str] = None + + netsuite_sales_order_id: Optional[str] = None + """This field's availability is dependent on your client's configuration.""" + + priority: Optional[float] = None + """ + If multiple credits or commits are applicable, the one with the lower priority + will apply first. + """ + + rate_type: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None + + rollover_fraction: Optional[float] = None + + salesforce_opportunity_id: Optional[str] = None + """This field's availability is dependent on your client's configuration.""" + + specifiers: Optional[List[CommitSpecifierInput]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. This field cannot + be used together with `applicable_product_ids` or `applicable_product_tags`. + Instead, to target usage by product or product tag, pass those values in the + body of `specifiers`. + """ + + +class DataEditAddOverrideOverrideSpecifier(BaseModel): + billing_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None + + commit_ids: Optional[List[str]] = None + + presentation_group_values: Optional[Dict[str, Optional[str]]] = None + + pricing_group_values: Optional[Dict[str, str]] = None + + product_id: Optional[str] = None + + product_tags: Optional[List[str]] = None + + recurring_commit_ids: Optional[List[str]] = None + + +class DataEditAddOverrideOverwriteRate(BaseModel): + rate_type: Literal["FLAT", "PERCENTAGE", "SUBSCRIPTION", "TIERED", "TIERED_PERCENTAGE", "CUSTOM"] + + credit_type: Optional[CreditTypeData] = None + + custom_rate: Optional[Dict[str, object]] = None + """Only set for CUSTOM rate_type. + + This field is interpreted by custom rate processors. + """ + + is_prorated: Optional[bool] = None + """Default proration configuration. + + Only valid for SUBSCRIPTION rate_type. Must be set to true. + """ + + price: Optional[float] = None + """Default price. + + For FLAT rate_type, this must be >=0. For PERCENTAGE rate_type, this is a + decimal fraction, e.g. use 0.1 for 10%; this must be >=0 and <=1. + """ + + quantity: Optional[float] = None + """Default quantity. For SUBSCRIPTION rate_type, this must be >=0.""" + + tiers: Optional[List[Tier]] = None + """Only set for TIERED rate_type.""" + + +class DataEditAddOverrideProduct(BaseModel): + id: str + + name: str + + +class DataEditAddOverride(BaseModel): + id: str + + created_at: datetime + + starting_at: datetime + + applicable_product_tags: Optional[List[str]] = None + + ending_before: Optional[datetime] = None + + entitled: Optional[bool] = None + + is_commit_specific: Optional[bool] = None + + multiplier: Optional[float] = None + + override_specifiers: Optional[List[DataEditAddOverrideOverrideSpecifier]] = None + + override_tiers: Optional[List[OverrideTier]] = None + + overwrite_rate: Optional[DataEditAddOverrideOverwriteRate] = None + + priority: Optional[float] = None + + product: Optional[DataEditAddOverrideProduct] = None + + target: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None + + type: Optional[Literal["OVERWRITE", "MULTIPLIER", "TIERED"]] = None + + +class DataEditAddRecurringCommitAccessAmount(BaseModel): + """The amount of commit to grant.""" + + credit_type_id: str + + unit_price: float + + quantity: Optional[float] = None + + +class DataEditAddRecurringCommitCommitDuration(BaseModel): + """The amount of time the created commits will be valid for""" + + value: float + + unit: Optional[Literal["PERIODS"]] = None + + +class DataEditAddRecurringCommitProduct(BaseModel): + id: str + + name: str + + +class DataEditAddRecurringCommitContract(BaseModel): + id: str + + +class DataEditAddRecurringCommitInvoiceAmount(BaseModel): + """The amount the customer should be billed for the commit. Not required.""" + + credit_type_id: str + + quantity: float + + unit_price: float + + +class DataEditAddRecurringCommit(BaseModel): + id: str + + access_amount: DataEditAddRecurringCommitAccessAmount + """The amount of commit to grant.""" + + commit_duration: DataEditAddRecurringCommitCommitDuration + """The amount of time the created commits will be valid for""" + + priority: float + """Will be passed down to the individual commits""" + + product: DataEditAddRecurringCommitProduct + + rate_type: Literal["COMMIT_RATE", "LIST_RATE"] + """Whether the created commits will use the commit rate or list rate""" + + starting_at: datetime + """Determines the start time for the first commit""" + + applicable_product_ids: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + applicable_product_tags: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + contract: Optional[DataEditAddRecurringCommitContract] = None + + description: Optional[str] = None + """Will be passed down to the individual commits""" + + ending_before: Optional[datetime] = None + """Determines when the contract will stop creating recurring commits. Optional""" + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for recurring credit hierarchy access control""" + + invoice_amount: Optional[DataEditAddRecurringCommitInvoiceAmount] = None + """The amount the customer should be billed for the commit. Not required.""" + + name: Optional[str] = None + """Displayed on invoices. Will be passed through to the individual commits""" + + netsuite_sales_order_id: Optional[str] = None + """Will be passed down to the individual commits""" + + proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None + """Determines whether the first and last commit will be prorated. + + If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and + last commits). + """ + + recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None + """The frequency at which the recurring commits will be created. + + If not provided: - The commits will be created on the usage invoice frequency. + If provided: - The period defined in the duration will correspond to this + frequency. - Commits will be created aligned with the recurring commit's + starting_at rather than the usage invoice dates. + """ + + rollover_fraction: Optional[float] = None + """Will be passed down to the individual commits. + + This controls how much of an individual unexpired commit will roll over upon + contract transition. Must be between 0 and 1. + """ + + specifiers: Optional[List[CommitSpecifier]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. + """ + + subscription_config: Optional[RecurringCommitSubscriptionConfig] = None + """Attach a subscription to the recurring commit/credit.""" + + +class DataEditAddRecurringCreditAccessAmount(BaseModel): + """The amount of commit to grant.""" + + credit_type_id: str + + unit_price: float + + quantity: Optional[float] = None + + +class DataEditAddRecurringCreditCommitDuration(BaseModel): + """The amount of time the created commits will be valid for""" + + value: float + + unit: Optional[Literal["PERIODS"]] = None + + +class DataEditAddRecurringCreditProduct(BaseModel): + id: str + + name: str + + +class DataEditAddRecurringCreditContract(BaseModel): + id: str + + +class DataEditAddRecurringCredit(BaseModel): + id: str + + access_amount: DataEditAddRecurringCreditAccessAmount + """The amount of commit to grant.""" + + commit_duration: DataEditAddRecurringCreditCommitDuration + """The amount of time the created commits will be valid for""" + + priority: float + """Will be passed down to the individual commits""" + + product: DataEditAddRecurringCreditProduct + + rate_type: Literal["COMMIT_RATE", "LIST_RATE"] + """Whether the created commits will use the commit rate or list rate""" + + starting_at: datetime + """Determines the start time for the first commit""" + + applicable_product_ids: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + applicable_product_tags: Optional[List[str]] = None + """Will be passed down to the individual commits""" + + contract: Optional[DataEditAddRecurringCreditContract] = None + + description: Optional[str] = None + """Will be passed down to the individual commits""" + + ending_before: Optional[datetime] = None + """Determines when the contract will stop creating recurring commits. Optional""" + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for recurring credit hierarchy access control""" + + name: Optional[str] = None + """Displayed on invoices. Will be passed through to the individual commits""" + + netsuite_sales_order_id: Optional[str] = None + """Will be passed down to the individual commits""" + + proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None + """Determines whether the first and last commit will be prorated. + + If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and + last commits). + """ + + recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None + """The frequency at which the recurring commits will be created. + + If not provided: - The commits will be created on the usage invoice frequency. + If provided: - The period defined in the duration will correspond to this + frequency. - Commits will be created aligned with the recurring commit's + starting_at rather than the usage invoice dates. + """ + + rollover_fraction: Optional[float] = None + """Will be passed down to the individual commits. + + This controls how much of an individual unexpired commit will roll over upon + contract transition. Must be between 0 and 1. + """ + + specifiers: Optional[List[CommitSpecifier]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. + """ + + subscription_config: Optional[RecurringCommitSubscriptionConfig] = None + """Attach a subscription to the recurring commit/credit.""" + + +class DataEditAddResellerRoyalty(BaseModel): + reseller_type: Literal["AWS", "AWS_PRO_SERVICE", "GCP", "GCP_PRO_SERVICE"] + + applicable_product_ids: Optional[List[str]] = None + + applicable_product_tags: Optional[List[str]] = None + + aws_account_number: Optional[str] = None + + aws_offer_id: Optional[str] = None + + aws_payer_reference_id: Optional[str] = None + + ending_before: Optional[datetime] = None + + fraction: Optional[float] = None + + gcp_account_id: Optional[str] = None + + gcp_offer_id: Optional[str] = None + + netsuite_reseller_id: Optional[str] = None + + reseller_contract_value: Optional[float] = None + + starting_at: Optional[datetime] = None + + +class DataEditAddScheduledChargeProduct(BaseModel): + id: str + + name: str + + +class DataEditAddScheduledCharge(BaseModel): + id: str + + product: DataEditAddScheduledChargeProduct + + schedule: SchedulePointInTime + + name: Optional[str] = None + """displayed on invoices""" + + netsuite_sales_order_id: Optional[str] = None + """This field's availability is dependent on your client's configuration.""" + + +class DataEditAddSubscriptionBillingPeriodsCurrent(BaseModel): + ending_before: datetime + + starting_at: datetime + + +class DataEditAddSubscriptionBillingPeriodsNext(BaseModel): + ending_before: datetime + + starting_at: datetime + + +class DataEditAddSubscriptionBillingPeriodsPrevious(BaseModel): + ending_before: datetime + + starting_at: datetime + + +class DataEditAddSubscriptionBillingPeriods(BaseModel): + """Previous, current, and next billing periods for the subscription.""" + + current: Optional[DataEditAddSubscriptionBillingPeriodsCurrent] = None + + next: Optional[DataEditAddSubscriptionBillingPeriodsNext] = None + + previous: Optional[DataEditAddSubscriptionBillingPeriodsPrevious] = None + + +class DataEditAddSubscriptionProration(BaseModel): + invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"] + + is_prorated: bool + + +class DataEditAddSubscriptionQuantitySchedule(BaseModel): + quantity: float + + starting_at: datetime + + ending_before: Optional[datetime] = None + + +class DataEditAddSubscriptionSubscriptionRateProduct(BaseModel): + id: str + + name: str + + +class DataEditAddSubscriptionSubscriptionRate(BaseModel): + billing_frequency: Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"] + + product: DataEditAddSubscriptionSubscriptionRateProduct + + +class DataEditAddSubscriptionSeatConfig(BaseModel): + seat_group_key: str + """ + The property name, sent on usage events, that identifies the seat ID associated + with the usage event. For example, the property name might be seat_id or + user_id. The property must be set as a group key on billable metrics and a + presentation/pricing group key on contract products. This allows linked + recurring credits with an allocation per seat to be consumed by only one seat's + usage. + """ + + +class DataEditAddSubscription(BaseModel): + billing_periods: DataEditAddSubscriptionBillingPeriods + """Previous, current, and next billing periods for the subscription.""" + + collection_schedule: Literal["ADVANCE", "ARREARS"] + + proration: DataEditAddSubscriptionProration + + quantity_management_mode: Literal["SEAT_BASED", "QUANTITY_ONLY"] + """Determines how the subscription's quantity is controlled. + + Defaults to QUANTITY_ONLY. **QUANTITY_ONLY**: The subscription quantity is + specified directly on the subscription. `initial_quantity` must be provided with + this option. Compatible with recurring commits/credits that use POOLED + allocation. **SEAT_BASED**: Use when you want to pass specific seat identifiers + (e.g. add user_123) to increment and decrement a subscription quantity, rather + than directly providing the quantity. You must use a **SEAT_BASED** subscription + to use a linked recurring credit with an allocation per seat. `seat_config` must + be provided with this option. + """ + + quantity_schedule: List[DataEditAddSubscriptionQuantitySchedule] + """List of quantity schedule items for the subscription. + + Only includes the current quantity and future quantity changes. + """ + + starting_at: datetime + + subscription_rate: DataEditAddSubscriptionSubscriptionRate + + id: Optional[str] = None + + custom_fields: Optional[Dict[str, str]] = None + """Custom fields to be added eg. { "key1": "value1", "key2": "value2" }""" + + description: Optional[str] = None + + ending_before: Optional[datetime] = None + + fiat_credit_type_id: Optional[str] = None + + name: Optional[str] = None + + seat_config: Optional[DataEditAddSubscriptionSeatConfig] = None + + +class DataEditAddUsageFilter(BaseModel): + group_key: str + + group_values: List[str] + + starting_at: datetime + """ + This will match contract starting_at value if usage filter is active from the + beginning of the contract. + """ + + ending_before: Optional[datetime] = None + """ + This will match contract ending_before value if usage filter is active until the + end of the contract. It will be undefined if the contract is open-ended. + """ + + +class DataEditArchiveCommit(BaseModel): + id: str + + +class DataEditArchiveCredit(BaseModel): + id: str + + +class DataEditArchiveScheduledCharge(BaseModel): + id: str + + +class DataEditRemoveOverride(BaseModel): + id: str + + +class DataEditUpdateCommitAccessScheduleAddScheduleItem(BaseModel): + amount: float + + ending_before: datetime + """RFC 3339 timestamp (exclusive)""" + + starting_at: datetime + """RFC 3339 timestamp (inclusive)""" + + +class DataEditUpdateCommitAccessScheduleRemoveScheduleItem(BaseModel): + id: str + + +class DataEditUpdateCommitAccessScheduleUpdateScheduleItem(BaseModel): + id: str + + amount: Optional[float] = None + + ending_before: Optional[datetime] = None + """RFC 3339 timestamp (exclusive)""" + + starting_at: Optional[datetime] = None + """RFC 3339 timestamp (inclusive)""" + + +class DataEditUpdateCommitAccessSchedule(BaseModel): + add_schedule_items: Optional[List[DataEditUpdateCommitAccessScheduleAddScheduleItem]] = None + + remove_schedule_items: Optional[List[DataEditUpdateCommitAccessScheduleRemoveScheduleItem]] = None + + update_schedule_items: Optional[List[DataEditUpdateCommitAccessScheduleUpdateScheduleItem]] = None + + +class DataEditUpdateCommitInvoiceScheduleAddScheduleItem(BaseModel): + timestamp: datetime + + amount: Optional[float] = None + + quantity: Optional[float] = None + + unit_price: Optional[float] = None + + +class DataEditUpdateCommitInvoiceScheduleRemoveScheduleItem(BaseModel): + id: str + + +class DataEditUpdateCommitInvoiceScheduleUpdateScheduleItem(BaseModel): + id: str + + amount: Optional[float] = None + + quantity: Optional[float] = None + + timestamp: Optional[datetime] = None + + unit_price: Optional[float] = None + + +class DataEditUpdateCommitInvoiceSchedule(BaseModel): + add_schedule_items: Optional[List[DataEditUpdateCommitInvoiceScheduleAddScheduleItem]] = None + + remove_schedule_items: Optional[List[DataEditUpdateCommitInvoiceScheduleRemoveScheduleItem]] = None + + update_schedule_items: Optional[List[DataEditUpdateCommitInvoiceScheduleUpdateScheduleItem]] = None + + +class DataEditUpdateCommit(BaseModel): + id: str + + access_schedule: Optional[DataEditUpdateCommitAccessSchedule] = None + + applicable_product_ids: Optional[List[str]] = None + """Which products the commit applies to. + + If applicable_product_ids, applicable_product_tags or specifiers are not + provided, the commit applies to all products. + """ + + applicable_product_tags: Optional[List[str]] = None + """Which tags the commit applies to. + + If applicable_product_ids, applicable_product_tags or specifiers are not + provided, the commit applies to all products. + """ + + description: Optional[str] = None + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for commit hierarchy access control""" + + invoice_schedule: Optional[DataEditUpdateCommitInvoiceSchedule] = None + + name: Optional[str] = None + + netsuite_sales_order_id: Optional[str] = None + + priority: Optional[float] = None + """ + If multiple commits are applicable, the one with the lower priority will apply + first. + """ + + product_id: Optional[str] = None + + rate_type: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None + """If set, the commit's rate type was updated to the specified value.""" + + rollover_fraction: Optional[float] = None + + specifiers: Optional[List[CommitSpecifierInput]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. This field cannot + be used together with `applicable_product_ids` or `applicable_product_tags`. + Instead, to target usage by product or product tag, pass those values in the + body of `specifiers`. + """ + + +class DataEditUpdateCreditAccessScheduleAddScheduleItem(BaseModel): + amount: float + + ending_before: datetime + """RFC 3339 timestamp (exclusive)""" + + starting_at: datetime + """RFC 3339 timestamp (inclusive)""" + + +class DataEditUpdateCreditAccessScheduleRemoveScheduleItem(BaseModel): + id: str + + +class DataEditUpdateCreditAccessScheduleUpdateScheduleItem(BaseModel): + id: str + + amount: Optional[float] = None + + ending_before: Optional[datetime] = None + """RFC 3339 timestamp (exclusive)""" + + starting_at: Optional[datetime] = None + """RFC 3339 timestamp (inclusive)""" + + +class DataEditUpdateCreditAccessSchedule(BaseModel): + add_schedule_items: Optional[List[DataEditUpdateCreditAccessScheduleAddScheduleItem]] = None + + remove_schedule_items: Optional[List[DataEditUpdateCreditAccessScheduleRemoveScheduleItem]] = None + + update_schedule_items: Optional[List[DataEditUpdateCreditAccessScheduleUpdateScheduleItem]] = None + + +class DataEditUpdateCredit(BaseModel): + id: str + + access_schedule: Optional[DataEditUpdateCreditAccessSchedule] = None + + applicable_product_ids: Optional[List[str]] = None + """Which products the credit applies to. + + If applicable_product_ids, applicable_product_tags or specifiers are not + provided, the credit applies to all products. + """ + + applicable_product_tags: Optional[List[str]] = None + """Which tags the credit applies to. + + If applicable_product_ids, applicable_product_tags or specifiers are not + provided, the credit applies to all products. + """ + + description: Optional[str] = None + + hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None + """Optional configuration for credit hierarchy access control""" + + name: Optional[str] = None + + netsuite_sales_order_id: Optional[str] = None + + priority: Optional[float] = None + """ + If multiple credits are applicable, the one with the lower priority will apply + first. + """ + + product_id: Optional[str] = None + + rate_type: Optional[Literal["LIST_RATE", "COMMIT_RATE"]] = None + """If set, the credit's rate type was updated to the specified value.""" + + rollover_fraction: Optional[float] = None + + specifiers: Optional[List[CommitSpecifierInput]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. This field cannot + be used together with `applicable_product_ids` or `applicable_product_tags`. + Instead, to target usage by product or product tag, pass those values in the + body of `specifiers`. + """ + + +class DataEditUpdateDiscountScheduleRecurringSchedule(BaseModel): + """Enter the unit price and quantity for the charge or instead only send the amount. + + If amount is sent, the unit price is assumed to be the amount and quantity is inferred to be 1. + """ + + amount_distribution: Literal["DIVIDED", "DIVIDED_ROUNDED", "EACH"] + + ending_before: datetime + """RFC 3339 timestamp (exclusive).""" + + frequency: Literal["MONTHLY", "QUARTERLY", "SEMI_ANNUAL", "ANNUAL", "WEEKLY"] + + starting_at: datetime + """RFC 3339 timestamp (inclusive).""" + + amount: Optional[float] = None + """Amount for the charge. + + Can be provided instead of unit_price and quantity. If amount is sent, the + unit_price is assumed to be the amount and quantity is inferred to be 1. + """ + + quantity: Optional[float] = None + """Quantity for the charge. + + Will be multiplied by unit_price to determine the amount and must be specified + with unit_price. If specified amount cannot be provided. + """ + + unit_price: Optional[float] = None + """Unit price for the charge. + + Will be multiplied by quantity to determine the amount and must be specified + with quantity. If specified amount cannot be provided. + """ + + +class DataEditUpdateDiscountScheduleScheduleItem(BaseModel): + timestamp: datetime + """timestamp of the scheduled event""" + + amount: Optional[float] = None + """Amount for the charge. + + Can be provided instead of unit_price and quantity. If amount is sent, the + unit_price is assumed to be the amount and quantity is inferred to be 1. + """ + + quantity: Optional[float] = None + """Quantity for the charge. + + Will be multiplied by unit_price to determine the amount and must be specified + with unit_price. If specified amount cannot be provided. + """ + + unit_price: Optional[float] = None + """Unit price for the charge. + + Will be multiplied by quantity to determine the amount and must be specified + with quantity. If specified amount cannot be provided. + """ + + +class DataEditUpdateDiscountSchedule(BaseModel): + """Must provide either schedule_items or recurring_schedule.""" + + credit_type_id: Optional[str] = None + """Defaults to USD (cents) if not passed.""" + + do_not_invoice: Optional[bool] = None + """This field is only applicable to commit invoice schedules. + + If true, this schedule will not generate an invoice. + """ + + recurring_schedule: Optional[DataEditUpdateDiscountScheduleRecurringSchedule] = None + """Enter the unit price and quantity for the charge or instead only send the + amount. + + If amount is sent, the unit price is assumed to be the amount and quantity is + inferred to be 1. + """ + + schedule_items: Optional[List[DataEditUpdateDiscountScheduleScheduleItem]] = None + """Either provide amount or provide both unit_price and quantity.""" + + +class DataEditUpdateDiscount(BaseModel): + id: str + + custom_fields: Optional[Dict[str, str]] = None + """Custom fields to be added eg. { "key1": "value1", "key2": "value2" }""" + + name: Optional[str] = None + + netsuite_sales_order_id: Optional[str] = None + + schedule: Optional[DataEditUpdateDiscountSchedule] = None + """Must provide either schedule_items or recurring_schedule.""" + + +class DataEditUpdatePrepaidBalanceThresholdConfigurationCommit(UpdateBaseThresholdCommit): + applicable_product_ids: Optional[List[str]] = None + """Which products the threshold commit applies to. + + If both applicable_product_ids and applicable_product_tags are not provided, the + commit applies to all products. + """ + + applicable_product_tags: Optional[List[str]] = None + """Which tags the threshold commit applies to. + + If both applicable_product_ids and applicable_product_tags are not provided, the + commit applies to all products. + """ + + specifiers: Optional[List[CommitSpecifierInput]] = None + """ + List of filters that determine what kind of customer usage draws down a commit + or credit. A customer's usage needs to meet the condition of at least one of the + specifiers to contribute to a commit's or credit's drawdown. This field cannot + be used together with `applicable_product_ids` or `applicable_product_tags`. + Instead, to target usage by product or product tag, pass those values in the + body of `specifiers`. + """ + + +class DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap(BaseModel): + """Update the discount cap. Set to null to remove an existing cap.""" + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" + + +class DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(BaseModel): + cap: Optional[DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap] = None + """Update the discount cap. Set to null to remove an existing cap.""" + + payment_fraction: Optional[float] = None + """ + The fraction of the original amount that the customer pays after applying the + discount. Set to null to remove the discount fraction. For example, 0.85 means + the customer pays 85% of the original amount (a 15% discount). + """ + + +class DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel): + entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"] + + key: str + + value: str + + +class DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude(BaseModel): + custom_field_filters: List[ + DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter + ] + + +class DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier(BaseModel): + exclude: List[DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude] + + +class DataEditUpdatePrepaidBalanceThresholdConfiguration(BaseModel): + commit: Optional[DataEditUpdatePrepaidBalanceThresholdConfigurationCommit] = None + + custom_credit_type_id: Optional[str] = None + """ + If provided, the threshold, recharge-to amount, and the resulting threshold + commit amount will be in terms of this credit type instead of the fiat currency. + """ + + discount_configuration: Optional[DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration] = None + + is_enabled: Optional[bool] = None + """ + When set to false, the contract will not be evaluated against the + threshold_amount. Toggling to true will result an immediate evaluation, + regardless of prior state. + """ + + payment_gate_config: Optional[PaymentGateConfigV2] = None + + recharge_to_amount: Optional[float] = None + """Specify the amount the balance should be recharged to.""" + + threshold_amount: Optional[float] = None + """Specify the threshold amount for the contract. + + Each time the contract's balance lowers to this amount, a threshold charge will + be initiated. + """ + + threshold_balance_specifiers: Optional[ + List[DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier] + ] = None + + +class DataEditUpdateRecurringCommitAccessAmount(BaseModel): + quantity: Optional[float] = None + + unit_price: Optional[float] = None + + +class DataEditUpdateRecurringCommitInvoiceAmount(BaseModel): + quantity: Optional[float] = None + + unit_price: Optional[float] = None + + +class DataEditUpdateRecurringCommit(BaseModel): + id: str + + access_amount: Optional[DataEditUpdateRecurringCommitAccessAmount] = None + + ending_before: Optional[datetime] = None + + invoice_amount: Optional[DataEditUpdateRecurringCommitInvoiceAmount] = None + + rate_type: Optional[Literal["LIST_RATE", "COMMIT_RATE"]] = None + + +class DataEditUpdateRecurringCreditAccessAmount(BaseModel): + quantity: Optional[float] = None + + unit_price: Optional[float] = None + + +class DataEditUpdateRecurringCredit(BaseModel): + id: str + + access_amount: Optional[DataEditUpdateRecurringCreditAccessAmount] = None + + ending_before: Optional[datetime] = None + + rate_type: Optional[Literal["LIST_RATE", "COMMIT_RATE"]] = None + + +class DataEditUpdateRefundInvoice(BaseModel): + date: datetime + + invoice_id: str + + +class DataEditUpdateScheduledChargeInvoiceScheduleAddScheduleItem(BaseModel): + timestamp: datetime + + amount: Optional[float] = None + + quantity: Optional[float] = None + + unit_price: Optional[float] = None + + +class DataEditUpdateScheduledChargeInvoiceScheduleRemoveScheduleItem(BaseModel): + id: str + + +class DataEditUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem(BaseModel): + id: str + + amount: Optional[float] = None + + quantity: Optional[float] = None + + timestamp: Optional[datetime] = None + + unit_price: Optional[float] = None + + +class DataEditUpdateScheduledChargeInvoiceSchedule(BaseModel): + add_schedule_items: Optional[List[DataEditUpdateScheduledChargeInvoiceScheduleAddScheduleItem]] = None + + remove_schedule_items: Optional[List[DataEditUpdateScheduledChargeInvoiceScheduleRemoveScheduleItem]] = None + + update_schedule_items: Optional[List[DataEditUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem]] = None + + +class DataEditUpdateScheduledCharge(BaseModel): + id: str + + invoice_schedule: Optional[DataEditUpdateScheduledChargeInvoiceSchedule] = None + + name: Optional[str] = None + + netsuite_sales_order_id: Optional[str] = None + + +class DataEditUpdateSpendThresholdConfigurationDiscountConfigurationCap(BaseModel): + """Update the discount cap. Set to null to remove an existing cap.""" + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" + + +class DataEditUpdateSpendThresholdConfigurationDiscountConfiguration(BaseModel): + cap: Optional[DataEditUpdateSpendThresholdConfigurationDiscountConfigurationCap] = None + """Update the discount cap. Set to null to remove an existing cap.""" + + payment_fraction: Optional[float] = None + """ + The fraction of the original amount that the customer pays after applying the + discount. Set to null to remove the discount fraction. For example, 0.85 means + the customer pays 85% of the original amount (a 15% discount). + """ + + +class DataEditUpdateSpendThresholdConfiguration(BaseModel): + commit: Optional[UpdateBaseThresholdCommit] = None + + discount_configuration: Optional[DataEditUpdateSpendThresholdConfigurationDiscountConfiguration] = None + + is_enabled: Optional[bool] = None + """ + When set to false, the contract will not be evaluated against the + threshold_amount. Toggling to true will result an immediate evaluation, + regardless of prior state. + """ + + payment_gate_config: Optional[PaymentGateConfigV2] = None + + threshold_amount: Optional[float] = None + """Specify the threshold amount for the contract. + + Each time the contract's usage hits this amount, a threshold charge will be + initiated. + """ + + +class DataEditUpdateSubscriptionQuantityUpdate(BaseModel): + starting_at: datetime + + quantity: Optional[float] = None + + quantity_delta: Optional[float] = None + + +class DataEditUpdateSubscriptionSeatUpdatesAddSeatID(BaseModel): + seat_ids: List[str] + + starting_at: datetime + """Assigned seats will be added/removed starting at this date.""" + + +class DataEditUpdateSubscriptionSeatUpdatesAddUnassignedSeat(BaseModel): + quantity: float + """ + The number of unassigned seats on the subscription will increase/decrease by + this delta. Must be greater than 0. + """ + + starting_at: datetime + """Unassigned seats will be updated starting at this date.""" + + +class DataEditUpdateSubscriptionSeatUpdatesRemoveSeatID(BaseModel): + seat_ids: List[str] + + starting_at: datetime + """Assigned seats will be added/removed starting at this date.""" + + +class DataEditUpdateSubscriptionSeatUpdatesRemoveUnassignedSeat(BaseModel): + quantity: float + """ + The number of unassigned seats on the subscription will increase/decrease by + this delta. Must be greater than 0. + """ + + starting_at: datetime + """Unassigned seats will be updated starting at this date.""" + + +class DataEditUpdateSubscriptionSeatUpdates(BaseModel): + """Manage subscription seats for subscriptions in SEAT_BASED mode.""" + + add_seat_ids: Optional[List[DataEditUpdateSubscriptionSeatUpdatesAddSeatID]] = None + """Adds seat IDs to the subscription. + + If there are unassigned seats, the new seat IDs will fill these unassigned seats + and not increase the total subscription quantity. Otherwise, if there are more + new seat IDs than unassigned seats, the total subscription quantity will + increase. + """ + + add_unassigned_seats: Optional[List[DataEditUpdateSubscriptionSeatUpdatesAddUnassignedSeat]] = None + """Adds unassigned seats to the subscription. + + This will increase the total subscription quantity. + """ + + remove_seat_ids: Optional[List[DataEditUpdateSubscriptionSeatUpdatesRemoveSeatID]] = None + """Removes seat IDs from the subscription, if possible. + + If a seat ID is removed, the total subscription quantity will decrease. + Otherwise, if the seat ID is not found on the subscription, this is a no-op. + """ + + remove_unassigned_seats: Optional[List[DataEditUpdateSubscriptionSeatUpdatesRemoveUnassignedSeat]] = None + """Removes unassigned seats from the subscription. + + This will decrease the total subscription quantity if there are are unassigned + seats. + """ + + +class DataEditUpdateSubscription(BaseModel): + id: str + + ending_before: Optional[datetime] = None + + quantity_updates: Optional[List[DataEditUpdateSubscriptionQuantityUpdate]] = None + + seat_updates: Optional[DataEditUpdateSubscriptionSeatUpdates] = None + """Manage subscription seats for subscriptions in SEAT_BASED mode.""" + + +class DataEdit(BaseModel): + id: str + + add_commits: Optional[List[DataEditAddCommit]] = None + + add_credits: Optional[List[DataEditAddCredit]] = None + + add_discounts: Optional[List[Discount]] = None + + add_overrides: Optional[List[DataEditAddOverride]] = None + + add_prepaid_balance_threshold_configuration: Optional[PrepaidBalanceThresholdConfigurationV2] = None + + add_pro_services: Optional[List[ProService]] = None + + add_recurring_commits: Optional[List[DataEditAddRecurringCommit]] = None + + add_recurring_credits: Optional[List[DataEditAddRecurringCredit]] = None + + add_reseller_royalties: Optional[List[DataEditAddResellerRoyalty]] = None + + add_scheduled_charges: Optional[List[DataEditAddScheduledCharge]] = None + + add_spend_threshold_configuration: Optional[SpendThresholdConfigurationV2] = None + + add_subscriptions: Optional[List[DataEditAddSubscription]] = None + """List of subscriptions on the contract.""" + + add_usage_filters: Optional[List[DataEditAddUsageFilter]] = None + + archive_commits: Optional[List[DataEditArchiveCommit]] = None + + archive_credits: Optional[List[DataEditArchiveCredit]] = None + + archive_scheduled_charges: Optional[List[DataEditArchiveScheduledCharge]] = None + + remove_overrides: Optional[List[DataEditRemoveOverride]] = None + + timestamp: Optional[datetime] = None + + uniqueness_key: Optional[str] = None + """Prevents the creation of duplicates. + + If a request to create a record is made with a previously used uniqueness key, a + new record will not be created and the request will fail with a 409 error. + """ + + update_commits: Optional[List[DataEditUpdateCommit]] = None + + update_contract_end_date: Optional[datetime] = None + + update_contract_name: Optional[str] = None + """Value to update the contract name to. + + If not provided, the contract name will remain unchanged. + """ + + update_credits: Optional[List[DataEditUpdateCredit]] = None + + update_discounts: Optional[List[DataEditUpdateDiscount]] = None + + update_prepaid_balance_threshold_configuration: Optional[DataEditUpdatePrepaidBalanceThresholdConfiguration] = None + + update_recurring_commits: Optional[List[DataEditUpdateRecurringCommit]] = None + + update_recurring_credits: Optional[List[DataEditUpdateRecurringCredit]] = None + + update_refund_invoices: Optional[List[DataEditUpdateRefundInvoice]] = None + + update_scheduled_charges: Optional[List[DataEditUpdateScheduledCharge]] = None + + update_spend_threshold_configuration: Optional[DataEditUpdateSpendThresholdConfiguration] = None + + update_subscriptions: Optional[List[DataEditUpdateSubscription]] = None + """Optional list of subscriptions to update.""" + + +class Data(BaseModel): + id: str -__all__ = ["ContractEditResponse"] + edit: Optional[DataEdit] = None class ContractEditResponse(BaseModel): - data: ID + data: Data diff --git a/src/metronome/types/v2/contract_get_edit_history_response.py b/src/metronome/types/v2/contract_get_edit_history_response.py index ebb37fb35..a2f598079 100644 --- a/src/metronome/types/v2/contract_get_edit_history_response.py +++ b/src/metronome/types/v2/contract_get_edit_history_response.py @@ -84,6 +84,10 @@ "DataUpdatePrepaidBalanceThresholdConfiguration", "DataUpdatePrepaidBalanceThresholdConfigurationCommit", "DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration", + "DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap", + "DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier", + "DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude", + "DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter", "DataUpdateRecurringCommit", "DataUpdateRecurringCommitAccessAmount", "DataUpdateRecurringCommitInvoiceAmount", @@ -97,6 +101,7 @@ "DataUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem", "DataUpdateSpendThresholdConfiguration", "DataUpdateSpendThresholdConfigurationDiscountConfiguration", + "DataUpdateSpendThresholdConfigurationDiscountConfigurationCap", "DataUpdateSubscription", "DataUpdateSubscriptionQuantityUpdate", "DataUpdateSubscriptionSeatUpdates", @@ -1085,7 +1090,20 @@ class DataUpdatePrepaidBalanceThresholdConfigurationCommit(UpdateBaseThresholdCo """ +class DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap(BaseModel): + """Update the discount cap. Set to null to remove an existing cap.""" + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" + + class DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(BaseModel): + cap: Optional[DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap] = None + """Update the discount cap. Set to null to remove an existing cap.""" + payment_fraction: Optional[float] = None """ The fraction of the original amount that the customer pays after applying the @@ -1094,6 +1112,24 @@ class DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(BaseMo """ +class DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel): + entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"] + + key: str + + value: str + + +class DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude(BaseModel): + custom_field_filters: List[ + DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter + ] + + +class DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier(BaseModel): + exclude: List[DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude] + + class DataUpdatePrepaidBalanceThresholdConfiguration(BaseModel): commit: Optional[DataUpdatePrepaidBalanceThresholdConfigurationCommit] = None @@ -1124,6 +1160,10 @@ class DataUpdatePrepaidBalanceThresholdConfiguration(BaseModel): be initiated. """ + threshold_balance_specifiers: Optional[ + List[DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier] + ] = None + class DataUpdateRecurringCommitAccessAmount(BaseModel): quantity: Optional[float] = None @@ -1215,7 +1255,20 @@ class DataUpdateScheduledCharge(BaseModel): netsuite_sales_order_id: Optional[str] = None +class DataUpdateSpendThresholdConfigurationDiscountConfigurationCap(BaseModel): + """Update the discount cap. Set to null to remove an existing cap.""" + + amount: float + """Accumulated spend ceiling above which the discount stops applying.""" + + spend_tracker_alias: str + """Alias of the spend tracker this cap is measured against.""" + + class DataUpdateSpendThresholdConfigurationDiscountConfiguration(BaseModel): + cap: Optional[DataUpdateSpendThresholdConfigurationDiscountConfigurationCap] = None + """Update the discount cap. Set to null to remove an existing cap.""" + payment_fraction: Optional[float] = None """ The fraction of the original amount that the customer pays after applying the diff --git a/tests/api_resources/v1/test_contracts.py b/tests/api_resources/v1/test_contracts.py index 7e0205e88..11ae3f1c5 100644 --- a/tests/api_resources/v1/test_contracts.py +++ b/tests/api_resources/v1/test_contracts.py @@ -105,6 +105,7 @@ def test_method_create_with_all_params(self, client: Metronome) -> None: "product_tags": ["string"], } ], + "spend_tracker_attributes": {"counts_as_discounted": True}, "temporary_id": "temporary_id", } ], @@ -265,7 +266,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None: "recharge_to_amount": 0, "threshold_amount": 0, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, professional_services=[ { @@ -445,8 +467,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None: "tax_type": "NONE", }, "threshold_amount": 0, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, }, + spend_trackers=[ + { + "alias": "alias", + "applicable_spend_specifiers": [ + { + "sources": ["THRESHOLD_RECHARGE"], + "spend_type": "COMMIT_PURCHASE", + "discounted": "ANY", + } + ], + "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "reset_frequency": "BILLING_PERIOD", + } + ], subscriptions=[ { "collection_schedule": "ADVANCE", @@ -733,6 +775,7 @@ def test_method_amend_with_all_params(self, client: Metronome) -> None: "product_tags": ["string"], } ], + "spend_tracker_attributes": {"counts_as_discounted": True}, "temporary_id": "temporary_id", } ], @@ -1532,6 +1575,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome) "product_tags": ["string"], } ], + "spend_tracker_attributes": {"counts_as_discounted": True}, "temporary_id": "temporary_id", } ], @@ -1692,7 +1736,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome) "recharge_to_amount": 0, "threshold_amount": 0, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, professional_services=[ { @@ -1872,8 +1937,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome) "tax_type": "NONE", }, "threshold_amount": 0, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, }, + spend_trackers=[ + { + "alias": "alias", + "applicable_spend_specifiers": [ + { + "sources": ["THRESHOLD_RECHARGE"], + "spend_type": "COMMIT_PURCHASE", + "discounted": "ANY", + } + ], + "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "reset_frequency": "BILLING_PERIOD", + } + ], subscriptions=[ { "collection_schedule": "ADVANCE", @@ -2160,6 +2245,7 @@ async def test_method_amend_with_all_params(self, async_client: AsyncMetronome) "product_tags": ["string"], } ], + "spend_tracker_attributes": {"counts_as_discounted": True}, "temporary_id": "temporary_id", } ], diff --git a/tests/api_resources/v1/test_packages.py b/tests/api_resources/v1/test_packages.py index 91a5625e7..b78c6ed4d 100644 --- a/tests/api_resources/v1/test_packages.py +++ b/tests/api_resources/v1/test_packages.py @@ -223,7 +223,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None: "recharge_to_amount": 0, "threshold_amount": 0, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, rate_card_alias="rate_card_alias", rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", @@ -364,8 +385,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None: "tax_type": "NONE", }, "threshold_amount": 0, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, }, + spend_trackers=[ + { + "alias": "alias", + "applicable_spend_specifiers": [ + { + "sources": ["THRESHOLD_RECHARGE"], + "spend_type": "COMMIT_PURCHASE", + "discounted": "ANY", + } + ], + "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "reset_frequency": "BILLING_PERIOD", + } + ], subscriptions=[ { "collection_schedule": "ADVANCE", @@ -776,7 +817,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome) "recharge_to_amount": 0, "threshold_amount": 0, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, rate_card_alias="rate_card_alias", rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", @@ -917,8 +979,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome) "tax_type": "NONE", }, "threshold_amount": 0, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, }, + spend_trackers=[ + { + "alias": "alias", + "applicable_spend_specifiers": [ + { + "sources": ["THRESHOLD_RECHARGE"], + "spend_type": "COMMIT_PURCHASE", + "discounted": "ANY", + } + ], + "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "reset_frequency": "BILLING_PERIOD", + } + ], subscriptions=[ { "collection_schedule": "ADVANCE", diff --git a/tests/api_resources/v1/test_payments.py b/tests/api_resources/v1/test_payments.py deleted file mode 100644 index a2285538c..000000000 --- a/tests/api_resources/v1/test_payments.py +++ /dev/null @@ -1,255 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from metronome import Metronome, AsyncMetronome -from tests.utils import assert_matches_type -from metronome.types.v1 import ( - Payment, - PaymentCancelResponse, - PaymentAttemptResponse, -) -from metronome.pagination import SyncBodyCursorPage, AsyncBodyCursorPage - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestPayments: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_list(self, client: Metronome) -> None: - payment = client.v1.payments.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Metronome) -> None: - payment = client.v1.payments.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - limit=1, - next_page="next_page", - statuses=["pending", "requires_intervention"], - ) - assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Metronome) -> None: - response = client.v1.payments.with_raw_response.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - payment = response.parse() - assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Metronome) -> None: - with client.v1.payments.with_streaming_response.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - payment = response.parse() - assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_method_attempt(self, client: Metronome) -> None: - payment = client.v1.payments.attempt( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - assert_matches_type(PaymentAttemptResponse, payment, path=["response"]) - - @parametrize - def test_raw_response_attempt(self, client: Metronome) -> None: - response = client.v1.payments.with_raw_response.attempt( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - payment = response.parse() - assert_matches_type(PaymentAttemptResponse, payment, path=["response"]) - - @parametrize - def test_streaming_response_attempt(self, client: Metronome) -> None: - with client.v1.payments.with_streaming_response.attempt( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - payment = response.parse() - assert_matches_type(PaymentAttemptResponse, payment, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_method_cancel(self, client: Metronome) -> None: - payment = client.v1.payments.cancel( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - assert_matches_type(PaymentCancelResponse, payment, path=["response"]) - - @parametrize - def test_raw_response_cancel(self, client: Metronome) -> None: - response = client.v1.payments.with_raw_response.cancel( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - payment = response.parse() - assert_matches_type(PaymentCancelResponse, payment, path=["response"]) - - @parametrize - def test_streaming_response_cancel(self, client: Metronome) -> None: - with client.v1.payments.with_streaming_response.cancel( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - payment = response.parse() - assert_matches_type(PaymentCancelResponse, payment, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncPayments: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_list(self, async_client: AsyncMetronome) -> None: - payment = await async_client.v1.payments.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: - payment = await async_client.v1.payments.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - limit=1, - next_page="next_page", - statuses=["pending", "requires_intervention"], - ) - assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: - response = await async_client.v1.payments.with_raw_response.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - payment = await response.parse() - assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: - async with async_client.v1.payments.with_streaming_response.list( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - payment = await response.parse() - assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_method_attempt(self, async_client: AsyncMetronome) -> None: - payment = await async_client.v1.payments.attempt( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - assert_matches_type(PaymentAttemptResponse, payment, path=["response"]) - - @parametrize - async def test_raw_response_attempt(self, async_client: AsyncMetronome) -> None: - response = await async_client.v1.payments.with_raw_response.attempt( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - payment = await response.parse() - assert_matches_type(PaymentAttemptResponse, payment, path=["response"]) - - @parametrize - async def test_streaming_response_attempt(self, async_client: AsyncMetronome) -> None: - async with async_client.v1.payments.with_streaming_response.attempt( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - payment = await response.parse() - assert_matches_type(PaymentAttemptResponse, payment, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_method_cancel(self, async_client: AsyncMetronome) -> None: - payment = await async_client.v1.payments.cancel( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - assert_matches_type(PaymentCancelResponse, payment, path=["response"]) - - @parametrize - async def test_raw_response_cancel(self, async_client: AsyncMetronome) -> None: - response = await async_client.v1.payments.with_raw_response.cancel( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - payment = await response.parse() - assert_matches_type(PaymentCancelResponse, payment, path=["response"]) - - @parametrize - async def test_streaming_response_cancel(self, async_client: AsyncMetronome) -> None: - async with async_client.v1.payments.with_streaming_response.cancel( - customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", - invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - payment = await response.parse() - assert_matches_type(PaymentCancelResponse, payment, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/v2/test_contracts.py b/tests/api_resources/v2/test_contracts.py index 765e06fd4..96cc07cdb 100644 --- a/tests/api_resources/v2/test_contracts.py +++ b/tests/api_resources/v2/test_contracts.py @@ -201,6 +201,7 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None: "product_tags": ["string"], } ], + "spend_tracker_attributes": {"counts_as_discounted": True}, "temporary_id": "temporary_id", } ], @@ -344,7 +345,28 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None: "recharge_to_amount": 0, "threshold_amount": 0, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, add_professional_services=[ { @@ -523,8 +545,28 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None: "tax_type": "NONE", }, "threshold_amount": 0, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, }, + add_spend_trackers=[ + { + "alias": "alias", + "applicable_spend_specifiers": [ + { + "sources": ["THRESHOLD_RECHARGE"], + "spend_type": "COMMIT_PURCHASE", + "discounted": "ANY", + } + ], + "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "reset_frequency": "BILLING_PERIOD", + } + ], add_subscriptions=[ { "collection_schedule": "ADVANCE", @@ -555,6 +597,7 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None: archive_commits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], archive_credits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], archive_scheduled_charges=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + archive_spend_trackers=["string"], remove_overrides=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], uniqueness_key="x", update_commits=[ @@ -664,7 +707,13 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None: ], }, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + "payment_fraction": 0, + }, "is_enabled": True, "payment_gate_config": { "payment_gate_type": "NONE", @@ -680,6 +729,21 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None: }, "recharge_to_amount": 0, "threshold_amount": 0, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, update_recurring_commits=[ { @@ -740,7 +804,13 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None: "priority": 0, "product_id": "product_id", }, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + "payment_fraction": 0, + }, "is_enabled": True, "payment_gate_config": { "payment_gate_type": "NONE", @@ -1217,6 +1287,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) - "product_tags": ["string"], } ], + "spend_tracker_attributes": {"counts_as_discounted": True}, "temporary_id": "temporary_id", } ], @@ -1360,7 +1431,28 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) - "recharge_to_amount": 0, "threshold_amount": 0, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, add_professional_services=[ { @@ -1539,8 +1631,28 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) - "tax_type": "NONE", }, "threshold_amount": 0, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "payment_fraction": 0, + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + }, }, + add_spend_trackers=[ + { + "alias": "alias", + "applicable_spend_specifiers": [ + { + "sources": ["THRESHOLD_RECHARGE"], + "spend_type": "COMMIT_PURCHASE", + "discounted": "ANY", + } + ], + "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "reset_frequency": "BILLING_PERIOD", + } + ], add_subscriptions=[ { "collection_schedule": "ADVANCE", @@ -1571,6 +1683,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) - archive_commits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], archive_credits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], archive_scheduled_charges=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + archive_spend_trackers=["string"], remove_overrides=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], uniqueness_key="x", update_commits=[ @@ -1680,7 +1793,13 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) - ], }, "custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + "payment_fraction": 0, + }, "is_enabled": True, "payment_gate_config": { "payment_gate_type": "NONE", @@ -1696,6 +1815,21 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) - }, "recharge_to_amount": 0, "threshold_amount": 0, + "threshold_balance_specifiers": [ + { + "exclude": [ + { + "custom_field_filters": [ + { + "entity": "Commit", + "key": "key", + "value": "value", + } + ] + } + ] + } + ], }, update_recurring_commits=[ { @@ -1756,7 +1890,13 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) - "priority": 0, "product_id": "product_id", }, - "discount_configuration": {"payment_fraction": 0}, + "discount_configuration": { + "cap": { + "amount": 0, + "spend_tracker_alias": "spend_tracker_alias", + }, + "payment_fraction": 0, + }, "is_enabled": True, "payment_gate_config": { "payment_gate_type": "NONE",