event to functon handler completed

This commit is contained in:
berkay 2025-01-15 19:18:11 +03:00
parent 25539c56cc
commit 76d286b519
55 changed files with 1271 additions and 1092 deletions

View File

@ -3,5 +3,5 @@
<component name="Black"> <component name="Black">
<option name="sdkName" value="Python 3.10 (hardware-data-lake)" /> <option name="sdkName" value="Python 3.10 (hardware-data-lake)" />
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 virtualenv at ~/git-gitea-evyos/wag-managment-api-service-version-3/.venv" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 virtualenv at ~/git-gitea-evyos/wag-managment-api-service-version-4/venv" project-jdk-type="Python SDK" />
</project> </project>

View File

@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.12 virtualenv at ~/git-gitea-evyos/wag-managment-api-service-version-3/.venv" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.12 virtualenv at ~/git-gitea-evyos/wag-managment-api-service-version-4/venv" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View File

View File

@ -0,0 +1,357 @@
import typing
from ApiValidations.Custom.token_objects import (
OccupantTokenObject,
EmployeeTokenObject,
)
from Schemas import (
BuildLivingSpace,
AccountRecords,
BuildIbans,
BuildDecisionBookPayments,
ApiEnumDropdown,
)
from ApiLibrary import system_arrow
from ApiValidations.Request import (
InsertAccountRecord,
UpdateAccountRecord,
ListOptions,
)
from Services.PostgresDb.Models.alchemy_response import AlchemyJsonResponse
from ApiEvents.abstract_class import (
MethodToEvent,
RouteFactoryConfig,
EndpointFactoryConfig,
)
from ApiValidations.Response import AccountRecordResponse
class AccountRecordsListEventMethods(MethodToEvent):
event_type = "SELECT"
event_description = ""
event_category = ""
__event_keys__ = {
"7192c2aa-5352-4e36-98b3-dafb7d036a3d": "account_records_list",
"208e6273-17ef-44f0-814a-8098f816b63a": "account_records_list_flt_res",
}
__event_validation__ = {
"7192c2aa-5352-4e36-98b3-dafb7d036a3d": AccountRecordResponse,
"208e6273-17ef-44f0-814a-8098f816b63a": AccountRecordResponse,
}
@classmethod
def account_records_list(
cls,
list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
db_session = AccountRecords.new_session()
if isinstance(token_dict, OccupantTokenObject):
AccountRecords.pre_query = AccountRecords.filter_all(
AccountRecords.company_id
== token_dict.selected_occupant.responsible_company_id,
db=db_session,
).query
elif isinstance(token_dict, EmployeeTokenObject):
AccountRecords.pre_query = AccountRecords.filter_all(
AccountRecords.company_id == token_dict.selected_company.company_id,
db=db_session,
).query
AccountRecords.filter_attr = list_options
records = AccountRecords.filter_all(db=db_session)
return AlchemyJsonResponse(
completed=True,
message="Account records listed successfully",
result=records,
cls_object=AccountRecords,
filter_attributes=list_options,
response_model=AccountRecordResponse,
)
@classmethod
def account_records_list_flt_res(
cls,
list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
db_session = AccountRecords.new_session()
if not isinstance(token_dict, OccupantTokenObject):
raise AccountRecords.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message="Only Occupant can see this data",
data={},
)
return_list = []
living_space: BuildLivingSpace = BuildLivingSpace.filter_by_one(
id=token_dict.selected_occupant.living_space_id
).data
if not living_space:
raise AccountRecords.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message="Living space not found",
data={},
)
if not list_options:
list_options = ListOptions()
main_filters = [
AccountRecords.living_space_id
== token_dict.selected_occupant.living_space_id,
BuildDecisionBookPayments.process_date
>= str(system_arrow.now().shift(months=-3).date()),
BuildDecisionBookPayments.process_date
< str(system_arrow.find_last_day_of_month(living_space.expiry_ends)),
BuildDecisionBookPayments.process_date
>= str(system_arrow.get(living_space.expiry_starts)),
BuildDecisionBookPayments.is_confirmed == True,
AccountRecords.active == True,
]
order_type = "desc"
if list_options.order_type:
order_type = "asc" if list_options.order_type[0] == "a" else "desc"
order_by_list = BuildDecisionBookPayments.process_date.desc()
if list_options.order_field:
if list_options.order_field == "process_date":
order_by_list = (
BuildDecisionBookPayments.process_date.asc()
if order_type == "asc"
else BuildDecisionBookPayments.process_date.desc()
)
if list_options.order_field == "bank_date":
order_by_list = (
AccountRecords.bank_date.desc()
if order_type == "asc"
else AccountRecords.bank_date.asc()
)
if list_options.order_field == "currency_value":
order_by_list = (
AccountRecords.currency_value.desc()
if order_type == "asc"
else AccountRecords.currency_value.asc()
)
if list_options.order_field == "process_comment":
order_by_list = (
AccountRecords.process_comment.desc()
if order_type == "asc"
else AccountRecords.process_comment.asc()
)
if list_options.order_field == "payment_amount":
order_by_list = (
BuildDecisionBookPayments.payment_amount.desc()
if order_type == "asc"
else BuildDecisionBookPayments.payment_amount.asc()
)
if list_options.query:
for key, value in list_options.query.items():
if key == "process_date":
main_filters.append(BuildDecisionBookPayments.process_date == value)
if key == "bank_date":
main_filters.append(AccountRecords.bank_date == value)
if key == "currency":
main_filters.append(BuildDecisionBookPayments.currency == value)
if key == "currency_value":
main_filters.append(AccountRecords.currency_value == value)
if key == "process_comment":
main_filters.append(AccountRecords.process_comment == value)
if key == "payment_amount":
main_filters.append(
BuildDecisionBookPayments.payment_amount == value
)
query = (
AccountRecords.session.query(
BuildDecisionBookPayments.process_date,
BuildDecisionBookPayments.payment_amount,
BuildDecisionBookPayments.currency,
AccountRecords.bank_date,
AccountRecords.currency_value,
AccountRecords.process_comment,
BuildDecisionBookPayments.uu_id,
)
.join(
AccountRecords,
AccountRecords.id == BuildDecisionBookPayments.account_records_id,
)
.filter(*main_filters)
).order_by(order_by_list)
query.limit(list_options.size or 5).offset(
(list_options.page or 1 - 1) * list_options.size or 5
)
for list_of_values in query.all() or []:
return_list.append(
{
"process_date": list_of_values[0],
"payment_amount": list_of_values[1],
"currency": list_of_values[2],
"bank_date": list_of_values[3],
"currency_value": list_of_values[4],
"process_comment": list_of_values[5],
}
)
return AlchemyJsonResponse(
completed=True,
message="Account records listed successfully",
result=return_list,
cls_object=AccountRecords,
filter_attributes=list_options,
response_model=AccountRecordResponse,
)
class AccountRecordsCreateEventMethods(MethodToEvent):
event_type = "CREATE"
event_description = ""
event_category = ""
__event_keys__ = {
"31f4f32f-0cd4-4995-8a6a-f9f56335848a": "account_records_create",
}
__event_validation__ = {
"31f4f32f-0cd4-4995-8a6a-f9f56335848a": InsertAccountRecord,
}
@classmethod
def account_records_create(
cls,
data: InsertAccountRecord,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
data_dict = data.excluded_dump()
if isinstance(token_dict, OccupantTokenObject):
db_session = AccountRecords.new_session()
build_iban = BuildIbans.filter_one(
BuildIbans.iban == data.iban,
BuildIbans.build_id == token_dict.selected_occupant.build_id,
db=db_session,
).data
if not build_iban:
raise BuildIbans.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message=f"{data.iban} is not found in company related to your organization",
data={
"iban": data.iban,
},
)
account_record = AccountRecords.find_or_create(**data.excluded_dump())
return AlchemyJsonResponse(
completed=True,
message="Account record created successfully",
result=account_record,
)
elif isinstance(token_dict, EmployeeTokenObject):
# Build.pre_query = Build.select_action(
# employee_id=token_dict.selected_employee.employee_id,
# )
# build_ids_list = Build.filter_all(
# )
# build_iban = BuildIbans.filter_one(
# BuildIbans.iban == data.iban,
# BuildIbans.build_id.in_([build.id for build in build_ids_list.data]),
# ).data
# if not build_iban:
# BuildIbans.raise_http_exception(
# status_code="HTTP_404_NOT_FOUND",
# error_case="UNAUTHORIZED",
# message=f"{data.iban} is not found in company related to your organization",
# data={
# "iban": data.iban,
# },
# )
bank_date = system_arrow.get(data.bank_date)
data_dict["bank_date_w"] = bank_date.weekday()
data_dict["bank_date_m"] = bank_date.month
data_dict["bank_date_d"] = bank_date.day
data_dict["bank_date_y"] = bank_date.year
if int(data.currency_value) < 0:
debit_type = ApiEnumDropdown.filter_by_one(
system=True, enum_class="DebitTypes", key="DT-D"
).data
data_dict["receive_debit"] = debit_type.id
data_dict["receive_debit_uu_id"] = str(debit_type.uu_id)
else:
debit_type = ApiEnumDropdown.filter_by_one(
system=True, enum_class="DebitTypes", key="DT-R"
).data
data_dict["receive_debit"] = debit_type.id
data_dict["receive_debit_uu_id"] = str(debit_type.uu_id)
account_record = AccountRecords.insert_one(data_dict).data
return AlchemyJsonResponse(
completed=True,
message="Account record created successfully",
result=account_record,
)
class AccountRecordsUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
event_description = ""
event_category = ""
__event_keys__ = {
"ec98ef2c-bcd0-432d-a8f4-1822a56c33b2": "account_records_update",
}
__event_validation__ = {
"ec98ef2c-bcd0-432d-a8f4-1822a56c33b2": UpdateAccountRecord,
}
@classmethod
def build_area_update(
cls,
build_uu_id: str,
data: UpdateAccountRecord,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
pass
elif isinstance(token_dict, EmployeeTokenObject):
pass
AccountRecords.build_parts_id = token_dict.selected_occupant.build_part_id
account_record = AccountRecords.update_one(build_uu_id, data).data
return AlchemyJsonResponse(
completed=True,
message="Account record updated successfully",
result=account_record,
cls_object=AccountRecords,
response_model=UpdateAccountRecord,
)
class AccountRecordsPatchEventMethods(MethodToEvent):
event_type = "PATCH"
event_description = ""
event_category = ""
__event_keys__ = {
"34c38937-42a2-45f1-b2ef-a23978650aee": "account_records_patch",
}
__event_validation__ = {
"34c38937-42a2-45f1-b2ef-a23978650aee": None,
}
@classmethod
def build_area_patch(
cls,
build_uu_id: str,
data,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
account_record = AccountRecords.patch_one(build_uu_id, data).data
return AlchemyJsonResponse(
completed=True,
message="Account record patched successfully",
result=account_record,
)

View File

@ -0,0 +1,99 @@
"""
Route configuration registry.
This module collects and registers all route configurations from different modules
to be used by the dynamic route creation system.
"""
from typing import Dict, List, Any, Callable
from fastapi import Request
from ApiEvents.abstract_class import RouteFactoryConfig, EndpointFactoryConfig
from ApiEvents.EventServiceApi.utils import with_token_event
from ApiEvents.EventServiceApi.account.account_records import (
AccountRecordsListEventMethods,
ListOptions,
InsertAccountRecord,
SearchAddress,
UpdateAccountRecord,
)
@with_token_event
def address_list(request: Request, list_options: ListOptions):
"""Handle address list endpoint."""
pass
@with_token_event
def address_create(request: Request, data: InsertAccountRecord):
"""Handle address creation endpoint."""
pass
@with_token_event
def address_search(request: Request, data: SearchAddress):
"""Handle address search endpoint."""
pass
@with_token_event
def address_update(request: Request, address_uu_id: str, data: UpdateAccountRecord):
"""Handle address update endpoint."""
pass
# Account Records Router Configuration
ACCOUNT_RECORDS_CONFIG = {
'name': 'account_records',
'prefix': '/account/records',
'tags': ['Account Records'],
'include_in_schema': True,
'endpoints': [
EndpointFactoryConfig(
endpoint="/list",
method="POST",
summary="List Active/Delete/Confirm Address",
description="List Active/Delete/Confirm Address",
is_auth_required=True,
is_event_required=True,
request_model=ListOptions,
endpoint_function=address_list
),
EndpointFactoryConfig(
endpoint="/create",
method="POST",
summary="Create Address with given auth levels",
description="Create Address with given auth levels",
is_auth_required=True,
is_event_required=True,
request_model=InsertAccountRecord,
endpoint_function=address_create
),
EndpointFactoryConfig(
endpoint="/search",
method="POST",
summary="Search Address with given auth levels",
description="Search Address with given auth levels",
is_auth_required=True,
is_event_required=True,
request_model=SearchAddress,
endpoint_function=address_search
),
EndpointFactoryConfig(
endpoint="/update/{address_uu_id}",
method="POST",
summary="Update Address with given auth levels",
description="Update Address with given auth levels",
is_auth_required=True,
is_event_required=True,
request_model=UpdateAccountRecord,
endpoint_function=address_update
)
]
}
# Registry of all route configurations
ROUTE_CONFIGS = [
ACCOUNT_RECORDS_CONFIG,
# Add other route configurations here
]
def get_route_configs() -> List[Dict[str, Any]]:
"""Get all registered route configurations."""
return ROUTE_CONFIGS

View File

@ -0,0 +1,51 @@
"""
Utility functions for API event handling.
"""
from functools import wraps
from inspect import signature
from typing import Callable, TypeVar, ParamSpec, Any
from fastapi import Request
from Services.PostgresDb.Models.token_models import parse_token_object_to_dict
P = ParamSpec('P')
R = TypeVar('R')
def with_token_event(func: Callable[P, R]) -> Callable[P, R]:
"""
Decorator that handles token parsing and event execution.
This decorator:
1. Parses the token from the request
2. Calls the appropriate event with the token and other arguments
Args:
func: The endpoint function to wrap
Returns:
Wrapped function that handles token parsing and event execution
"""
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
# Extract request from args or kwargs
request = next(
(arg for arg in args if isinstance(arg, Request)),
kwargs.get('request')
)
if not request:
raise ValueError("Request object not found in arguments")
# Parse token
token_dict = parse_token_object_to_dict(request=request)
# Add token_dict to kwargs
kwargs['token_dict'] = token_dict
# Call the original function
return token_dict.available_event(**{
k: v for k, v in kwargs.items()
if k in signature(token_dict.available_event).parameters
})
return wrapper

181
ApiEvents/abstract_class.py Normal file
View File

@ -0,0 +1,181 @@
"""
Abstract base classes for API route and event handling.
This module provides core abstractions for route configuration and factory,
with support for authentication and event handling.
"""
from typing import Optional, Dict, Any, List, Type, Union, ClassVar, Tuple, TypeVar
from dataclasses import dataclass, field
from pydantic import BaseModel
ResponseModel = TypeVar('ResponseModel', bound=BaseModel)
@dataclass
class EndpointFactoryConfig:
"""Configuration class for API endpoints.
Attributes:
endpoint: URL path for this endpoint
method: HTTP method (GET, POST, etc.)
summary: Short description for API documentation
description: Detailed description for API documentation
is_auth_required: Whether authentication is required
is_event_required: Whether event handling is required
request_model: Expected request model type
extra_options: Additional endpoint options
response_model: Expected response model type
"""
endpoint: str
method: str
summary: str
description: str
is_auth_required: bool
is_event_required: bool
request_model: Type[BaseModel]
extra_options: Dict[str, Any] = field(default_factory=dict)
response_model: Optional[Type[BaseModel]] = None
@dataclass
class RouteFactoryConfig:
"""Configuration class for API route factories.
Attributes:
name: Route name
tags: List of tags for API documentation
prefix: URL prefix for all endpoints in this route
include_in_schema: Whether to include in OpenAPI schema
endpoints: List of endpoint configurations
extra_options: Additional route options
"""
name: str
tags: Union[str, List[str]]
prefix: str
include_in_schema: bool = True
endpoints: List[EndpointFactoryConfig] = field(default_factory=list)
extra_options: Dict[str, Any] = field(default_factory=dict)
def __post_init__(self):
"""Validate and normalize configuration after initialization."""
if isinstance(self.tags, str):
self.tags = [self.tags]
def as_dict(self) -> Dict[str, Any]:
"""Convert configuration to dictionary format."""
return {
"name": self.name,
"tags": self.tags,
"prefix": self.prefix,
"include_in_schema": self.include_in_schema,
"endpoints": [
{
"endpoint": ep.endpoint,
"method": ep.method,
"summary": ep.summary,
"description": ep.description,
"is_auth_required": ep.is_auth_required,
"is_event_required": ep.is_event_required,
"response_model": ep.response_model.__name__ if ep.response_model else None,
"request_model": ep.request_model.__name__,
"extra_options": ep.extra_options
}
for ep in self.endpoints
],
"extra_options": self.extra_options
}
class ActionsSchema:
"""Base class for defining API action schemas.
This class handles endpoint registration and validation in the database.
Subclasses should implement specific validation logic.
"""
def __init__(self, endpoint: str):
"""Initialize with an API endpoint path.
Args:
endpoint: The API endpoint path (e.g. "/users/create")
"""
self.endpoint = endpoint
def retrieve_action_from_endpoint(self) -> Dict[str, Any]:
"""Retrieve the endpoint registration from the database.
Returns:
Dict containing the endpoint registration data
Raises:
HTTPException: If endpoint is not found in database
"""
raise NotImplementedError("Subclasses must implement retrieve_action_from_endpoint")
class ActionsSchemaFactory:
"""Factory class for creating and validating action schemas.
This class ensures proper initialization and validation of API endpoints
through their action schemas.
"""
def __init__(self, action: ActionsSchema):
"""Initialize with an action schema.
Args:
action: The action schema to initialize
Raises:
HTTPException: If action initialization fails
"""
self.action = action
self.action_match = self.action.retrieve_action_from_endpoint()
class MethodToEvent:
"""Base class for mapping methods to API events with type safety.
This class provides a framework for handling API events with proper
type checking for tokens and response models.
Type Parameters:
TokenType: Type of authentication token
ResponseModel: Type of response model
"""
action_key: ClassVar[Optional[str]] = None
event_type: ClassVar[Optional[str]] = None
event_description: ClassVar[str] = ""
event_category: ClassVar[str] = ""
__event_keys__: ClassVar[Dict[str, str]] = {}
__event_validation__: ClassVar[List[Tuple[Type[ResponseModel], List[Dict[str, Any]]]]] = []
@classmethod
def retrieve_language_parameters(
cls, language: str, function_code: str
) -> Dict[str, str]:
"""Retrieve language-specific parameters for an event.
Args:
language: Language code (e.g. 'tr', 'en')
function_code: Function identifier
Returns:
Dictionary of language-specific field mappings
"""
validation_dict = dict(cls.__event_validation__)
if function_code not in validation_dict:
return {}
event_response_model, event_language_models = validation_dict[function_code]
# Collect language-specific field mappings
language_models = {}
for model in event_language_models:
language_models.update(model.get(language, model.get("tr", {})))
# Map response model fields to language-specific values
return {
field: language_models[field]
for field in event_response_model.model_fields
if field in language_models
}

View File

@ -1,7 +1,4 @@
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
)
from typing import Optional from typing import Optional

View File

@ -1,10 +1,8 @@
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
ListOptions,
)
from typing import Optional from typing import Optional
from ApiValidations.Request import PydanticBaseModel, ListOptions
from ApiValidations.handler import BaseModelRegular
class PostCodeValidation: class PostCodeValidation:
tr = { tr = {

View File

@ -1,4 +1,4 @@
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
class SingleEnumClassKeyValidation: class SingleEnumClassKeyValidation:

View File

@ -1,8 +1,5 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
)
class BuildAreaValidation: class BuildAreaValidation:

View File

@ -1,4 +1,5 @@
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
from typing import Optional from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel

View File

@ -1,44 +1,14 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel, # from api_validations.validations_request import (
PydanticBaseModelValidation, # PydanticBaseModel,
) # PydanticBaseModelValidation,
# )
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
class BuildLivingSpaceValidation: class InsertBuildLivingSpace(BaseModelRegular):
tr = {
"person_uu_id": "Kişi UUID'si",
"build_parts_uu_id": "Bina UUID'si",
"occupant_type_uu_id": "Mülk Sahibi UUID'si",
"expiry_starts": "Geçerlilik Başlangıç Tarihi",
"expiry_ends": "Geçerlilik Bitiş Tarihi",
}
en = {
"person_uu_id": "Person UUID",
"build_parts_uu_id": "Build UUID",
"occupant_type_uu_id": "Occupant UUID",
"expiry_starts": "Expiry Starts",
"expiry_ends": "Expiry Ends",
}
class PydanticBaseModelValidationUpdate:
tr = {
**PydanticBaseModelValidation.tr,
"is_tenant_live": "Kiracı mı?",
"build_parts_uu_id": "Bina UUID'si",
"person_uu_id": "Kişi UUID'si",
}
en = {
**PydanticBaseModelValidation.en,
"is_tenant_live": "Is Tenant Live?",
"build_parts_uu_id": "Build UUID",
"person_uu_id": "Person UUID",
}
class InsertBuildLivingSpace(BaseModelRegular, BuildLivingSpaceValidation):
person_uu_id: str person_uu_id: str
build_parts_uu_id: str build_parts_uu_id: str
occupant_type_uu_id: str occupant_type_uu_id: str
@ -46,7 +16,7 @@ class InsertBuildLivingSpace(BaseModelRegular, BuildLivingSpaceValidation):
expiry_ends: Optional[str] = None expiry_ends: Optional[str] = None
class UpdateBuildLivingSpace(PydanticBaseModel, BuildLivingSpaceValidation): class UpdateBuildLivingSpace(PydanticBaseModel):
is_tenant_live: Optional[bool] = None is_tenant_live: Optional[bool] = None
build_parts_uu_id: Optional[str] = None build_parts_uu_id: Optional[str] = None
person_uu_id: Optional[str] = None person_uu_id: Optional[str] = None

