"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""

from .sdkconfiguration import SDKConfiguration
from orb import utils
from orb.models import errors, operations, shared
from typing import Optional

class PriceInterval:
    r"""The Price Interval resource represents a period of time for which a price will bill on a subscription. A
    subscription’s price intervals define its billing behavior.
    """
    sdk_configuration: SDKConfiguration

    def __init__(self, sdk_config: SDKConfiguration) -> None:
        self.sdk_configuration = sdk_config
        
    
    def add_edit_price_intervals(self, subscription_id: str, add_edit_price_interval_params: Optional[shared.AddEditPriceIntervalParams] = None) -> operations.AddEditPriceIntervalsResponse:
        r"""Add or edit price intervals
        This endpoint is used to add and edit subscription [price intervals](../reference/price-interval). By making
        modifications to a subscription’s price intervals, you can [flexibly and atomically control the billing behavior of a
        subscription](../guides/product-catalog/modifying-subscriptions).

        ## Adding price intervals

        Prices can be added as
        price intervals to a subscription by specifying them in the `add` array. A `price_id` or `external_price_id` from an
        add-on price or previously removed plan price can be specified to reuse an existing price definition (however, please
        note that prices from other plans cannot be added to the subscription). Additionally, a new price can be specified using
        the `price` field — this price will be created automatically.

        A `start_date` must be specified for the price
        interval. This is the date when the price will start billing on the subscription, so this will notably result in an
        immediate charge at this time for any billed in advance fixed fees. The `end_date` will default to null, resulting in a
        price interval that will bill on a continually recurring basis. Both of these dates can be set in the past or the future
        and Orb will generate or modify invoices to ensure the subscription’s invoicing behavior is correct.

        Additionally, a
        discount, minimum, or maximum can be specified on the price interval. This will only apply to this price interval, not
        any other price intervals on the subscription.

        ## Editing price intervals

        Price intervals can be adjusted by
        specifying edits to make in the `edit` array. A `price_interval_id` to edit must be specified — this can be retrieved
        from the `price_intervals` field on the subscription.

        A new `start_date` or `end_date` can be specified to change the
        range of the price interval, which will modify past or future invoices to ensure correctness. If either of these dates
        are unspecified, they will default to the existing date on the price interval. To remove a price interval entirely from
        a subscription, set the `end_date` to be equivalent to the `start_date`.

        ## Fixed fee quantity transitions
        The fixed fee quantity transitions for a fixed fee price interval can also be specified when adding or editing by passing an
        array for `fixed_fee_quantity_transitions`. A fixed fee quantity transition must have a `quantity` and an
        `effective_date`, which is the date after which the new quantity will be used for billing. If a fixed fee quantity
        transition is scheduled at a billing period boundary, the full quantity will be billed on an invoice with the other
        prices on the subscription. If the fixed fee quantity transition is scheduled mid-billing period, the difference between
        the existing quantity and quantity specified in the transition will be prorated for the rest of the billing period and
        billed immediately, which will generate a new invoice.

        Notably, the list of fixed fee quantity transitions passed
        will overwrite the existing fixed fee quantity transitions on the price interval, so the entire list of transitions must
        be specified to add additional transitions. The existing list of transitions can be retrieved using the
        `fixed_fee_quantity_transitions` property on a subscription’s serialized price intervals.
        """
        request = operations.AddEditPriceIntervalsRequest(
            subscription_id=subscription_id,
            add_edit_price_interval_params=add_edit_price_interval_params,
        )
        
        base_url = utils.template_url(*self.sdk_configuration.get_server_details())
        
        url = utils.generate_url(operations.AddEditPriceIntervalsRequest, base_url, '/subscriptions/{subscription_id}/price_intervals', request)
        headers = {}
        req_content_type, data, form = utils.serialize_request_body(request, "add_edit_price_interval_params", False, True, 'json')
        if req_content_type not in ('multipart/form-data', 'multipart/mixed'):
            headers['content-type'] = req_content_type
        headers['Accept'] = 'application/json'
        headers['user-agent'] = self.sdk_configuration.user_agent
        
        client = self.sdk_configuration.security_client
        
        http_res = client.request('POST', url, data=data, files=form, headers=headers)
        content_type = http_res.headers.get('Content-Type')

        res = operations.AddEditPriceIntervalsResponse(status_code=http_res.status_code, content_type=content_type, raw_response=http_res)
        
        if http_res.status_code == 200:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, Optional[shared.Subscription])
                res.subscription = out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code == 400:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, errors.FourHundredError)
                out.raw_response = http_res
                raise out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code == 401:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, errors.FourHundredAndOneError)
                out.raw_response = http_res
                raise out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code == 404:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, errors.FourHundredAndFourError)
                out.raw_response = http_res
                raise out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code == 409:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, errors.FourHundredAndNineError)
                out.raw_response = http_res
                raise out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code == 413:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, errors.FourHundredAndThirteenError)
                out.raw_response = http_res
                raise out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code == 429:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, errors.FourHundredAndTwentyNineError)
                out.raw_response = http_res
                raise out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code >= 400 and http_res.status_code < 500 or http_res.status_code >= 500 and http_res.status_code < 600:
            raise errors.SDKError('API error occurred', http_res.status_code, http_res.text, http_res)
        elif http_res.status_code == 500:
            if utils.match_content_type(content_type, 'application/json'):
                out = utils.unmarshal_json(http_res.text, errors.FiveHundredError)
                out.raw_response = http_res
                raise out
            else:
                raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)

        return res

    