- Implement tests for basic and bearer authentication headers in `test_auth.py`. - Create tests for the `EasybillWebhookParser` in `test_webhooks.py`, covering JSON and form-encoded payloads, as well as a generic parse and acknowledgement method.
491 lines
29 KiB
Python
491 lines
29 KiB
Python
# 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
|
|
|
|
|