View File

@ -1,81 +1,18 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
)
class BuildTypesUpdateValidation: class InsertBuildTypes(BaseModelRegular):
tr = {
**PydanticBaseModelValidation.tr,
"function_code": "Fonksiyon Kodu",
"type_code": "Tip Kodu",
"lang": "Dil",
"type_name": "Tip Adı",
}
en = {
**PydanticBaseModelValidation.en,
"function_code": "Function Code",
"type_code": "Type Code",
"lang": "Language",
"type_name": "Type Name",
}
class BuildTypesValidation:
tr = {
"function_code": "Fonksiyon Kodu",
"type_code": "Tip Kodu",
"lang": "Dil",
"type_name": "Tip Adı",
}
en = {
"function_code": "Function Code",
"type_code": "Type Code",
"lang": "Language",
"type_name": "Type Name",
}
class InsertBuildTypes(BaseModelRegular, BuildTypesValidation):
function_code: str function_code: str
type_code: str type_code: str
lang: str lang: str
type_name: str type_name: str
class UpdateBuildTypes(PydanticBaseModel, BuildTypesUpdateValidation): ... class UpdateBuildTypes(PydanticBaseModel): ...
class BuildPartsValidation: class InsertBuildParts(BaseModelRegular):
tr = {
"address_gov_code": "Adres İl Kodu",
"part_no": "Daire No",
"part_level": "Daire Seviyesi",
"build_part_type_uu_id": "Bina Daire Tipi UUID'si",
"part_code": "Daire Kodu",
"part_gross_size": "Daire Brüt Alanı",
"part_net_size": "Daire Net Alanı",
"default_accessory": "Varsayılan Aksesuar",
"human_livable": "İnsan Yaşanabilir",
"part_direction": "Daire Yönü",
}
en = {
"address_gov_code": "Address Gov Code",
"part_no": "Flat No",
"part_level": "Flat Level",
"build_part_type_uu_id": "Build Flat Type UUID",
"part_code": "Flat Code",
"part_gross_size": "Flat Gross Size",
"part_net_size": "Flat Net Size",
"default_accessory": "Default Accessory",
"human_livable": "Human Livable",
"part_direction": "Flat Direction",
}
class InsertBuildParts(BaseModelRegular, BuildPartsValidation):
build_uu_id: str build_uu_id: str
address_gov_code: str address_gov_code: str
part_no: int part_no: int
@ -90,40 +27,7 @@ class InsertBuildParts(BaseModelRegular, BuildPartsValidation):
ref_id: Optional[str] = None ref_id: Optional[str] = None
class UpdateBuildPartsValidation: class UpdateBuildParts(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"address_gov_code": "Adres İl Kodu",
"part_no": "Daire No",
"part_level": "Daire Seviyesi",
"build_part_type_uu_id": "Bina Daire Tipi UUID'si",
"part_code": "Daire Kodu",
"part_gross_size": "Daire Brüt Alanı",
"part_net_size": "Daire Net Alanı",
"default_accessory": "Varsayılan Aksesuar",
"human_livable": "İnsan Yaşanabilir",
"part_direction": "Daire Yönü",
"current_owner_person_uu_id": "Mevcut Sahip Kişi UUID'si",
"current_tenant_person_uu_id": "Mevcut Kiracı Kişi UUID'si",
}
en = {
**PydanticBaseModelValidation.en,
"address_gov_code": "Address Gov Code",
"part_no": "Flat No",
"part_level": "Flat Level",
"build_part_type_uu_id": "Build Flat Type UUID",
"part_code": "Flat Code",
"part_gross_size": "Flat Gross Size",
"part_net_size": "Flat Net Size",
"default_accessory": "Default Accessory",
"human_livable": "Human Livable",
"part_direction": "Flat Direction",
"current_owner_person_uu_id": "Current Owner Person UUID",
"current_tenant_person_uu_id": "Current Tenant Person UUID",
}
class UpdateBuildParts(PydanticBaseModel, UpdateBuildPartsValidation):
address_gov_code: Optional[str] = None address_gov_code: Optional[str] = None
part_no: Optional[int] = None part_no: Optional[int] = None
part_level: Optional[int] = None part_level: Optional[int] = None

