# coding: utf-8

"""
    easybill REST API

     The first version of the easybill REST API. [CHANGELOG](https://api.easybill.de/rest/v1/CHANGELOG.md)  ## Authentication  You can choose between two available methods: `Basic Auth` or `Bearer Token`.  In each HTTP request, one of the following HTTP headers is required:  ``` # Basic Auth Authorization: Basic base64_encode('<email>:<api_key>') # Bearer Token Authorization: Bearer <api_key> ```  ## Limitations  ### Request Limit  * PLUS: 10 requests per minute * BUSINESS: 60 requests per minute  If the limit is exceeded, you will receive the HTTP error: `429 Too Many Requests`  ### Result Limit  All result lists are limited to 100 by default. This limit can be increased by the query parameter `limit` to a maximum of 1000.  ## Query filter  Many list resources can be filtered. In `/documents` you can filter e.g. by number with `/documents?number=111028654`. If you want to filter multiple numbers, you can either enter them separated by commas `/documents?number=111028654,222006895` or as an array `/documents?number[]=111028654&number[]=222006895`.  **Warning**: The maximum size of an HTTP request line in bytes is 4094. If this limit is exceeded, you will receive the HTTP error: `414 Request-URI Too Large`  ### Escape commas in query  You can escape commans in query `name=Patrick\\, Peter` if you submit the header `X-Easybill-Escape: true` in your request.  ## Property login_id  This is the login of your admin or employee account.  ## Date and Date-Time format Please use the timezone `Europe/Berlin`. * **date** = *Y-m-d* = `2016-12-31` * **date-time** = *Y-m-d H:i:s* = `2016-12-31 03:13:37`  Date or datetime can be `null` because the attributes have been added later and the entry is older.

    The version of the OpenAPI document: 1.96.0
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from datetime import date, datetime
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from typing import Optional, Set
from typing_extensions import Self
from pydantic_core import to_jsonable_python

class PostBox(BaseModel):
    """
    PostBox
    """ # noqa: E501
    id: Optional[StrictInt] = None
    document_id: Optional[StrictInt] = None
    to: Optional[StrictStr] = None
    cc: Optional[StrictStr] = None
    var_from: Optional[StrictStr] = Field(default=None, alias="from")
    subject: Optional[StrictStr] = None
    message: Optional[StrictStr] = None
    var_date: Optional[date] = Field(default=None, alias="date")
    created_at: Optional[datetime] = None
    processed_at: Optional[datetime] = None
    send_by_self: Optional[StrictBool] = None
    send_with_attachment: Optional[StrictBool] = None
    type: Optional[StrictStr] = None
    status: Optional[StrictStr] = None
    status_msg: Optional[StrictStr] = None
    login_id: Optional[StrictInt] = None
    document_file_type: Optional[StrictStr] = None
    post_send_type: Optional[StrictStr] = Field(default=None, description="This value indicates what method is used when the document is send via mail. The different types are offered by the german post as additional services. The registered mail options will include a tracking number which will be  added to the postbox when known.  If the value is omitted or empty when a postbox is created with the type \"POST\" post_send_type_standard will be used.  For postbox with a different type than \"POST\" this field will hold a empty string. ")
    tracking_identifier: Optional[StrictStr] = Field(default=None, description="If the document is send with one of the registered send types stated for post_send_type, a tracking identifier will be added to the postbox at a later point when the tracking identifier is provided by our service partner. ")
    __properties: ClassVar[List[str]] = ["id", "document_id", "to", "cc", "from", "subject", "message", "date", "created_at", "processed_at", "send_by_self", "send_with_attachment", "type", "status", "status_msg", "login_id", "document_file_type", "post_send_type", "tracking_identifier"]

    @field_validator('type')
    def type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['FAX', 'EMAIL', 'POST']):
            raise ValueError("must be one of enum values ('FAX', 'EMAIL', 'POST')")
        return value

    @field_validator('status')
    def status_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['WAITING', 'PREPARE', 'ERROR', 'OK', 'PROCESSING']):
            raise ValueError("must be one of enum values ('WAITING', 'PREPARE', 'ERROR', 'OK', 'PROCESSING')")
        return value

    @field_validator('document_file_type')
    def document_file_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['default', 'zugferd1', 'zugferd2_2', 'zugferd2_4_en16931', 'zugferd2_4_extended', 'xrechnung', 'xrechnung_xml']):
            raise ValueError("must be one of enum values ('default', 'zugferd1', 'zugferd2_2', 'zugferd2_4_en16931', 'zugferd2_4_extended', 'xrechnung', 'xrechnung_xml')")
        return value

    @field_validator('post_send_type')
    def post_send_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['post_send_type_standard', 'post_send_type_registered', 'post_send_type_registered_and_personal', 'post_send_type_registered_and_receipt', 'post_send_type_registered_throwin', 'post_send_type_prio']):
            raise ValueError("must be one of enum values ('post_send_type_standard', 'post_send_type_registered', 'post_send_type_registered_and_personal', 'post_send_type_registered_and_receipt', 'post_send_type_registered_throwin', 'post_send_type_prio')")
        return value

    model_config = ConfigDict(
        validate_by_name=True,
        validate_by_alias=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        return json.dumps(to_jsonable_python(self.to_dict()))

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of PostBox from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        """
        excluded_fields: Set[str] = set([
            "id",
            "login_id",
            "tracking_identifier",
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # set to None if document_file_type (nullable) is None
        # and model_fields_set contains the field
        if self.document_file_type is None and "document_file_type" in self.model_fields_set:
            _dict['document_file_type'] = None

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of PostBox from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "id": obj.get("id"),
            "document_id": obj.get("document_id"),
            "to": obj.get("to"),
            "cc": obj.get("cc"),
            "from": obj.get("from"),
            "subject": obj.get("subject"),
            "message": obj.get("message"),
            "date": obj.get("date"),
            "created_at": obj.get("created_at"),
            "processed_at": obj.get("processed_at"),
            "send_by_self": obj.get("send_by_self"),
            "send_with_attachment": obj.get("send_with_attachment"),
            "type": obj.get("type"),
            "status": obj.get("status"),
            "status_msg": obj.get("status_msg"),
            "login_id": obj.get("login_id"),
            "document_file_type": obj.get("document_file_type"),
            "post_send_type": obj.get("post_send_type"),
            "tracking_identifier": obj.get("tracking_identifier")
        })
        return _obj


