easybill_client/generated/async/easybill_generated_async/models/time_tracking.py
claudi caacb339dd Add unit tests for authentication and webhook parsing
- 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.
2026-04-17 10:20:12 +02:00

162 lines
7.7 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 datetime
from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing import Optional, Set
from typing_extensions import Self
from pydantic_core import to_jsonable_python
class TimeTracking(BaseModel):
"""
TimeTracking
""" # noqa: E501
cleared_at: Optional[datetime] = None
created_at: Optional[datetime] = None
date_from_at: Optional[datetime] = None
date_thru_at: Optional[datetime] = None
description: StrictStr
hourly_rate: Optional[Union[StrictFloat, StrictInt]] = Field(default=0.0, description="Hourly rate in cents (e.g. \"150\" = 1.50€)")
id: Optional[StrictInt] = None
note: Optional[StrictStr] = 'null'
number: Optional[StrictStr] = Field(default=None, description="Can be chosen freely")
position_id: Optional[StrictInt] = None
project_id: Optional[StrictInt] = None
login_id: Optional[StrictInt] = Field(default=None, description="If omitted or null, the currently active login is used.")
timer_value: Optional[StrictInt] = Field(default=None, description="Tracked time in minutes")
__properties: ClassVar[List[str]] = ["cleared_at", "created_at", "date_from_at", "date_thru_at", "description", "hourly_rate", "id", "note", "number", "position_id", "project_id", "login_id", "timer_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 TimeTracking 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.
"""
excluded_fields: Set[str] = set([
"created_at",
"id",
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# set to None if cleared_at (nullable) is None
# and model_fields_set contains the field
if self.cleared_at is None and "cleared_at" in self.model_fields_set:
_dict['cleared_at'] = None
# set to None if date_from_at (nullable) is None
# and model_fields_set contains the field
if self.date_from_at is None and "date_from_at" in self.model_fields_set:
_dict['date_from_at'] = None
# set to None if date_thru_at (nullable) is None
# and model_fields_set contains the field
if self.date_thru_at is None and "date_thru_at" in self.model_fields_set:
_dict['date_thru_at'] = None
# set to None if note (nullable) is None
# and model_fields_set contains the field
if self.note is None and "note" in self.model_fields_set:
_dict['note'] = 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 position_id (nullable) is None
# and model_fields_set contains the field
if self.position_id is None and "position_id" in self.model_fields_set:
_dict['position_id'] = 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 login_id (nullable) is None
# and model_fields_set contains the field
if self.login_id is None and "login_id" in self.model_fields_set:
_dict['login_id'] = None
# set to None if timer_value (nullable) is None
# and model_fields_set contains the field
if self.timer_value is None and "timer_value" in self.model_fields_set:
_dict['timer_value'] = None
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TimeTracking from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"cleared_at": obj.get("cleared_at"),
"created_at": obj.get("created_at"),
"date_from_at": obj.get("date_from_at"),
"date_thru_at": obj.get("date_thru_at"),
"description": obj.get("description"),
"hourly_rate": obj.get("hourly_rate") if obj.get("hourly_rate") is not None else 0.0,
"id": obj.get("id"),
"note": obj.get("note") if obj.get("note") is not None else 'null',
"number": obj.get("number"),
"position_id": obj.get("position_id"),
"project_id": obj.get("project_id"),
"login_id": obj.get("login_id"),
"timer_value": obj.get("timer_value")
})
return _obj