View File

@ -1,57 +1,9 @@
from typing import Optional from typing import Optional
from datetime import datetime from datetime import datetime
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
CrudRecordValidation,
)
class BuildValidation: class InsertBuild(BaseModelRegular):
tr = {
**CrudRecordValidation.tr,
"gov_address_code": "Devlet Adres Kodu",
"build_name": "Bina Adı",
"build_types_uu_id": "Bina Tipi",
"build_no": "Bina No",
"max_floor": "Kat Sayısı",
"underground_floor": "Bodrum Kat Sayısı",
"address_uu_id": "Adres",
"build_date": "Yapım Tarihi",
"decision_period_date": "Karar Tarihi",
"tax_no": "Vergi No",
"lift_count": "Asansör Sayısı",
"heating_system": "Isıtma Sistemi",
"cooling_system": "Soğutma Sistemi",
"hot_water_system": "Sıcak Su Sistemi",
"block_service_man_count": "Hizmet Görevlisi Sayısı",
"security_service_man_count": "Güvenlik Görevlisi Sayısı",
"garage_count": "Garaj Sayısı",
}
en = {
**CrudRecordValidation.en,
"gov_address_code": "Government Address Code",
"build_name": "Building Name",
"build_types_uu_id": "Building Type",
"build_no": "Building No",
"max_floor": "Number of Floors",
"underground_floor": "Number of Basement Floors",
"address_uu_id": "Address",
"build_date": "Construction Date",
"decision_period_date": "Decision Date",
"tax_no": "Tax No",
"lift_count": "Number of Elevators",
"heating_system": "Heating System",
"cooling_system": "Cooling System",
"hot_water_system": "Hot Water System",
"block_service_man_count": "Number of Service Officers",
"security_service_man_count": "Number of Security Officers",
"garage_count": "Number of Garages",
}
class InsertBuild(BaseModelRegular, BuildValidation):
gov_address_code: str gov_address_code: str
build_name: str build_name: str
@ -72,18 +24,7 @@ class InsertBuild(BaseModelRegular, BuildValidation):
garage_count: Optional[int] = None garage_count: Optional[int] = None
class BuildUpdateValidation: class UpdateBuild(PydanticBaseModel):
tr = {
**BuildValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**BuildValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuild(PydanticBaseModel, BuildUpdateValidation):
gov_address_code: Optional[str] = None gov_address_code: Optional[str] = None
build_name: Optional[str] = None build_name: Optional[str] = None
build_no: Optional[str] = None build_no: Optional[str] = None

View File

@ -1,26 +1,8 @@
from typing import Optional, List from typing import Optional, List
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
)
class CompanyValidation: class InsertCompany(BaseModelRegular):
tr = {
"formal_name": "Resmi Ad",
"company_type": "Şirket Tipi",
"commercial_type": "Ticari Tip",
"tax_no": "Vergi No",
"public_name": "Halka Açık Ad",
"company_tag": "Şirket Etiketi",
"default_lang_type": "Varsayılan Dil Tipi",
"default_money_type": "Varsayılan Para Tipi",
"official_address_uu_id": "Resmi Adres UU ID",
}
class InsertCompany(BaseModelRegular, CompanyValidation):
formal_name: str formal_name: str
company_type: str company_type: str
commercial_type: str commercial_type: str
@ -33,18 +15,7 @@ class InsertCompany(BaseModelRegular, CompanyValidation):
# parent_uu_id: Optional[int] = None # parent_uu_id: Optional[int] = None
class CompanyUpdateValidation: class UpdateCompany(PydanticBaseModel):
tr = {
**CompanyValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**CompanyValidation.tr,
**PydanticBaseModelValidation.en,
}
class UpdateCompany(PydanticBaseModel, CompanyUpdateValidation):
company_uu_id: str company_uu_id: str
public_name: Optional[str] = None public_name: Optional[str] = None
formal_name: Optional[str] = None formal_name: Optional[str] = None
@ -55,20 +26,7 @@ class UpdateCompany(PydanticBaseModel, CompanyUpdateValidation):
official_address_uu_id: Optional[str] = None official_address_uu_id: Optional[str] = None
class MatchCompany2CompanyValidation: class MatchCompany2Company(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"match_company_uu_id": "Eşleşen Şirket UU ID",
"duty_uu_id": "Görev UU ID",
}
en = {
**PydanticBaseModelValidation.en,
"match_company_uu_id": "Match Company UU ID",
"duty_uu_id": "Duty UU ID",
}
class MatchCompany2Company(PydanticBaseModel, MatchCompany2CompanyValidation):
match_company_uu_id: List[str] match_company_uu_id: List[str]
duty_uu_id: str duty_uu_id: str
show_only: Optional[bool] = None show_only: Optional[bool] = None

View File

@ -1,6 +1,6 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
class ListOptionsValidation: class ListOptionsValidation:

View File

