# 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, StrictFloat, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional, Union
from easybill_generated_sync.models.advanced_data_field import AdvancedDataField
from easybill_generated_sync.models.customer_snapshot import CustomerSnapshot
from easybill_generated_sync.models.document_address import DocumentAddress
from easybill_generated_sync.models.document_position import DocumentPosition
from easybill_generated_sync.models.document_recurring import DocumentRecurring
from easybill_generated_sync.models.file_format_config import FileFormatConfig
from easybill_generated_sync.models.service_date import ServiceDate
from typing import Optional, Set
from typing_extensions import Self
from pydantic_core import to_jsonable_python

class Document(BaseModel):
    """
    Document
    """ # noqa: E501
    address: Optional[DocumentAddress] = None
    advanced_data_fields: Optional[List[AdvancedDataField]] = Field(default=None, description="EN16931 Business Terms (BT fields) for structured invoice data. On update the submitted list fully replaces the existing fields — send an empty array to clear all.")
    attachment_ids: Optional[List[StrictInt]] = None
    label_address: Optional[DocumentAddress] = None
    amount: Optional[StrictInt] = Field(default=None, description="Amount in cents  (e.g. \"150\" = 1.50€)")
    amount_net: Optional[StrictInt] = Field(default=None, description="Amount in cents  (e.g. \"150\" = 1.50€)")
    anonymize_due_date: Optional[date] = Field(default=None, description="A date which signals when to anonymize the document. Must be in the future. Turns into a read only field if the document is anonymized")
    anonymize_status: Optional[StrictStr] = Field(default='NOT_ANONYMIZED', description="This field signals if the document was anonymized")
    anonymized_at: Optional[StrictStr] = None
    bank_debit_form: Optional[StrictStr] = 'null'
    billing_country: Optional[StrictStr] = None
    calc_vat_from: Optional[StrictInt] = Field(default=None, description="0 === Net, 1 === Gross.")
    cancel_id: Optional[StrictInt] = Field(default=None, description="ID from the cancel document. Only for document type INVOICE.")
    cash_allowance: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Cash allowance percentage. If not provided, inherits from customer when available.")
    cash_allowance_days: Optional[StrictInt] = Field(default=None, description="Days for cash allowance. If not provided, inherits from customer when available.")
    cash_allowance_text: Optional[StrictStr] = 'null'
    contact_id: Optional[StrictInt] = None
    contact_label: Optional[StrictStr] = ''
    contact_text: Optional[StrictStr] = ''
    created_at: Optional[datetime] = None
    currency: Optional[StrictStr] = 'EUR'
    customer_id: Optional[StrictInt] = None
    customer_snapshot: Optional[CustomerSnapshot] = None
    discount: Optional[StrictStr] = 'null'
    discount_type: Optional[StrictStr] = null
    document_date: Optional[date] = None
    due_date: Optional[date] = Field(default=None, description="To change the value use grace_period.")
    edited_at: Optional[datetime] = None
    external_id: Optional[StrictStr] = 'null'
    replica_url: Optional[StrictStr] = 'null'
    grace_period: Optional[StrictInt] = Field(default=None, description="will be replaced by its alias due_in_days.")
    due_in_days: Optional[StrictInt] = Field(default=None, description="due date in days. If not provided, inherits from customer when available")
    id: Optional[StrictInt] = None
    is_acceptable_on_public_domain: Optional[StrictBool] = Field(default=False, description="Indicates if a document can be accepted by the end customer through the document's public access page.")
    is_archive: Optional[StrictBool] = False
    is_draft: Optional[StrictBool] = Field(default=None, description="This property is read only. To finish the document call /documents/{id}/done.")
    is_replica: Optional[StrictBool] = Field(default=False, description="Marks a document as a replica from another software.")
    is_oss: Optional[StrictBool] = Field(default=False, description="Indicates if a document is a one-stop-shop document")
    item_notes: Optional[List[StrictStr]] = Field(default=None, description="Field holds all unique document_note of items for the document")
    items: Optional[List[DocumentPosition]] = None
    last_postbox_id: Optional[StrictInt] = None
    login_id: Optional[StrictInt] = Field(default=None, description="If omitted or null, the currently active login is used.")
    number: Optional[StrictStr] = 'null'
    order_number: Optional[StrictStr] = ''
    buyer_reference: Optional[StrictStr] = ''
    paid_amount: Optional[StrictInt] = None
    paid_at: Optional[date] = None
    pdf_pages: Optional[StrictInt] = None
    pdf_template: Optional[StrictStr] = Field(default=None, description="Default template is null or 'DE', default english is 'EN' and for all others use the numeric template ID.")
    payment_link_enabled: Optional[StrictBool] = Field(default=False, description="Whether the payment link is shown on this document. Overrides the setting from the referenced template.")
    payment_link_locale: Optional[StrictStr] = Field(default='de', description="Language of the payment link text on the document.")
    project_id: Optional[StrictInt] = None
    recurring_options: Optional[DocumentRecurring] = None
    ref_id: Optional[StrictInt] = Field(default=None, description="Reference document id")
    root_id: Optional[StrictInt] = Field(default=None, description="Root document id")
    service_date: Optional[ServiceDate] = None
    shipping_country: Optional[StrictStr] = 'null'
    status: Optional[StrictStr] = Field(default=null, description="This value can only be used in document type DELIVERY, ORDER, CHARGE or OFFER. NULL is default = not set.")
    text: Optional[StrictStr] = None
    text_prefix: Optional[StrictStr] = None
    text_tax: Optional[StrictStr] = Field(default='null', description="Overwrites the default vat-option text from the document layout. It is only displayed in documents with the type other than: Delivery, Dunning, Reminder or Letter and a different vat-option than null")
    title: Optional[StrictStr] = 'null'
    type: Optional[StrictStr] = Field(default='INVOICE', description="Can only set on create.")
    use_shipping_address: Optional[StrictBool] = Field(default=False, description="If true and customer has shipping address then it will be used.")
    vat_country: Optional[StrictStr] = 'null'
    vat_id: Optional[StrictStr] = ''
    fulfillment_country: Optional[StrictStr] = 'null'
    vat_option: Optional[StrictStr] = Field(default=null, description="NULL: Normal steuerbar<br/> nStb: Nicht steuerbar (Drittland)<br/> nStbUstID: Nicht steuerbar (EU mit USt-IdNr.)<br/> nStbNoneUstID: Nicht steuerbar (EU ohne USt-IdNr.)<br/> nStbIm: Nicht steuerbarer Innenumsatz<br/> revc: Steuerschuldwechsel §13b (Inland)<br/> IG: Innergemeinschaftliche Lieferung<br/> AL: Ausfuhrlieferung<br/> sStfr: sonstige Steuerbefreiung<br/> smallBusiness: Kleinunternehmen (Keine MwSt.)")
    file_format_config: Optional[List[FileFormatConfig]] = None
    __properties: ClassVar[List[str]] = ["address", "advanced_data_fields", "attachment_ids", "label_address", "amount", "amount_net", "anonymize_due_date", "anonymize_status", "anonymized_at", "bank_debit_form", "billing_country", "calc_vat_from", "cancel_id", "cash_allowance", "cash_allowance_days", "cash_allowance_text", "contact_id", "contact_label", "contact_text", "created_at", "currency", "customer_id", "customer_snapshot", "discount", "discount_type", "document_date", "due_date", "edited_at", "external_id", "replica_url", "grace_period", "due_in_days", "id", "is_acceptable_on_public_domain", "is_archive", "is_draft", "is_replica", "is_oss", "item_notes", "items", "last_postbox_id", "login_id", "number", "order_number", "buyer_reference", "paid_amount", "paid_at", "pdf_pages", "pdf_template", "payment_link_enabled", "payment_link_locale", "project_id", "recurring_options", "ref_id", "root_id", "service_date", "shipping_country", "status", "text", "text_prefix", "text_tax", "title", "type", "use_shipping_address", "vat_country", "vat_id", "fulfillment_country", "vat_option", "file_format_config"]

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

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

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

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

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

        if value not in set(['de', 'en']):
            raise ValueError("must be one of enum values ('de', 'en')")
        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(['ACCEPT', 'DONE', 'DROPSHIPPING', 'CANCEL']):
            raise ValueError("must be one of enum values ('ACCEPT', 'DONE', 'DROPSHIPPING', 'CANCEL')")
        return value

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

        if value not in set(['INVOICE', 'RECURRING', 'CREDIT', 'OFFER', 'REMINDER', 'DUNNING', 'STORNO', 'STORNO_CREDIT', 'DELIVERY', 'PDF', 'CHARGE', 'CHARGE_CONFIRM', 'LETTER', 'ORDER', 'PROFORMA_INVOICE', 'STORNO_PROFORMA_INVOICE']):
            raise ValueError("must be one of enum values ('INVOICE', 'RECURRING', 'CREDIT', 'OFFER', 'REMINDER', 'DUNNING', 'STORNO', 'STORNO_CREDIT', 'DELIVERY', 'PDF', 'CHARGE', 'CHARGE_CONFIRM', 'LETTER', 'ORDER', 'PROFORMA_INVOICE', 'STORNO_PROFORMA_INVOICE')")
        return value

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

        if value not in set(['NULL', 'nStb', 'nStbUstID', 'nStbNoneUstID', 'nStbIm', 'revc', 'IG', 'AL', 'sStfr', 'smallBusiness']):
            raise ValueError("must be one of enum values ('NULL', 'nStb', 'nStbUstID', 'nStbNoneUstID', 'nStbIm', 'revc', 'IG', 'AL', 'sStfr', 'smallBusiness')")
        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 Document 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.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        """
        excluded_fields: Set[str] = set([
            "attachment_ids",
            "amount",
            "amount_net",
            "anonymize_status",
            "anonymized_at",
            "billing_country",
            "cancel_id",
            "created_at",
            "due_date",
            "edited_at",
            "id",
            "is_draft",
            "item_notes",
            "last_postbox_id",
            "paid_amount",
            "paid_at",
            "pdf_pages",
            "root_id",
            "vat_id",
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of address
        if self.address:
            _dict['address'] = self.address.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in advanced_data_fields (list)
        _items = []
        if self.advanced_data_fields:
            for _item_advanced_data_fields in self.advanced_data_fields:
                if _item_advanced_data_fields:
                    _items.append(_item_advanced_data_fields.to_dict())
            _dict['advanced_data_fields'] = _items
        # override the default output from pydantic by calling `to_dict()` of label_address
        if self.label_address:
            _dict['label_address'] = self.label_address.to_dict()
        # override the default output from pydantic by calling `to_dict()` of customer_snapshot
        if self.customer_snapshot:
            _dict['customer_snapshot'] = self.customer_snapshot.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in items (list)
        _items = []
        if self.items:
            for _item_items in self.items:
                if _item_items:
                    _items.append(_item_items.to_dict())
            _dict['items'] = _items
        # override the default output from pydantic by calling `to_dict()` of recurring_options
        if self.recurring_options:
            _dict['recurring_options'] = self.recurring_options.to_dict()
        # override the default output from pydantic by calling `to_dict()` of service_date
        if self.service_date:
            _dict['service_date'] = self.service_date.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in file_format_config (list)
        _items = []
        if self.file_format_config:
            for _item_file_format_config in self.file_format_config:
                if _item_file_format_config:
                    _items.append(_item_file_format_config.to_dict())
            _dict['file_format_config'] = _items
        # set to None if anonymize_due_date (nullable) is None
        # and model_fields_set contains the field
        if self.anonymize_due_date is None and "anonymize_due_date" in self.model_fields_set:
            _dict['anonymize_due_date'] = None

        # set to None if anonymized_at (nullable) is None
        # and model_fields_set contains the field
        if self.anonymized_at is None and "anonymized_at" in self.model_fields_set:
            _dict['anonymized_at'] = None

        # set to None if bank_debit_form (nullable) is None
        # and model_fields_set contains the field
        if self.bank_debit_form is None and "bank_debit_form" in self.model_fields_set:
            _dict['bank_debit_form'] = None

        # set to None if cash_allowance (nullable) is None
        # and model_fields_set contains the field
        if self.cash_allowance is None and "cash_allowance" in self.model_fields_set:
            _dict['cash_allowance'] = None

        # set to None if cash_allowance_days (nullable) is None
        # and model_fields_set contains the field
        if self.cash_allowance_days is None and "cash_allowance_days" in self.model_fields_set:
            _dict['cash_allowance_days'] = None

        # set to None if cash_allowance_text (nullable) is None
        # and model_fields_set contains the field
        if self.cash_allowance_text is None and "cash_allowance_text" in self.model_fields_set:
            _dict['cash_allowance_text'] = None

        # set to None if contact_id (nullable) is None
        # and model_fields_set contains the field
        if self.contact_id is None and "contact_id" in self.model_fields_set:
            _dict['contact_id'] = None

        # set to None if customer_id (nullable) is None
        # and model_fields_set contains the field
        if self.customer_id is None and "customer_id" in self.model_fields_set:
            _dict['customer_id'] = None

        # set to None if discount (nullable) is None
        # and model_fields_set contains the field
        if self.discount is None and "discount" in self.model_fields_set:
            _dict['discount'] = None

        # set to None if discount_type (nullable) is None
        # and model_fields_set contains the field
        if self.discount_type is None and "discount_type" in self.model_fields_set:
            _dict['discount_type'] = None

        # set to None if external_id (nullable) is None
        # and model_fields_set contains the field
        if self.external_id is None and "external_id" in self.model_fields_set:
            _dict['external_id'] = None

        # set to None if replica_url (nullable) is None
        # and model_fields_set contains the field
        if self.replica_url is None and "replica_url" in self.model_fields_set:
            _dict['replica_url'] = None

        # set to None if grace_period (nullable) is None
        # and model_fields_set contains the field
        if self.grace_period is None and "grace_period" in self.model_fields_set:
            _dict['grace_period'] = None

        # set to None if due_in_days (nullable) is None
        # and model_fields_set contains the field
        if self.due_in_days is None and "due_in_days" in self.model_fields_set:
            _dict['due_in_days'] = None

        # set to None if number (nullable) is None
        # and model_fields_set contains the field
        if self.number is None and "number" in self.model_fields_set:
            _dict['number'] = None

        # set to None if project_id (nullable) is None
        # and model_fields_set contains the field
        if self.project_id is None and "project_id" in self.model_fields_set:
            _dict['project_id'] = None

        # set to None if ref_id (nullable) is None
        # and model_fields_set contains the field
        if self.ref_id is None and "ref_id" in self.model_fields_set:
            _dict['ref_id'] = None

        # set to None if root_id (nullable) is None
        # and model_fields_set contains the field
        if self.root_id is None and "root_id" in self.model_fields_set:
            _dict['root_id'] = None

        # set to None if shipping_country (nullable) is None
        # and model_fields_set contains the field
        if self.shipping_country is None and "shipping_country" in self.model_fields_set:
            _dict['shipping_country'] = None

        # set to None if status (nullable) is None
        # and model_fields_set contains the field
        if self.status is None and "status" in self.model_fields_set:
            _dict['status'] = None

        # set to None if text_tax (nullable) is None
        # and model_fields_set contains the field
        if self.text_tax is None and "text_tax" in self.model_fields_set:
            _dict['text_tax'] = None

        # set to None if title (nullable) is None
        # and model_fields_set contains the field
        if self.title is None and "title" in self.model_fields_set:
            _dict['title'] = None

        # set to None if vat_country (nullable) is None
        # and model_fields_set contains the field
        if self.vat_country is None and "vat_country" in self.model_fields_set:
            _dict['vat_country'] = None

        # set to None if fulfillment_country (nullable) is None
        # and model_fields_set contains the field
        if self.fulfillment_country is None and "fulfillment_country" in self.model_fields_set:
            _dict['fulfillment_country'] = None

        # set to None if vat_option (nullable) is None
        # and model_fields_set contains the field
        if self.vat_option is None and "vat_option" in self.model_fields_set:
            _dict['vat_option'] = None

        return _dict

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

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

        _obj = cls.model_validate({
            "address": DocumentAddress.from_dict(obj["address"]) if obj.get("address") is not None else None,
            "advanced_data_fields": [AdvancedDataField.from_dict(_item) for _item in obj["advanced_data_fields"]] if obj.get("advanced_data_fields") is not None else None,
            "attachment_ids": obj.get("attachment_ids"),
            "label_address": DocumentAddress.from_dict(obj["label_address"]) if obj.get("label_address") is not None else None,
            "amount": obj.get("amount"),
            "amount_net": obj.get("amount_net"),
            "anonymize_due_date": obj.get("anonymize_due_date"),
            "anonymize_status": obj.get("anonymize_status") if obj.get("anonymize_status") is not None else 'NOT_ANONYMIZED',
            "anonymized_at": obj.get("anonymized_at"),
            "bank_debit_form": obj.get("bank_debit_form") if obj.get("bank_debit_form") is not None else 'null',
            "billing_country": obj.get("billing_country"),
            "calc_vat_from": obj.get("calc_vat_from"),
            "cancel_id": obj.get("cancel_id"),
            "cash_allowance": obj.get("cash_allowance"),
            "cash_allowance_days": obj.get("cash_allowance_days"),
            "cash_allowance_text": obj.get("cash_allowance_text") if obj.get("cash_allowance_text") is not None else 'null',
            "contact_id": obj.get("contact_id"),
            "contact_label": obj.get("contact_label") if obj.get("contact_label") is not None else '',
            "contact_text": obj.get("contact_text") if obj.get("contact_text") is not None else '',
            "created_at": obj.get("created_at"),
            "currency": obj.get("currency") if obj.get("currency") is not None else 'EUR',
            "customer_id": obj.get("customer_id"),
            "customer_snapshot": CustomerSnapshot.from_dict(obj["customer_snapshot"]) if obj.get("customer_snapshot") is not None else None,
            "discount": obj.get("discount") if obj.get("discount") is not None else 'null',
            "discount_type": obj.get("discount_type") if obj.get("discount_type") is not None else null,
            "document_date": obj.get("document_date"),
            "due_date": obj.get("due_date"),
            "edited_at": obj.get("edited_at"),
            "external_id": obj.get("external_id") if obj.get("external_id") is not None else 'null',
            "replica_url": obj.get("replica_url") if obj.get("replica_url") is not None else 'null',
            "grace_period": obj.get("grace_period"),
            "due_in_days": obj.get("due_in_days"),
            "id": obj.get("id"),
            "is_acceptable_on_public_domain": obj.get("is_acceptable_on_public_domain") if obj.get("is_acceptable_on_public_domain") is not None else False,
            "is_archive": obj.get("is_archive") if obj.get("is_archive") is not None else False,
            "is_draft": obj.get("is_draft"),
            "is_replica": obj.get("is_replica") if obj.get("is_replica") is not None else False,
            "is_oss": obj.get("is_oss") if obj.get("is_oss") is not None else False,
            "item_notes": obj.get("item_notes"),
            "items": [DocumentPosition.from_dict(_item) for _item in obj["items"]] if obj.get("items") is not None else None,
            "last_postbox_id": obj.get("last_postbox_id"),
            "login_id": obj.get("login_id"),
            "number": obj.get("number") if obj.get("number") is not None else 'null',
            "order_number": obj.get("order_number") if obj.get("order_number") is not None else '',
            "buyer_reference": obj.get("buyer_reference") if obj.get("buyer_reference") is not None else '',
            "paid_amount": obj.get("paid_amount"),
            "paid_at": obj.get("paid_at"),
            "pdf_pages": obj.get("pdf_pages"),
            "pdf_template": obj.get("pdf_template"),
            "payment_link_enabled": obj.get("payment_link_enabled") if obj.get("payment_link_enabled") is not None else False,
            "payment_link_locale": obj.get("payment_link_locale") if obj.get("payment_link_locale") is not None else 'de',
            "project_id": obj.get("project_id"),
            "recurring_options": DocumentRecurring.from_dict(obj["recurring_options"]) if obj.get("recurring_options") is not None else None,
            "ref_id": obj.get("ref_id"),
            "root_id": obj.get("root_id"),
            "service_date": ServiceDate.from_dict(obj["service_date"]) if obj.get("service_date") is not None else None,
            "shipping_country": obj.get("shipping_country") if obj.get("shipping_country") is not None else 'null',
            "status": obj.get("status") if obj.get("status") is not None else null,
            "text": obj.get("text"),
            "text_prefix": obj.get("text_prefix"),
            "text_tax": obj.get("text_tax") if obj.get("text_tax") is not None else 'null',
            "title": obj.get("title") if obj.get("title") is not None else 'null',
            "type": obj.get("type") if obj.get("type") is not None else 'INVOICE',
            "use_shipping_address": obj.get("use_shipping_address") if obj.get("use_shipping_address") is not None else False,
            "vat_country": obj.get("vat_country") if obj.get("vat_country") is not None else 'null',
            "vat_id": obj.get("vat_id") if obj.get("vat_id") is not None else '',
            "fulfillment_country": obj.get("fulfillment_country") if obj.get("fulfillment_country") is not None else 'null',
            "vat_option": obj.get("vat_option") if obj.get("vat_option") is not None else null,
            "file_format_config": [FileFormatConfig.from_dict(_item) for _item in obj["file_format_config"]] if obj.get("file_format_config") is not None else None
        })
        return _obj


