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

from __future__ import annotations
import dataclasses
import dateutil.parser
from .address import Address
from .parcel import Parcel
from .rate import Rate
from .shipmentextra import ShipmentExtra
from dataclasses_json import Undefined, dataclass_json
from datetime import datetime
from enum import Enum
from shippo import utils
from typing import List, Optional


@dataclass_json(undefined=Undefined.EXCLUDE)
@dataclasses.dataclass
class Messages:
    code: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('code'), 'exclude': lambda f: f is None }})
    source: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('source'), 'exclude': lambda f: f is None }})
    text: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('text'), 'exclude': lambda f: f is None }})
    


class ShipmentStatus(str, Enum):
    r"""`Waiting` shipments have been successfully submitted but not yet been processed.
    `Queued` shipments are currently being processed. 
    `Success` shipments have been processed successfully, meaning that rate generation has concluded. 
    `Error` does not occur currently and is reserved for future use.
    """
    ERROR = 'ERROR'
    QUEUED = 'QUEUED'
    SUCCESS = 'SUCCESS'
    STATUS = 'STATUS'


@dataclass_json(undefined=Undefined.EXCLUDE)
@dataclasses.dataclass
class Shipment:
    r"""Shipment represents the parcel as retrieved from the database"""
    metadata: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('metadata') }})
    r"""A string of up to 100 characters that can be filled with any additional information you want to attach to the object."""
    address_from: Address = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('address_from') }})
    r"""<a href=\\"#tag/Addresses\\">Address</a> object of the sender / seller. Will be returned expanded by default."""
    address_to: Address = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('address_to') }})
    r"""<a href=\\"#tag/Addresses\\">Address</a> object of the recipient / buyer. Will be returned expanded by default."""
    carrier_accounts: List[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('carrier_accounts') }})
    r"""An array of object_ids of the carrier account objects to be used for getting shipping rates for this shipment.
    If no carrier account object_ids are set in this field, Shippo will attempt to generate rates using all the 
    carrier accounts that have the `active` field set.
    """
    messages: List[Messages] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('messages') }})
    r"""An array containing elements of the following schema:<br>`code` (string): an identifier for the corresponding message
    (not always available)<br>`message` (string): a publishable message containing further information.
    """
    object_created: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('object_created'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""Date and time of Shipment creation."""
    object_id: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('object_id') }})
    r"""Unique identifier of the given Shipment object."""
    object_owner: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('object_owner') }})
    r"""Username of the user who created the Shipment object."""
    object_updated: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('object_updated'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""Date and time of last Shipment update."""
    parcels: List[Parcel] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('parcels') }})
    r"""List of Parcel objects to be shipped."""
    rates: List[Rate] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('rates') }})
    r"""An array with all available rates. If <code>async</code> has been set to <code>false</code> in the request,
    this will be populated with all available rates in the response. Otherwise rates will be created
    asynchronously and this array will initially be empty.
    """
    status: ShipmentStatus = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status') }})
    r"""`Waiting` shipments have been successfully submitted but not yet been processed.
    `Queued` shipments are currently being processed. 
    `Success` shipments have been processed successfully, meaning that rate generation has concluded. 
    `Error` does not occur currently and is reserved for future use.
    """
    customs_declaration: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('customs_declaration'), 'exclude': lambda f: f is None }})
    r"""ID of the Customs Declarations object for an international shipment."""
    extra: Optional[ShipmentExtra] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('extra'), 'exclude': lambda f: f is None }})
    r"""An object holding optional extra services to be requested."""
    shipment_date: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('shipment_date'), 'exclude': lambda f: f is None }})
    r"""Date the shipment will be tendered to the carrier. Must be in the format `2014-01-18T00:35:03.463Z`.
    Defaults to current date and time if no value is provided. Please note that some carriers require this value to
    be in the future, on a working day, or similar.
    """
    address_return: Optional[Address] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('address_return'), 'exclude': lambda f: f is None }})
    r"""ID of the Address object where the shipment will be sent back to if it is not delivered
    (Only available for UPS, USPS, and Fedex shipments). <br/> 
    If this field is not set, your shipments will be returned to the address_from.
    """
    test: Optional[bool] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('test'), 'exclude': lambda f: f is None }})
    r"""Indicates whether the object has been created in test mode."""
    