@ -1,127 +1,34 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel, ListOptions
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class DecisionBookDecisionBookInvitationsValidation: class DecisionBookDecisionBookInvitations(BaseModelRegular):
tr = {
"build_decision_book_uu_id": "Karar Defteri UUID",
"message": "Mesaj",
"planned_date": "Planlanan Tarih",
}
en = {
"build_decision_book_uu_id": "Decision Book UUID",
"message": "Message",
"planned_date": "Planned Date",
}
class DecisionBookDecisionBookInvitations(
BaseModelRegular, DecisionBookDecisionBookInvitationsValidation
):
build_decision_book_uu_id: str build_decision_book_uu_id: str
message: str message: str
planned_date: str planned_date: str
class DecisionBookDecisionBookInvitationsAttendValidation: class DecisionBookDecisionBookInvitationsAttend(BaseModelRegular):
tr = {
"token": "Token",
"is_attend": "Katılacak mı?",
}
en = {
"token": "Token",
"is_attend": "Is Attend?",
}
class DecisionBookDecisionBookInvitationsAttend(
BaseModelRegular, DecisionBookDecisionBookInvitationsAttendValidation
):
token: str token: str
is_attend: bool is_attend: bool
class DecisionBookDecisionBookInvitationsAssignValidation: class DecisionBookDecisionBookInvitationsAssign(BaseModelRegular):
tr = {
"token": "Token",
"build_living_space_uu_id": "Yapı Yaşam Alanı UUID",
"occupant_type_uu_id": "Sakin Tipi UUID",
}
en = {
"token": "Token",
"build_living_space_uu_id": "Build Living Space UUID",
"occupant_type_uu_id": "Occupant Type UUID",
}
class DecisionBookDecisionBookInvitationsAssign(
BaseModelRegular, DecisionBookDecisionBookInvitationsAssignValidation
):
token: str token: str
build_living_space_uu_id: str build_living_space_uu_id: str
occupant_type_uu_id: str occupant_type_uu_id: str
class DecisionBookDecisionBookInvitationsUpdateValidation: class DecisionBookDecisionBookInvitationsUpdate(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"token": "Token",
"occupant_type_uu_id": "Sakin Tipi UUID",
}
en = {
**PydanticBaseModelValidation.en,
"token": "Token",
"occupant_type_uu_id": "Occupant Type UUID",
}
class DecisionBookDecisionBookInvitationsUpdate(
PydanticBaseModel, DecisionBookDecisionBookInvitationsUpdateValidation
):
token: str token: str
occupant_type_uu_id: Optional[str] = None occupant_type_uu_id: Optional[str] = None
class ListDecisionBookValidation: class ListDecisionBook(ListOptions):
tr = {
"build_decision_book_uu_id": "Karar Defteri UUID",
}
en = {
"build_decision_book_uu_id": "Decision Book UUID",
}
class ListDecisionBook(ListOptions, ListDecisionBookValidation):
build_decision_book_uu_id: Optional[str] = None build_decision_book_uu_id: Optional[str] = None
class InsertDecisionBookValidation: class InsertDecisionBook(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"build_uu_id": "Yapı UUID",
"decision_type": "Karar Tipi",
"meeting_date": "Toplantı Tarihi",
"is_out_sourced": "Dış Kaynak mı?",
"resp_company_fix_wage": "Firma Sabit Ücreti",
"resp_company_uu_id": "Firma UUID",
}
en = {
**PydanticBaseModelValidation.en,
"build_uu_id": "Build UUID",
"decision_type": "Decision Type",
"meeting_date": "Meeting Date",
"is_out_sourced": "Is Out Sourced?",
"resp_company_fix_wage": "Company Fixed Wage",
"resp_company_uu_id": "Company UUID",
}
class InsertDecisionBook(PydanticBaseModel, InsertDecisionBookValidation):
build_uu_id: str build_uu_id: str
decision_type: str decision_type: str
meeting_date: str meeting_date: str
@ -131,44 +38,12 @@ class InsertDecisionBook(PydanticBaseModel, InsertDecisionBookValidation):
resp_company_uu_id: Optional[str] = None resp_company_uu_id: Optional[str] = None
class InsertDecisionBookCompletedValidation: class InsertDecisionBookCompleted(BaseModelRegular):
tr = {
"build_decision_book_uu_id": "Karar Defteri UUID",
"meeting_completed_date": "Toplantı Tamamlanma Tarihi",
}
en = {
"build_decision_book_uu_id": "Decision Book UUID",
"meeting_completed_date": "Meeting Completed Date",
}
class InsertDecisionBookCompleted(
BaseModelRegular, InsertDecisionBookCompletedValidation
):
build_decision_book_uu_id: str build_decision_book_uu_id: str
meeting_completed_date: str meeting_completed_date: str
class InsertDecisionBookPersonValidation: class InsertDecisionBookPerson(BaseModelRegular):
tr = {
"person_uu_id": "Kişi UUID",
"build_decision_book_uu_id": "Karar Defteri UUID",
"management_typecode_uu_id": "Yönetim Tipi UUID",
"dues_discount_approval_date": "Aidat İndirim Onay Tarihi",
"dues_fix_discount": "Aidat Sabit İndirim",
"dues_percent_discount": "Aidat Yüzde İndirim",
}
en = {
"person_uu_id": "Person UUID",
"build_decision_book_uu_id": "Decision Book UUID",
"management_typecode_uu_id": "Management Type UUID",
"dues_discount_approval_date": "Dues Discount Approval Date",
"dues_fix_discount": "Dues Fix Discount",
"dues_percent_discount": "Dues Percent Discount",
}
class InsertDecisionBookPerson(BaseModelRegular, InsertDecisionBookPersonValidation):
person_uu_id: str person_uu_id: str
build_decision_book_uu_id: str build_decision_book_uu_id: str
management_typecode_uu_id: str management_typecode_uu_id: str
@ -178,67 +53,18 @@ class InsertDecisionBookPerson(BaseModelRegular, InsertDecisionBookPersonValidat
dues_percent_discount: Optional[int] = None dues_percent_discount: Optional[int] = None
class UpdateDecisionBookPersonValidation: class UpdateDecisionBookPerson(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"dues_fix_discount": "Aidat Sabit İndirim",
"dues_percent_discount": "Aidat Yüzde İndirim",
}
en = {
**PydanticBaseModelValidation.en,
"dues_fix_discount": "Dues Fix Discount",
"dues_percent_discount": "Dues Percent Discount",
}
class UpdateDecisionBookPerson(PydanticBaseModel, UpdateDecisionBookPersonValidation):
dues_fix_discount: Optional[float] = None dues_fix_discount: Optional[float] = None
dues_percent_discount: Optional[int] = None dues_percent_discount: Optional[int] = None
class RemoveDecisionBookPersonValidation: class RemoveDecisionBookPerson(PydanticBaseModel):
tr = {
"person_uu_id": "Kişi UUID",
"build_decision_book_person_uu_id": "Karar Defteri Kişi UUID",
}
en = {
"person_uu_id": "Person UUID",
"build_decision_book_person_uu_id": "Decision Book Person UUID",
}
class RemoveDecisionBookPerson(PydanticBaseModel, RemoveDecisionBookPersonValidation):
person_uu_id: str person_uu_id: str
build_decision_book_person_uu_id: str build_decision_book_person_uu_id: str
class UpdateDecisionBookValidation: class UpdateDecisionBook(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"decision_book_pdf_path": "Karar Defteri PDF Yolu",
"is_out_sourced": "Dış Kaynak mı?",
"contact_agreement_path": "İletişim Anlaşma Yolu",
"contact_agreement_date": "İletişim Anlaşma Tarihi",
"meeting_date": "Toplantı Tarihi",
"decision_type": "Karar Tipi",
"resp_company_fix_wage": "Firma Sabit Ücreti",
"resp_company_uu_id": "Firma UUID",
}
en = {
**PydanticBaseModelValidation.en,
"decision_book_pdf_path": "Decision Book PDF Path",
"is_out_sourced": "Is Out Sourced?",
"contact_agreement_path": "Contact Agreement Path",
"contact_agreement_date": "Contact Agreement Date",
"meeting_date": "Meeting Date",
"decision_type": "Decision Type",
"resp_company_fix_wage": "Company Fixed Wage",
"resp_company_uu_id": "Company UUID",
}
class UpdateDecisionBook(PydanticBaseModel, UpdateDecisionBookValidation):
decision_book_pdf_path: Optional[str] = None decision_book_pdf_path: Optional[str] = None
is_out_sourced: Optional[bool] = None is_out_sourced: Optional[bool] = None
contact_agreement_path: Optional[str] = None contact_agreement_path: Optional[str] = None
@ -250,34 +76,7 @@ class UpdateDecisionBook(PydanticBaseModel, UpdateDecisionBookValidation):
resp_company_uu_id: Optional[str] = None resp_company_uu_id: Optional[str] = None
class InsertBuildDecisionBookItemsValidation: class InsertBuildDecisionBookItems(BaseModelRegular):
tr = {
"token": "Token",
"info_type_uu_id": "Bilgi Tipi UUID",
"item_comment": "Öğe Yorumu / Açıklama",
"currency": "Para Birimi",
"unit_type": "Birim Tipi",
"debit_start_date": "Borç Başlangıç Tarihi",
"debit_end_date": "Borç Bitiş Tarihi",
"unit_price_is_fixed": "Birim Fiyat Sabit mi?",
"unit_price": "Birim Fiyat",
}
en = {
"token": "Token",
"info_type_uu_id": "Info Type UUID",
"item_comment": "Item Comment",
"currency": "Currency",
"unit_type": "Unit Type",
"debit_start_date": "Debit Start Date",
"debit_end_date": "Debit End Date",
"unit_price_is_fixed": "Unit Price Is Fixed?",
"unit_price": "Unit Price",
}
class InsertBuildDecisionBookItems(
BaseModelRegular, InsertBuildDecisionBookItemsValidation
):
token: str token: str
info_type_uu_id: str info_type_uu_id: str
item_comment: str item_comment: str
@ -293,64 +92,19 @@ class InsertBuildDecisionBookItems(
# item_objection: Optional[str] = None # item_objection: Optional[str] = None
class UpdateBuildDecisionBookItemsValidation: class UpdateBuildDecisionBookItems(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"item_comment": "Öğe Yorumu / Açıklama",
"item_objection": "Öğe İtirazı",
}
en = {
**PydanticBaseModelValidation.en,
"item_comment": "Item Comment",
"item_objection": "Item Objection",
}
class UpdateBuildDecisionBookItems(
PydanticBaseModel, UpdateBuildDecisionBookItemsValidation
):
item_comment: Optional[str] = None item_comment: Optional[str] = None
item_objection: Optional[str] = None item_objection: Optional[str] = None
class InsertBuildDecisionBookItemDebitsValidation: class InsertBuildDecisionBookItemDebits(BaseModelRegular):
tr = {
"build_decision_book_item_uu_id": "Karar Defteri Öğe UUID",
"dues_values": "Aidat Değerleri",
}
en = {
"build_decision_book_item_uu_id": "Decision Book Item UUID",
"dues_values": "Dues Values",
}
class InsertBuildDecisionBookItemDebits(
BaseModelRegular, InsertBuildDecisionBookItemDebitsValidation
):
build_decision_book_item_uu_id: str build_decision_book_item_uu_id: str
dues_values: dict dues_values: dict
# dues_types_uu_id: str # dues_types_uu_id: str
# decision_taken: Optional[bool] = None # decision_taken: Optional[bool] = None
class UpdateBuildDecisionBookItemDebitsValidation: class UpdateBuildDecisionBookItemDebits(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"dues_types_uu_id": "Aidat Tipi UUID",
"dues_values": "Aidat Değerleri",
"decision_taken": "Karar Alındı mı?",
}
en = {
**PydanticBaseModelValidation.en,
"dues_types_uu_id": "Dues Type UUID",
"dues_values": "Dues Values",
"decision_taken": "Decision Taken?",
}
class UpdateBuildDecisionBookItemDebits(
PydanticBaseModel, UpdateBuildDecisionBookItemDebitsValidation
):
dues_types_uu_id: Optional[str] = None dues_types_uu_id: Optional[str] = None
dues_values: Optional[dict] = None dues_values: Optional[dict] = None
decision_taken: Optional[bool] = None decision_taken: Optional[bool] = None

View File

@ -1,28 +1,10 @@
from typing import Optional from typing import Optional
from api_validations.validations_request import ( from ApiValidations.Request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
) )
class DepartmentsPydanticValidation: class DepartmentsPydantic(PydanticBaseModel):
tr = {
"department_code": "Department Kodu",
"department_name": "Departman Adı",
"department_description": "Departman Açıklaması",
"company_uu_id": "Şirket UUID",
"parent_department_uu_id": "Üst Departman UUID",
}
en = {
"department_code": "Department Code",
"department_name": "Department Name",
"department_description": "Department Description",
"company_uu_id": "Company UUID",
"parent_department_uu_id": "Parent Department UUID",
}
class DepartmentsPydantic(PydanticBaseModel, PydanticBaseModelValidation):
department_code: Optional[str] department_code: Optional[str]
department_name: Optional[str] department_name: Optional[str]

View File

@ -1,176 +1,51 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
)
class BindEmployees2PeopleValidation: class BindEmployees2People(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"staff_uu_id": "Kadro UUID",
"people_uu_id": "Kişi UUID",
"expiry_starts": "Başlangıç Tarihi",
}
en = {
**PydanticBaseModelValidation.en,
"staff_uu_id": "Staff UUID",
"people_uu_id": "People UUID",
"expiry_starts": "Start Date",
}
class BindEmployees2People(PydanticBaseModel, BindEmployees2PeopleValidation):
staff_uu_id: str staff_uu_id: str
people_uu_id: str people_uu_id: str
expiry_starts: Optional[str] = None expiry_starts: Optional[str] = None
class UnBindEmployees2PeopleValidation: class UnBindEmployees2People(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
"people_uu_id": "Kişi UUID",
"expiry_ends": "Bitiş Tarihi",
}
en = {
**PydanticBaseModelValidation.en,
"people_uu_id": "People UUID",
"expiry_ends": "End Date",
}
class UnBindEmployees2People(PydanticBaseModel, UnBindEmployees2PeopleValidation):
people_uu_id: str people_uu_id: str
expiry_ends: str expiry_ends: str
class InsertEmployeesValidation: class InsertEmployees(BaseModelRegular):
tr = {
"staff_uu_id": "Kadro UUID",
"people_uu_id": "Kişi UUID",
}
en = {
"staff_uu_id": "Staff UUID",
"people_uu_id": "People UUID",
}
class InsertEmployees(BaseModelRegular, InsertEmployeesValidation):
staff_uu_id: str staff_uu_id: str
people_uu_id: Optional[str] = None people_uu_id: Optional[str] = None
class InsertCompanyDutyValidation: class InsertCompanyDuty(BaseModelRegular):
tr = {
"duty_code": "Görev Kodu",
"duty_name": "Görev Adı",
"duty_description": "Görev Açıklaması",
}
en = {
"duty_code": "Duty Code",
"duty_name": "Duty Name",
"duty_description": "Duty Description",
}
class InsertCompanyDuty(BaseModelRegular, InsertCompanyDutyValidation):
duty_code: str duty_code: str
duty_name: str duty_name: str
duty_description: Optional[str] = None duty_description: Optional[str] = None
class SelectDutiesValidation: class SelectDuties(BaseModelRegular):
tr = {
"duty_uu_id": "Görev UUID",
}
en = {
"duty_uu_id": "Duty UUID",
}
class SelectDuties(BaseModelRegular, SelectDutiesValidation):
duty_uu_id: Optional[str] = None duty_uu_id: Optional[str] = None
class InsertDutiesValidation: class InsertDuties(BaseModelRegular):
tr = {
"duties_uu_id": "Görev UUID",
"department_uu_id": "Departman UUID",
"is_default_duty": "Varsayılan Görev",
}
en = {
"duties_uu_id": "Duty UUID",
"department_uu_id": "Department UUID",
"is_default_duty": "Default Duty",
}
class InsertDuties(BaseModelRegular, InsertDutiesValidation):
duties_uu_id: str duties_uu_id: str
department_uu_id: str department_uu_id: str
is_default_duty: Optional[bool] = False is_default_duty: Optional[bool] = False
class UpdateDutiesValidation:
tr = {
**PydanticBaseModelValidation.tr,
"duties_uu_id": "Görev UUID",
"department_uu_id": "Departman UUID",
"is_default_duty": "Varsayılan Görev",
}
en = {
**PydanticBaseModelValidation.en,
"duties_uu_id": "Duty UUID",
"department_uu_id": "Department UUID",
"is_default_duty": "Default Duty",
}
class UpdateDuties(PydanticBaseModel): class UpdateDuties(PydanticBaseModel):
duties_uu_id: Optional[str] = None duties_uu_id: Optional[str] = None
department_uu_id: Optional[str] = None department_uu_id: Optional[str] = None
is_default_duty: Optional[bool] = None is_default_duty: Optional[bool] = None
class UpdateCompanyDutyValidation:
tr = {
**PydanticBaseModelValidation.tr,
"duty_code": "Görev Kodu",
"duty_name": "Görev Adı",
"duty_description": "Görev Açıklaması",
}
en = {
**PydanticBaseModelValidation.en,
"duty_code": "Duty Code",
"duty_name": "Duty Name",
"duty_description": "Duty Description",
}
class UpdateCompanyDuty(PydanticBaseModel): class UpdateCompanyDuty(PydanticBaseModel):
duty_code: Optional[str] = None duty_code: Optional[str] = None
duty_name: Optional[str] = None duty_name: Optional[str] = None
duty_description: Optional[str] = None duty_description: Optional[str] = None
class InsertCompanyEmployeesSalariesValidation:
tr = {
"gross_salary": "Brüt Maaş",
"net_salary": "Net Maaş",
"start_date": "Başlangıç Tarihi",
"stop_date": "Bitiş Tarihi",
"people_id": "Kişi ID",
}
en = {
"gross_salary": "Gross Salary",
"net_salary": "Net Salary",
"start_date": "Start Date",
"stop_date": "Stop Date",
"people_id": "People ID",
}
class InsertCompanyEmployeesSalaries(BaseModelRegular): class InsertCompanyEmployeesSalaries(BaseModelRegular):
gross_salary: float gross_salary: float
net_salary: float net_salary: float
@ -179,25 +54,6 @@ class InsertCompanyEmployeesSalaries(BaseModelRegular):
people_id: int people_id: int
class UpdateCompanyEmployeesSalariesValidation:
tr = {
**PydanticBaseModelValidation.tr,
"gross_salary": "Brüt Maaş",
"net_salary": "Net Maaş",
"start_date": "Başlangıç Tarihi",
"stop_date": "Bitiş Tarihi",
"people_id": "Kişi ID",
}
en = {
**PydanticBaseModelValidation.en,
"gross_salary": "Gross Salary",
"net_salary": "Net Salary",
"start_date": "Start Date",
"stop_date": "Stop Date",
"people_id": "People ID",
}
class UpdateCompanyEmployeesSalaries(PydanticBaseModel): class UpdateCompanyEmployeesSalaries(PydanticBaseModel):
gross_salary: Optional[float] = None gross_salary: Optional[float] = None
net_salary: Optional[float] = None net_salary: Optional[float] = None
@ -206,24 +62,8 @@ class UpdateCompanyEmployeesSalaries(PydanticBaseModel):
people_id: Optional[int] = None people_id: Optional[int] = None
class InsertCompanyEmployeesValidation:
tr = {
"employee_description": "Çalışan Açıklaması",
"person_uu_id": "Kişi UUID",
"duty_uu_id": "Görev UUID",
"start_date": "Başlangıç Tarihi",
"stop_date": "Bitiş Tarihi",
}
en = {
"employee_description": "Employee Description",
"person_uu_id": "Person UUID",
"duty_uu_id": "Duty UUID",
"start_date": "Start Date",
"stop_date": "Stop Date",
}
class InsertCompanyEmployees(BaseModelRegular):
class InsertCompanyEmployees(BaseModelRegular, InsertCompanyEmployeesValidation):
employee_description: Optional[str] = None employee_description: Optional[str] = None
person_uu_id: str person_uu_id: str
@ -233,19 +73,7 @@ class InsertCompanyEmployees(BaseModelRegular, InsertCompanyEmployeesValidation)
stop_date: Optional[str] = None stop_date: Optional[str] = None
class UpdateCompanyEmployeesValidation:
tr = {
**PydanticBaseModelValidation.tr,
"stop_date": "Bitiş Tarihi",
"employee_description": "Çalışan Açıklaması",
}
en = {
**PydanticBaseModelValidation.en,
"stop_date": "Stop Date",
"employee_description": "Employee Description",
}
class UpdateCompanyEmployees(PydanticBaseModel):
class UpdateCompanyEmployees(PydanticBaseModel, UpdateCompanyEmployeesValidation):
stop_date: Optional[str] = None stop_date: Optional[str] = None
employee_description: Optional[str] = None employee_description: Optional[str] = None

View File

@ -1,5 +1,5 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
class RegisterEvents2EmployeeValidation: class RegisterEvents2EmployeeValidation:

View File

@ -1,4 +1,4 @@
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
class RegisterModules2OccupantValidation: class RegisterModules2OccupantValidation:

View File

@ -1,29 +1,8 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
)
class InsertPersonValidation: class InsertPerson(BaseModelRegular):
tr = {
"firstname": "İsim",
"surname": "Soyisim",
"sex_code": "Cinsiyet",
"national_identity_id": "T.C. Kimlik Numarası",
"middle_name": "Orta İsim",
"father_name": "Baba Adı",
"mother_name": "Anne Adı",
"country_code": "Ülke Kodu",
"birth_place": "Doğum Yeri",
"birth_date": "Doğum Tarihi",
"tax_no": "Vergi Numarası",
"ref_id": "Referans ID",
}
class InsertPerson(BaseModelRegular, InsertPersonValidation):
firstname: str firstname: str
surname: str surname: str
sex_code: str sex_code: str
@ -38,18 +17,7 @@ class InsertPerson(BaseModelRegular, InsertPersonValidation):
ref_id: Optional[str] = None ref_id: Optional[str] = None
class UpdatePersonValidation: class UpdatePerson(PydanticBaseModel):
tr = {
**PydanticBaseModelValidation.tr,
**InsertPersonValidation.tr,
}
en = {
**PydanticBaseModelValidation.en,
**InsertPersonValidation.tr,
}
class UpdatePerson(PydanticBaseModel, UpdatePersonValidation):
firstname: Optional[str] = None firstname: Optional[str] = None
surname: Optional[str] = None surname: Optional[str] = None
middle_name: Optional[str] middle_name: Optional[str]

View File

@ -1,31 +1,8 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
)
class InsertBuildDecisionBookProjectItemsValidation: class InsertBuildDecisionBookProjectItems(BaseModelRegular):
tr = {
"build_decision_book_project_uu_id": "Proje UUID",
"item_header": "Başlık",
"item_comment": "ıklama",
"attachment_pdf_path": "Ek Dosya Yolu",
"item_objection": "İtiraz",
}
en = {
"build_decision_book_project_uu_id": "Project UUID",
"item_header": "Header",
"item_comment": "Comment",
"attachment_pdf_path": "Attachment PDF Path",
"item_objection": "Objection",
}
class InsertBuildDecisionBookProjectItems(
BaseModelRegular, InsertBuildDecisionBookProjectItemsValidation
):
build_decision_book_project_uu_id: str build_decision_book_project_uu_id: str
item_header: str item_header: str
item_comment: str item_comment: str
@ -33,17 +10,6 @@ class InsertBuildDecisionBookProjectItems(
item_objection: Optional[str] = None item_objection: Optional[str] = None
class UpdateBuildDecisionBookProjectItemsValidation:
tr = {
**InsertBuildDecisionBookProjectItemsValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectItemsValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuildDecisionBookProjectItems(PydanticBaseModel): class UpdateBuildDecisionBookProjectItems(PydanticBaseModel):
item_header: Optional[str] = None item_header: Optional[str] = None
item_comment: Optional[str] = None item_comment: Optional[str] = None
@ -52,30 +18,7 @@ class UpdateBuildDecisionBookProjectItems(PydanticBaseModel):
build_decision_book_project_uu_id: Optional[str] = None build_decision_book_project_uu_id: Optional[str] = None
class InsertBuildDecisionBookProjectPersonValidation: class InsertBuildDecisionBookProjectPerson(BaseModelRegular):
tr = {
"dues_percent_discount": "İskonto Oranı",
"job_fix_wage": "Sabit Ücret",
"bid_price": "Teklif Fiyatı",
"decision_price": "Karar Fiyatı",
"build_decision_book_project_uu_id": "Proje UUID",
"living_space_uu_id": "Yaşam Alanı UUID",
"project_team_type_uu_id": "Proje Takım Tipi UUID",
}
en = {
"dues_percent_discount": "Discount Rate",
"job_fix_wage": "Fixed Wage",
"bid_price": "Bid Price",
"decision_price": "Decision Price",
"build_decision_book_project_uu_id": "Project UUID",
"living_space_uu_id": "Living Space UUID",
"project_team_type_uu_id": "Project Team Type UUID",
}
class InsertBuildDecisionBookProjectPerson(
BaseModelRegular, InsertBuildDecisionBookProjectPersonValidation
):
dues_percent_discount: Optional[int] = None dues_percent_discount: Optional[int] = None
job_fix_wage: Optional[float] = None job_fix_wage: Optional[float] = None
bid_price: Optional[float] = None bid_price: Optional[float] = None
@ -85,20 +28,7 @@ class InsertBuildDecisionBookProjectPerson(
project_team_type_uu_id: str project_team_type_uu_id: str
class UpdateBuildDecisionBookProjectPersonValidation: class UpdateBuildDecisionBookProjectPerson(PydanticBaseModel):
tr = {
**InsertBuildDecisionBookProjectPersonValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectPersonValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuildDecisionBookProjectPerson(
PydanticBaseModel, UpdateBuildDecisionBookProjectPersonValidation
):
dues_percent_discount: Optional[int] = None dues_percent_discount: Optional[int] = None
job_fix_wage: Optional[float] = None job_fix_wage: Optional[float] = None
bid_price: Optional[float] = None bid_price: Optional[float] = None
@ -108,47 +38,8 @@ class UpdateBuildDecisionBookProjectPerson(
project_team_type_uu_id: Optional[str] = None project_team_type_uu_id: Optional[str] = None
class InsertBuildDecisionBookProjectsValidation:
tr = {
"build_decision_book_item_uu_id": "Karar Defteri UUID",
"project_responsible_person_uu_id": "Proje Sorumlu Kişi UUID",
"project_name": "Proje Adı",
"project_start_date": "Proje Başlangıç Tarihi",
"project_stop_date": "Proje Bitiş Tarihi",
"project_type": "Proje Tipi",
"is_out_sourced": "Dış Kaynak Kullanımı",
"project_note": "Proje Notu",
"decision_book_pdf_path": "Karar Defteri PDF Yolu",
"resp_company_fix_wage": "Firma Sabit Ücreti",
"contact_agreement_path": "İletişim Anlaşması Yolu",
"contact_agreement_date": "İletişim Anlaşması Tarihi",
"meeting_date": "Toplantı Tarihi",
"currency": "Para Birimi",
"bid_price": "Teklif Fiyatı",
"resp_company_uu_id": "Firma UUID",
}
en = {
"build_decision_book_item_uu_id": "Decision Book UUID",
"project_responsible_person_uu_id": "Project Responsible Person UUID",
"project_name": "Project Name",
"project_start_date": "Project Start Date",
"project_stop_date": "Project Stop Date",
"project_type": "Project Type",
"is_out_sourced": "Out Sourced",
"project_note": "Project Note",
"decision_book_pdf_path": "Decision Book PDF Path",
"resp_company_fix_wage": "Company Fixed Wage",
"contact_agreement_path": "Contact Agreement Path",
"contact_agreement_date": "Contact Agreement Date",
"meeting_date": "Meeting Date",
"currency": "Currency",
"bid_price": "Bid Price",
"resp_company_uu_id": "Company UUID",
}
class InsertBuildDecisionBookProjects( class InsertBuildDecisionBookProjects(
BaseModelRegular, InsertBuildDecisionBookProjectsValidation BaseModelRegular
): ):
build_decision_book_item_uu_id: str build_decision_book_item_uu_id: str
project_responsible_person_uu_id: str project_responsible_person_uu_id: str
@ -169,19 +60,8 @@ class InsertBuildDecisionBookProjects(
resp_company_uu_id: Optional[str] = None resp_company_uu_id: Optional[str] = None
class UpdateBuildDecisionBookProjectsValidation:
tr = {
**InsertBuildDecisionBookProjectsValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectsValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuildDecisionBookProjects( class UpdateBuildDecisionBookProjects(
PydanticBaseModel, UpdateBuildDecisionBookProjectsValidation PydanticBaseModel
): ):
build_decision_book_project_uu_id: str build_decision_book_project_uu_id: str
is_out_sourced: Optional[bool] = False is_out_sourced: Optional[bool] = False
@ -196,23 +76,9 @@ class UpdateBuildDecisionBookProjects(
approved_price: Optional[float] = None approved_price: Optional[float] = None
class ApprovalsBuildDecisionBookProjectsValidation:
tr = {
"build_decision_book_project_uu_id": "Karar Defteri Proje UUID",
"project_stop_date": "Proje Bitiş Tarihi",
"status_code": "Durum Kodu",
"final_price_list": "Son Fiyat Listesi",
}
en = {
"build_decision_book_project_uu_id": "Decision Book Project UUID",
"project_stop_date": "Project Stop Date",
"status_code": "Status Code",
"final_price_list": "Final Price List",
}
class ApprovalsBuildDecisionBookProjects( class ApprovalsBuildDecisionBookProjects(
PydanticBaseModel, ApprovalsBuildDecisionBookProjectsValidation PydanticBaseModel
): ):
build_decision_book_project_uu_id: str build_decision_book_project_uu_id: str
project_stop_date: str project_stop_date: str
@ -222,29 +88,8 @@ class ApprovalsBuildDecisionBookProjects(
) )
class InsertBuildDecisionBookProjectItemDebitsValidation:
tr = {
"build_decision_book_project_item_uu_id": "Karar Defteri Proje Öğe UUID",
"payment_date": "Ödeme Tarihi",
"dues_values": "Borç Değerleri",
"is_official": "Resmi Mi?",
"discount_value": "İskonto Oranı",
"discount_fix": "İskonto Sabit",
"decision_taken": "Karar Alındı Mı?",
}
en = {
"build_decision_book_project_item_uu_id": "Decision Book Project Item UUID",
"payment_date": "Payment Date",
"dues_values": "Dues Values",
"is_official": "Is Official?",
"discount_value": "Discount Rate",
"discount_fix": "Discount Fix",
"decision_taken": "Decision Taken?",
}
class InsertBuildDecisionBookProjectItemDebits( class InsertBuildDecisionBookProjectItemDebits(
PydanticBaseModel, InsertBuildDecisionBookProjectItemDebitsValidation PydanticBaseModel
): ):
build_decision_book_project_item_uu_id: str build_decision_book_project_item_uu_id: str
payment_date: str payment_date: str
@ -255,19 +100,8 @@ class InsertBuildDecisionBookProjectItemDebits(
decision_taken: Optional[bool] = None decision_taken: Optional[bool] = None
class UpdateBuildDecisionBookProjectItemDebitsValidation:
tr = {
**InsertBuildDecisionBookProjectItemDebitsValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectItemDebitsValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuildDecisionBookProjectItemDebits( class UpdateBuildDecisionBookProjectItemDebits(
PydanticBaseModel, UpdateBuildDecisionBookProjectItemDebitsValidation PydanticBaseModel
): ):
dues_values: Optional[str] = None dues_values: Optional[str] = None
discount_value: Optional[float] = None discount_value: Optional[float] = None

View File

@ -1,8 +1,6 @@
from typing import Optional, List from typing import Optional, List
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
from api_validations.validations_request import ( from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
PydanticBaseModel,
)
class CheckEndpointAccess(BaseModelRegular): class CheckEndpointAccess(BaseModelRegular):

View File

@ -1,4 +1,4 @@
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular
class RegisterServices2OccupantValidation: class RegisterServices2OccupantValidation:

View File

@ -1,8 +1,5 @@
from typing import Optional from typing import Optional
from api_validations.core_validations import BaseModelRegular from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
from api_validations.validations_request import (
PydanticBaseModel,
)
class InsertStaffValidation: class InsertStaffValidation:

View File

@ -1,7 +1,5 @@
from typing import Optional from typing import Optional
from api_validations.validations_request import ( from ApiValidations.Request import PydanticBaseModel
PydanticBaseModel,
)
class InsertUsersValidation: class InsertUsersValidation:

View File

@ -0,0 +1,3 @@
from .account_responses import AccountRecordResponse
__all__ = ["AccountRecordResponse"]

View File

@ -0,0 +1,259 @@
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
from decimal import Decimal
from uuid import UUID
from pydantic import BaseModel
class AccountBooksResponse(BaseModel):
"""Response model for account books"""
country: str
branch_type: int
company_id: int
company_uu_id: str
branch_id: Optional[int]
branch_uu_id: Optional[str]
class AccountCodesResponse(BaseModel):
"""Response model for account codes"""
account_code: str
comment_line: str
is_receive_or_debit: bool
product_id: int = 0
nvi_id: str = ""
status_id: int = 0
account_code_seperator: str = "."
system_id: int = 0
locked: bool = False
company_id: Optional[int]
company_uu_id: str
customer_id: Optional[int]
customer_uu_id: str
person_id: Optional[int]
person_uu_id: str
class AccountCodeParserResponse(BaseModel):
"""Response model for account code parser"""
account_code_1: str
account_code_2: str
account_code_3: str
account_code_4: str = ""
account_code_5: str = ""
account_code_6: str = ""
account_code_id: int
account_code_uu_id: str
class AccountMasterResponse(BaseModel):
"""Response model for account master"""
doc_date: datetime
plug_type: str
plug_number: int
special_code: str = ""
authorization_code: str = ""
doc_code: str = ""
doc_type: int = 0
comment_line1: str = ""
comment_line2: str = ""
comment_line3: str = ""
comment_line4: str = ""
comment_line5: str = ""
comment_line6: str = ""
project_code: str = ""
module_no: str = ""
journal_no: int = 0
status_id: int = 0
canceled: bool = False
print_count: int = 0
total_active: Decimal = Decimal("0")
total_passive: Decimal = Decimal("0")
total_active_1: Decimal = Decimal("0")
total_passive_1: Decimal = Decimal("0")
total_active_2: Decimal = Decimal("0")
total_passive_2: Decimal = Decimal("0")
total_active_3: Decimal = Decimal("0")
total_passive_3: Decimal = Decimal("0")
total_active_4: Decimal = Decimal("0")
total_passive_4: Decimal = Decimal("0")
cross_ref: int = 0
data_center_id: str = ""
data_center_rec_num: int = 0
account_header_id: int
account_header_uu_id: str
project_item_id: Optional[int]
project_item_uu_id: Optional[str]
department_id: Optional[int]
department_uu_id: Optional[str]
class AccountDetailResponse(BaseModel):
"""Response model for account detail"""
doc_date: datetime
line_no: int
receive_debit: str
debit: Decimal
department: str = ""
special_code: str = ""
account_ref: int = 0
account_fiche_ref: int = 0
center_ref: int = 0
general_code: str = ""
credit: Decimal = Decimal("0")
currency_type: str = "TL"
exchange_rate: Decimal = Decimal("0")
debit_cur: Decimal = Decimal("0")
credit_cur: Decimal = Decimal("0")
discount_cur: Decimal = Decimal("0")
amount: Decimal = Decimal("0")
cross_account_code: str = ""
inf_index: Decimal = Decimal("0")
not_inflated: int = 0
not_calculated: int = 0
comment_line1: str = ""
comment_line2: str = ""
comment_line3: str = ""
comment_line4: str = ""
comment_line5: str = ""
comment_line6: str = ""
owner_acc_ref: int = 0
from_where: int = 0
orj_eid: int = 0
canceled: int = 0
cross_ref: int = 0
data_center_id: str = ""
data_center_rec_num: str = "0"
status_id: int = 0
plug_type_id: Optional[int]
plug_type_uu_id: str
account_header_id: int
account_header_uu_id: str
account_code_id: int
account_code_uu_id: str
account_master_id: int
account_master_uu_id: str
project_id: Optional[int]
project_uu_id: Optional[str]
class AccountRecordResponse(BaseModel):
"""Response model for account financial records.
This model represents a financial transaction record in the system,
including bank transaction details, amounts, and related metadata.
Attributes:
iban (str): International Bank Account Number
bank_date (datetime): Date when the transaction occurred at the bank
currency_value (Decimal): Original transaction amount
bank_balance (Decimal): Account balance after the transaction
currency (str): Currency code (e.g., "TRY", "USD")
additional_balance (Decimal): Any additional balance adjustments
channel_branch (str): Bank branch or channel where transaction occurred
process_name (str): Name/type of the transaction
process_type (str): Classification of the transaction
process_comment (str): Additional transaction details or notes
bank_reference_code (str): Bank's reference code for the transaction
add_comment_note (Optional[str]): Additional internal notes
is_receipt_mail_send (Optional[bool]): Whether receipt was emailed
found_from (Optional[str]): Source of the transaction record
similarity (Optional[float]): Matching confidence for duplicate detection
remainder_balance (Optional[Decimal]): Remaining balance if partial
bank_date_y (Optional[int]): Year of bank transaction
bank_date_m (Optional[int]): Month of bank transaction
bank_date_w (Optional[int]): Week of bank transaction
bank_date_d (Optional[int]): Day of bank transaction
approving_accounting_record (Optional[bool]): Accounting approval status
accounting_receipt_date (Optional[datetime]): When receipt was processed
accounting_receipt_number (Optional[int]): Receipt reference number
approved_record (Optional[bool]): Whether record is approved
import_file_name (Optional[str]): Source file if imported
receive_debit_uu_id (Optional[str]): Related debit record ID
budget_type_uu_id (Optional[str]): Associated budget type ID
company_uu_id (Optional[str]): Associated company ID
send_company_uu_id (Optional[str]): Sending company ID
customer_id (Optional[str]): Associated customer ID
customer_uu_id (Optional[str]): Associated customer UUID
send_person_uu_id (Optional[str]): Sending person ID
approving_accounting_person_uu_id (Optional[str]): Approver ID
build_parts_uu_id (Optional[str]): Related building part ID
build_decision_book_uu_id (Optional[str]): Related decision book ID
"""
iban: str
bank_date: datetime
currency_value: Decimal
bank_balance: Decimal
currency: str = "TRY"
additional_balance: Decimal = Decimal("0")
channel_branch: str
process_name: str
process_type: str
process_comment: str
bank_reference_code: str
add_comment_note: Optional[str]
is_receipt_mail_send: Optional[bool] = False
found_from: Optional[str]
similarity: Optional[float]
remainder_balance: Optional[Decimal]
bank_date_y: Optional[int]
bank_date_m: Optional[int]
bank_date_w: Optional[int]
bank_date_d: Optional[int]
approving_accounting_record: Optional[bool]
accounting_receipt_date: Optional[datetime]
accounting_receipt_number: Optional[int]
approved_record: Optional[bool]
import_file_name: Optional[str]
receive_debit_uu_id: Optional[str]
budget_type_uu_id: Optional[str]
company_uu_id: Optional[str]
send_company_uu_id: Optional[str]
customer_id: Optional[str]
customer_uu_id: Optional[str]
send_person_uu_id: Optional[str]
approving_accounting_person_uu_id: Optional[str]
build_parts_uu_id: Optional[str]
build_decision_book_uu_id: Optional[str]
class AccountRecordExchangeResponse(BaseModel):
"""Response model for currency exchange records.
This model represents a currency exchange transaction, tracking
exchange rates and converted amounts for financial records.
Attributes:
account_record_id (int): ID of the related account record
account_record_uu_id (str): UUID of the related account record
exchange_rate (Decimal): Applied exchange rate
exchange_currency (str): Target currency code
exchange_value (Decimal): Converted amount
exchange_date (datetime): When the exchange was calculated
"""
account_record_id: int
account_record_uu_id: str
exchange_rate: Decimal
exchange_currency: str = "TRY"
exchange_value: Decimal
exchange_date: datetime
class AccountRecordsListResponse(BaseModel):
"""Response model for account records list endpoint"""
uu_id: UUID
account_name: str
account_code: str
company_id: int
company_uu_id: str
created_at: datetime
updated_at: Optional[datetime]
deleted: bool = False

View File

@ -10,14 +10,53 @@ This module initializes and configures the FastAPI application with:
""" """
import uvicorn import uvicorn
import routers from fastapi import FastAPI
from create_routes import get_all_routers
from create_file import create_app
from prometheus_fastapi_instrumentator import Instrumentator from prometheus_fastapi_instrumentator import Instrumentator
from app_handler import setup_middleware, get_uvicorn_config from app_handler import setup_middleware, get_uvicorn_config
from create_file import setup_security_schema, configure_route_security
from fastapi.openapi.utils import get_openapi
app = create_app(routers=routers) # Initialize FastAPI application def create_app() -> FastAPI:
"""Create and configure the FastAPI application."""
app = FastAPI()
# Get all routers and protected routes from the new configuration
routers, protected_routes = get_all_routers()
# Include all routers
for router in routers:
app.include_router(router)
# Configure OpenAPI schema with security
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="WAG Management API",
version="4.0.0",
description="WAG Management API Service",
routes=app.routes,
)
# Add security scheme
openapi_schema.update(setup_security_schema())
# Configure security for protected routes
for path, methods in protected_routes.items():
for method in methods:
configure_route_security(path, method, openapi_schema, list(protected_routes.keys()))
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
return app
app = create_app() # Initialize FastAPI application
Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
setup_middleware(app) # Configure middleware and exception handlers setup_middleware(app) # Configure middleware and exception handlers

View File

@ -9,15 +9,14 @@ This module provides functionality to create and configure a FastAPI application
- Security requirements for protected endpoints - Security requirements for protected endpoints
""" """
from types import ModuleType from typing import Any, Dict, List, Tuple
from typing import Any, Dict, List, Optional, Union
from fastapi import FastAPI, APIRouter from fastapi import FastAPI, APIRouter
from fastapi.responses import JSONResponse, RedirectResponse from fastapi.responses import JSONResponse, RedirectResponse
from fastapi.openapi.utils import get_openapi from fastapi.openapi.utils import get_openapi
from fastapi.routing import APIRoute
from AllConfigs.main import MainConfig as Config
from middleware.auth_middleware import MiddlewareModule
from AllConfigs.main import MainConfig as Config
from create_routes import get_all_routers
def setup_security_schema() -> Dict[str, Any]: def setup_security_schema() -> Dict[str, Any]:
""" """
@ -27,15 +26,18 @@ def setup_security_schema() -> Dict[str, Any]:
Dict[str, Any]: Security schema configuration Dict[str, Any]: Security schema configuration
""" """
return { return {
"Bearer": { "components": {
"type": "http", "securitySchemes": {
"scheme": "bearer", "Bearer": {
"bearerFormat": "JWT", "type": "http",
"description": "Enter the token", "scheme": "bearer",
"bearerFormat": "JWT",
"description": "Enter the token"
}
}
} }
} }
def configure_route_security( def configure_route_security(
path: str, method: str, schema: Dict[str, Any], protected_paths: List[str] path: str, method: str, schema: Dict[str, Any], protected_paths: List[str]
) -> None: ) -> None:
@ -49,42 +51,13 @@ def configure_route_security(
protected_paths: List of paths that require authentication protected_paths: List of paths that require authentication
""" """
if path in protected_paths: if path in protected_paths:
if "paths" not in schema: if "paths" in schema and path in schema["paths"]:
schema["paths"] = {} if method.lower() in schema["paths"][path]:
schema["paths"][path][method.lower()]["security"] = [{"Bearer": []}]
if path not in schema["paths"]: def create_app() -> FastAPI:
schema["paths"][path] = {}
if method not in schema["paths"][path]:
schema["paths"][path][method] = {}
schema["paths"][path][method]["security"] = [{"Bearer": []}]
def get_routers(routers_module: ModuleType) -> List[APIRouter]:
""" """
Extract all routers from the routers module. Create and configure a FastAPI application with dynamic route creation.
Args:
routers_module: Module containing router definitions
Returns:
List[APIRouter]: List of router instances
"""
routers = []
for attr_name in dir(routers_module):
attr = getattr(routers_module, attr_name)
if isinstance(attr, APIRouter):
routers.append(attr)
return routers
def create_app(routers: ModuleType) -> FastAPI:
"""
Create and configure a FastAPI application.
Args:
routers: Module containing router definitions
Returns: Returns:
FastAPI: Configured FastAPI application instance FastAPI: Configured FastAPI application instance
@ -95,53 +68,39 @@ def create_app(routers: ModuleType) -> FastAPI:
description=Config.DESCRIPTION, description=Config.DESCRIPTION,
default_response_class=JSONResponse, default_response_class=JSONResponse,
) )
# Add home route that redirects to API documentation
@app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION)) @app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION))
async def home() -> RedirectResponse: async def home() -> RedirectResponse:
"""Redirect root path to API documentation.""" """Redirect root path to API documentation."""
return RedirectResponse(url="/docs") return RedirectResponse(url="/docs")
# Get all routers # Get all routers and protected routes using the dynamic route creation
router_instances = get_routers(routers) routers, protected_routes = get_all_routers()
# Find protected paths # Include all routers
protected_paths = [] for router in routers:
for router in router_instances:
for route in router.routes:
if isinstance(route, APIRoute):
# Check if the route has auth_required decorator
if any(d.__name__ == "auth_required" for d in route.dependencies):
protected_paths.append(route.path)
# Include routers
for router in router_instances:
app.include_router(router) app.include_router(router)
# Configure custom OpenAPI schema # Configure OpenAPI schema with security
def custom_openapi(): def custom_openapi():
if app.openapi_schema: if app.openapi_schema:
return app.openapi_schema return app.openapi_schema
openapi_schema = get_openapi( openapi_schema = get_openapi(
title=Config.TITLE, title="WAG Management API",
version="1.0.0", version="4.0.0",
description=Config.DESCRIPTION, description="WAG Management API Service",
routes=app.routes, routes=app.routes,
) )
# Add security schemes # Add security scheme
openapi_schema["components"] = {"securitySchemes": setup_security_schema()} security_schema = setup_security_schema()
openapi_schema.update(security_schema)
# Configure security for each route # Configure security for protected routes
for route in app.routes: for path, methods in protected_routes.items():
if isinstance(route, APIRoute): for method in methods:
configure_route_security( configure_route_security(path, method, openapi_schema, list(protected_routes.keys()))
route.path,
route.methods.pop().lower(),
openapi_schema,
protected_paths,
)
app.openapi_schema = openapi_schema app.openapi_schema = openapi_schema
return app.openapi_schema return app.openapi_schema

View File

@ -0,0 +1,119 @@
"""
Route configuration and factory module.
Handles dynamic route creation based on configurations.
"""
from typing import Optional, Dict, Any, List, Callable, TypeVar, ParamSpec
P = ParamSpec('P') # For function parameters
R = TypeVar('R') # For return type
from dataclasses import dataclass
from functools import wraps
from fastapi import APIRouter, Request
from fastapi.routing import APIRoute
from middleware.auth_middleware import MiddlewareModule
from pydantic import BaseModel
from AllConfigs.main import MainConfig as Config
from ApiEvents.EventServiceApi.route_configs import get_route_configs
@dataclass
class EndpointFactoryConfig:
endpoint: str
method: str
summary: str
description: str
endpoint_function: Callable[P, R] # Now accepts any parameters and return type
response_model: Optional[type] = None
request_model: Optional[type] = None
is_auth_required: bool = True
is_event_required: bool = False
extra_options: Dict[str, Any] = None
def __post_init__(self):
if self.extra_options is None:
self.extra_options = {}
class EnhancedEndpointFactory:
def __init__(self, router_config: dict):
self.router = APIRouter(
prefix=router_config['prefix'],
tags=router_config['tags'],
include_in_schema=router_config.get('include_in_schema', True)
)
self.endpoints = router_config['endpoints']
self.protected_routes: Dict[str, List[str]] = {}
def create_endpoint(self, config: EndpointFactoryConfig):
"""
Create an endpoint directly from the configuration.
Args:
config: EndpointFactoryConfig instance containing endpoint configuration
"""
endpoint_path = config.endpoint
endpoint_function = config.endpoint_function
if config.is_auth_required:
endpoint_function = MiddlewareModule.auth_required(endpoint_function)
# Track protected routes
full_path = f"{self.router.prefix}{endpoint_path}"
if full_path not in self.protected_routes:
self.protected_routes[full_path] = []
self.protected_routes[full_path].append(config.method.lower())
# Register the endpoint with FastAPI router
getattr(self.router, config.method.lower())(
endpoint_path,
response_model=config.response_model,
summary=config.summary,
description=config.description,
**config.extra_options
)(endpoint_function)
def get_router(self) -> APIRouter:
"""Get the configured router."""
return self.router
def get_protected_routes(self) -> Dict[str, List[str]]:
"""Get the protected routes mapping."""
return self.protected_routes
async def health_check(request: Request):
"""Default health check endpoint."""
return {"status": "healthy", "message": "Service is running"}
async def ping_test(request: Request, service_name: str = "base-router"):
"""Default ping test endpoint."""
return {"ping": "pong", "service": service_name}
def get_all_routers() -> tuple[List[APIRouter], Dict[str, List[str]]]:
"""
Get all configured routers and their protected routes.
Returns:
tuple: (routers, protected_routes)
"""
routers = []
all_protected_routes = {}
# Get route configurations from the registry
route_configs = get_route_configs()
for config in route_configs:
factory = EnhancedEndpointFactory(config)
# Create endpoints from configuration
for endpoint_config in config['endpoints']:
factory.create_endpoint(endpoint_config)
# Add router and protected routes
routers.append(factory.get_router())
all_protected_routes.update(factory.get_protected_routes())
return routers, all_protected_routes

View File

@ -113,6 +113,7 @@ class MiddlewareModule:
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr") raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
except Exception as e: except Exception as e:
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr") raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
return wrapper return wrapper

View File

@ -1,3 +0,0 @@
from .base_router import test_route
__all__ = ["test_route"]

View File

@ -1,22 +0,0 @@
"""
Base router configuration and setup.
"""
from fastapi import APIRouter, Request
from middleware.auth_middleware import MiddlewareModule
# Create test router
test_route = APIRouter(prefix="/test", tags=["Test"])
test_route.include_router(test_route, include_in_schema=True)
@test_route.get("/health")
@MiddlewareModule.auth_required
async def health_check(request: Request):
return {"status": "healthy", "message": "Service is running"}
@test_route.get("/ping")
async def ping_test():
return {"ping": "pong", "service": "base-router"}

View File

@ -1,4 +1,4 @@
FROM python:3.9-slim FROM python:3.12-slim
WORKDIR /app WORKDIR /app
@ -19,7 +19,6 @@ RUN poetry config virtualenvs.create false \
&& rm -rf ~/.cache/pypoetry && rm -rf ~/.cache/pypoetry
# Copy application code # Copy application code
COPY DockerApiServices/AllApiNeeds /app/ COPY DockerApiServices/AllApiNeeds /app/
COPY ErrorHandlers /app/ErrorHandlers COPY ErrorHandlers /app/ErrorHandlers
COPY LanguageModels /app/LanguageModels COPY LanguageModels /app/LanguageModels

View File

@ -1,4 +1,4 @@
FROM python:3.9-slim FROM python:3.12-slim
WORKDIR /app WORKDIR /app

View File

@ -1,4 +1,4 @@
FROM python:3.9-slim FROM python:3.12-slim
WORKDIR /app WORKDIR /app

View File

@ -36,6 +36,9 @@ pytest-cov = "^4.1.0"
prometheus-client = "^0.19.0" prometheus-client = "^0.19.0"
prometheus-fastapi-instrumentator = "^6.1.0" prometheus-fastapi-instrumentator = "^6.1.0"
# Cryptography
cryptography = "^43.0.3"
# Utilities # Utilities
python-dateutil = "^2.8.2" python-dateutil = "^2.8.2"
typing-extensions = "^4.8.0" typing-extensions = "^4.8.0"

View File

@ -18,6 +18,7 @@ class HTTPExceptionApiHandler:
@staticmethod @staticmethod
def retrieve_error_status_code(exc: HTTPExceptionApi) -> int: def retrieve_error_status_code(exc: HTTPExceptionApi) -> int:
from ErrorHandlers import DEFAULT_ERROR from ErrorHandlers import DEFAULT_ERROR
error_by_codes = BaseErrorModelClass.retrieve_error_by_codes() error_by_codes = BaseErrorModelClass.retrieve_error_by_codes()
grab_status_code = error_by_codes.get( grab_status_code = error_by_codes.get(
str(exc.error_code).upper(), DEFAULT_ERROR str(exc.error_code).upper(), DEFAULT_ERROR
@ -27,12 +28,15 @@ class HTTPExceptionApiHandler:
@staticmethod @staticmethod
def retrieve_error_message(exc: HTTPExceptionApi, error_languages) -> str: def retrieve_error_message(exc: HTTPExceptionApi, error_languages) -> str:
from ErrorHandlers import DEFAULT_ERROR from ErrorHandlers import DEFAULT_ERROR
return error_languages.get(str(exc.error_code).upper(), DEFAULT_ERROR) return error_languages.get(str(exc.error_code).upper(), DEFAULT_ERROR)
async def handle_exception( async def handle_exception(
self, request: Union[Request, WebSocket], exc: Exception self, request: Union[Request, WebSocket], exc: Exception
) -> Union[Response, Awaitable[None]]: ) -> Union[Response, Awaitable[None]]:
request_string = str(request.url) if isinstance(request, Request) else request.url.path request_string = (
str(request.url) if isinstance(request, Request) else request.url.path
)
if isinstance(exc, HTTPExceptionApi): if isinstance(exc, HTTPExceptionApi):
error_languages = MergedErrorLanguageModels.get_language_models( error_languages = MergedErrorLanguageModels.get_language_models(
language=exc.lang language=exc.lang
@ -45,6 +49,7 @@ class HTTPExceptionApiHandler:
"message": error_message, "message": error_message,
"lang": exc.lang, "lang": exc.lang,
"request": request_string, "request": request_string,
"loc": exc.loc,
}, },
) )
return self.RESPONSE_MODEL( return self.RESPONSE_MODEL(
@ -53,5 +58,6 @@ class HTTPExceptionApiHandler:
"message": "Internal Server Error", "message": "Internal Server Error",
"lang": "def", "lang": "def",
"request": request_string, "request": request_string,
"loc": exc.loc,
}, },
) # Handle other exceptions with a generic 500 error ) # Handle other exceptions with a generic 500 error

View File

@ -1,5 +1,6 @@
class HTTPExceptionApi(Exception): class HTTPExceptionApi(Exception):
def __init__(self, error_code: str, lang: str): def __init__(self, error_code: str, lang: str, loc: str = ""):
self.error_code = error_code self.error_code = error_code
self.lang = lang self.lang = lang
self.loc = loc

View File

@ -4,10 +4,7 @@ from ErrorHandlers.ErrorHandlers.api_exc_handler import (
from ErrorHandlers.Exceptions.api_exc import ( from ErrorHandlers.Exceptions.api_exc import (
HTTPExceptionApi, HTTPExceptionApi,
) )
DEFAULT_ERROR = "UNKNOWN_ERROR" DEFAULT_ERROR = "UNKNOWN_ERROR"
__all__ = [ __all__ = ["HTTPExceptionApiHandler", "HTTPExceptionApi", "DEFAULT_ERROR"]
"HTTPExceptionApiHandler",
"HTTPExceptionApi",
"DEFAULT_ERROR"
]

View File

@ -11,4 +11,3 @@ class BaseError:
NOT_ACCEPTABLE: int = 406 NOT_ACCEPTABLE: int = 406
INVALID_DATA: int = 422 INVALID_DATA: int = 422
UNKNOWN_ERROR: int = 502 UNKNOWN_ERROR: int = 502

View File

@ -16,4 +16,3 @@ class BaseErrorModelClass:
} }
language_model_status.update(clean_dict) language_model_status.update(clean_dict)
return language_model_status return language_model_status

View File

@ -37,7 +37,7 @@ class DecisionBookBudgetBooks(CrudCollection):
Index( Index(
"_decision_book_budget_companies_book_ndx_00", "_decision_book_budget_companies_book_ndx_00",
company_id, company_id,
CrudCollection.created_at, "created_at",
), ),
{"comment": "budget Book Information"}, {"comment": "budget Book Information"},
) )

View File

@ -1,6 +1,4 @@
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from sqlalchemy import ( from sqlalchemy import (
String, String,
Integer, Integer,
@ -13,13 +11,13 @@ from sqlalchemy import (
) )
from sqlalchemy.orm import mapped_column, relationship, Mapped from sqlalchemy.orm import mapped_column, relationship, Mapped
# from databases.extensions import SelectAction from ApiLibrary.extensions.select import SelectAction
from ApiValidations.Custom.token_objects import EmployeeTokenObject
from ApiValidations.Request import ( from ApiValidations.Request import (
InsertCompany, InsertCompany,
UpdateCompany, UpdateCompany,
MatchCompany2Company, MatchCompany2Company,
) )
from api_objects.auth.token_objects import EmployeeTokenObject
from LanguageModels.Database.company.company import ( from LanguageModels.Database.company.company import (
RelationshipDutyCompanyLanguageModel, RelationshipDutyCompanyLanguageModel,
CompaniesLanguageModel, CompaniesLanguageModel,

View File

@ -18,6 +18,7 @@ from sqlalchemy.orm import mapped_column, relationship, Mapped
from ApiLibrary.date_time_actions.date_functions import system_arrow from ApiLibrary.date_time_actions.date_functions import system_arrow
from AllConfigs.Token.config import Auth, ApiStatic from AllConfigs.Token.config import Auth, ApiStatic
from ApiLibrary.extensions.select import SelectAction, SelectActionWithEmployee
from Services.PostgresDb import CrudCollection from Services.PostgresDb import CrudCollection
@ -64,6 +65,10 @@ class UsersTokens(CrudCollection):
# users = relationship("Users", back_populates="tokens", foreign_keys=[user_id]) # users = relationship("Users", back_populates="tokens", foreign_keys=[user_id])
class UserLoginModule:
pass
class Users(CrudCollection, UserLoginModule, SelectAction): class Users(CrudCollection, UserLoginModule, SelectAction):
""" """
Application User frame to connect to API with assigned token-based HTTP connection Application User frame to connect to API with assigned token-based HTTP connection

View File

@ -101,6 +101,3 @@ class ApiEnumDropdown(CrudCollection):
None, None,
) )
) )
ApiEnumDropdown.set_session(ApiEnumDropdown.__session__)

View File

@ -2,6 +2,7 @@ from contextlib import contextmanager
from typing import Any, Dict, Optional, Generator from typing import Any, Dict, Optional, Generator
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy import inspect from sqlalchemy import inspect
from Services.PostgresDb.database import Base from Services.PostgresDb.database import Base
@ -17,7 +18,8 @@ class BaseModel(Base):
__abstract__ = True # Marks this as a base class, won't create a table __abstract__ = True # Marks this as a base class, won't create a table
def get_session(self) -> Session: @classmethod
def new_session(cls) -> Session:
"""Get database session.""" """Get database session."""
from Services.PostgresDb.database import get_db from Services.PostgresDb.database import get_db

View File

@ -438,7 +438,7 @@ class FilterAttributes:
@classmethod @classmethod
def filter_all( def filter_all(
cls: Type[T], db: Session, *args: BinaryExpression, system: bool = False cls: Type[T], *args: Any, db: Session, system: bool = False
) -> PostgresResponse: ) -> PostgresResponse:
""" """
Filter multiple records by expressions. Filter multiple records by expressions.
@ -473,8 +473,8 @@ class FilterAttributes:
@classmethod @classmethod
def filter_one( def filter_one(
cls: Type[T], cls: Type[T],
*args: Any,
db: Session, db: Session,
*args: BinaryExpression,
system: bool = False, system: bool = False,
expired: bool = False, expired: bool = False,
) -> PostgresResponse: ) -> PostgresResponse:

View File

@ -110,13 +110,13 @@ class CrudMixin(
# Common timestamp fields for all models # Common timestamp fields for all models
expiry_starts: Mapped[TIMESTAMP] = mapped_column( expiry_starts: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP(timezone=True), type_=TIMESTAMP(timezone=True),
server_default=func.now(), server_default=func.now(),
nullable=False, nullable=False,
comment="Record validity start timestamp", comment="Record validity start timestamp",
) )
expiry_ends: Mapped[TIMESTAMP] = mapped_column( expiry_ends: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP(timezone=True), type_=TIMESTAMP(timezone=True),
default="2099-12-31", default="2099-12-31",
server_default="2099-12-31", server_default="2099-12-31",
comment="Record validity end timestamp", comment="Record validity end timestamp",
@ -434,7 +434,7 @@ class BaseCollection(CrudMixin):
__abstract__ = True __abstract__ = True
__repr__ = ReprMixin.__repr__ __repr__ = ReprMixin.__repr__
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(Integer, primary_key=True)
class CrudCollection(CrudMixin): class CrudCollection(CrudMixin):
@ -454,7 +454,7 @@ class CrudCollection(CrudMixin):
__repr__ = ReprMixin.__repr__ __repr__ = ReprMixin.__repr__
# Primary and reference fields # Primary and reference fields
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(Integer, primary_key=True)
uu_id: Mapped[str] = mapped_column( uu_id: Mapped[str] = mapped_column(
UUID, UUID,
server_default=text("gen_random_uuid()"), server_default=text("gen_random_uuid()"),

View File

@ -42,6 +42,11 @@ class PostgresResponse(Generic[T]):
self._data: Optional[Union[List[T], T]] = None self._data: Optional[Union[List[T], T]] = None
self._count: Optional[int] = None self._count: Optional[int] = None
@property
def query(self) -> Query:
"""Get query object."""
return self._query
@property @property
def data(self) -> Union[List[T], T, None]: def data(self) -> Union[List[T], T, None]:
""" """

View File

@ -25,13 +25,13 @@ Base = declarative_base()
@lru_cache() @lru_cache()
def get_session_factory() -> scoped_session: def get_session_factory() -> scoped_session:
"""Create a thread-safe session factory.""" """Create a thread-safe session factory."""
SessionLocal = sessionmaker( session_local = sessionmaker(
bind=engine, bind=engine,
autocommit=False, autocommit=False,
autoflush=False, autoflush=False,
expire_on_commit=False, # Prevent expired object issues expire_on_commit=False, # Prevent expired object issues
) )
return scoped_session(SessionLocal) return scoped_session(session_local)
@contextmanager @contextmanager

View File

@ -1,11 +1,11 @@
[tool.poetry] [tool.poetry]
name = "wag-management-api-services" name = "wag-management-api-services"
version = "0.1.1" version = "0.1.0"
description = "WAG Management API Service" description = "WAG Management API Service"
authors = ["Karatay Berkay <karatay.berkay@evyos.com.tr>"] authors = ["Karatay Berkay <karatay.berkay@evyos.com.tr>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.12"
# FastAPI and Web # FastAPI and Web
fastapi = "^0.104.1" fastapi = "^0.104.1"
uvicorn = "^0.24.0" uvicorn = "^0.24.0"