From 76d286b5194631171f03b2a0abed988fb8e7e1ff Mon Sep 17 00:00:00 2001 From: berkay Date: Wed, 15 Jan 2025 19:18:11 +0300 Subject: [PATCH] event to functon handler completed --- .idea/misc.xml | 2 +- .idea/wag-managment-api-service-version-4.iml | 2 +- ApiEvents/EventServiceApi/__init__.py | 0 .../account/account_records.py | 357 ++++++++++++++++++ ApiEvents/EventServiceApi/route_configs.py | 99 +++++ ApiEvents/EventServiceApi/utils.py | 51 +++ ApiEvents/abstract_class.py | 181 +++++++++ ApiValidations/Request/account_records.py | 5 +- ApiValidations/Request/address.py | 8 +- ApiValidations/Request/application.py | 2 +- ApiValidations/Request/area.py | 5 +- ApiValidations/Request/authentication.py | 3 +- ApiValidations/Request/build_living_space.py | 48 +-- ApiValidations/Request/build_part.py | 106 +----- ApiValidations/Request/building.py | 65 +--- ApiValidations/Request/company.py | 50 +-- .../Request/core_request_validations.py | 2 +- ApiValidations/Request/decision_book.py | 278 +------------- ApiValidations/Request/departments.py | 22 +- ApiValidations/Request/employee.py | 190 +--------- ApiValidations/Request/events.py | 2 +- ApiValidations/Request/modules.py | 2 +- ApiValidations/Request/people.py | 38 +- .../Request/project_decision_book.py | 184 +-------- ApiValidations/Request/rules.py | 6 +- ApiValidations/Request/services.py | 2 +- ApiValidations/Request/staff.py | 5 +- ApiValidations/Request/user.py | 4 +- ApiValidations/Response/__init__.py | 3 + ApiValidations/Response/account_responses.py | 259 +++++++++++++ DockerApiServices/AllApiNeeds/app.py | 47 ++- DockerApiServices/AllApiNeeds/create_file.py | 113 ++---- .../AllApiNeeds/create_routes.py | 119 ++++++ .../AllApiNeeds/middleware/auth_middleware.py | 1 + .../AllApiNeeds/routers/__init__.py | 3 - .../AllApiNeeds/routers/base_router.py | 22 -- DockerApiServices/AuthServiceApi/Dockerfile | 3 +- DockerApiServices/EventServiceApi/Dockerfile | 2 +- .../ValidationServiceApi/Dockerfile | 2 +- DockerApiServices/pyproject.toml | 3 + .../ErrorHandlers/api_exc_handler.py | 10 +- ErrorHandlers/Exceptions/api_exc.py | 3 +- ErrorHandlers/__init__.py | 7 +- ErrorHandlers/base.py | 1 - ErrorHandlers/bases.py | 1 - Schemas/building/budget.py | 2 +- Schemas/company/company.py | 6 +- Schemas/identity/identity.py | 5 + Schemas/others/enums.py | 3 - Services/PostgresDb/Models/base_model.py | 4 +- .../PostgresDb/Models/filter_functions.py | 4 +- Services/PostgresDb/Models/mixins.py | 8 +- Services/PostgresDb/Models/response.py | 5 + Services/PostgresDb/database.py | 4 +- pyproject.toml | 4 +- 55 files changed, 1271 insertions(+), 1092 deletions(-) create mode 100644 ApiEvents/EventServiceApi/__init__.py create mode 100644 ApiEvents/EventServiceApi/account/account_records.py create mode 100644 ApiEvents/EventServiceApi/route_configs.py create mode 100644 ApiEvents/EventServiceApi/utils.py create mode 100644 ApiEvents/abstract_class.py create mode 100644 ApiValidations/Response/account_responses.py create mode 100644 DockerApiServices/AllApiNeeds/create_routes.py delete mode 100644 DockerApiServices/AllApiNeeds/routers/__init__.py delete mode 100644 DockerApiServices/AllApiNeeds/routers/base_router.py diff --git a/.idea/misc.xml b/.idea/misc.xml index fa53637..67daa03 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/.idea/wag-managment-api-service-version-4.iml b/.idea/wag-managment-api-service-version-4.iml index 001c2cd..daa9c2e 100644 --- a/.idea/wag-managment-api-service-version-4.iml +++ b/.idea/wag-managment-api-service-version-4.iml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/ApiEvents/EventServiceApi/__init__.py b/ApiEvents/EventServiceApi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ApiEvents/EventServiceApi/account/account_records.py b/ApiEvents/EventServiceApi/account/account_records.py new file mode 100644 index 0000000..26032b6 --- /dev/null +++ b/ApiEvents/EventServiceApi/account/account_records.py @@ -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, + ) diff --git a/ApiEvents/EventServiceApi/route_configs.py b/ApiEvents/EventServiceApi/route_configs.py new file mode 100644 index 0000000..98f87c4 --- /dev/null +++ b/ApiEvents/EventServiceApi/route_configs.py @@ -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 diff --git a/ApiEvents/EventServiceApi/utils.py b/ApiEvents/EventServiceApi/utils.py new file mode 100644 index 0000000..5650872 --- /dev/null +++ b/ApiEvents/EventServiceApi/utils.py @@ -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 diff --git a/ApiEvents/abstract_class.py b/ApiEvents/abstract_class.py new file mode 100644 index 0000000..6292b94 --- /dev/null +++ b/ApiEvents/abstract_class.py @@ -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 + } diff --git a/ApiValidations/Request/account_records.py b/ApiValidations/Request/account_records.py index 69a4754..5dca43c 100644 --- a/ApiValidations/Request/account_records.py +++ b/ApiValidations/Request/account_records.py @@ -1,7 +1,4 @@ -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel from typing import Optional diff --git a/ApiValidations/Request/address.py b/ApiValidations/Request/address.py index c7b9249..8939943 100644 --- a/ApiValidations/Request/address.py +++ b/ApiValidations/Request/address.py @@ -1,10 +1,8 @@ -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - ListOptions, -) from typing import Optional +from ApiValidations.Request import PydanticBaseModel, ListOptions +from ApiValidations.handler import BaseModelRegular + class PostCodeValidation: tr = { diff --git a/ApiValidations/Request/application.py b/ApiValidations/Request/application.py index f9fa22b..3a1147b 100644 --- a/ApiValidations/Request/application.py +++ b/ApiValidations/Request/application.py @@ -1,4 +1,4 @@ -from api_validations.core_validations import BaseModelRegular +from ApiValidations.Request import BaseModelRegular class SingleEnumClassKeyValidation: diff --git a/ApiValidations/Request/area.py b/ApiValidations/Request/area.py index cfdf675..635adbf 100644 --- a/ApiValidations/Request/area.py +++ b/ApiValidations/Request/area.py @@ -1,8 +1,5 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel class BuildAreaValidation: diff --git a/ApiValidations/Request/authentication.py b/ApiValidations/Request/authentication.py index d1205ce..2526e23 100644 --- a/ApiValidations/Request/authentication.py +++ b/ApiValidations/Request/authentication.py @@ -1,4 +1,5 @@ -from api_validations.core_validations import BaseModelRegular +from ApiValidations.Request import BaseModelRegular + from typing import Optional from pydantic import BaseModel diff --git a/ApiValidations/Request/build_living_space.py b/ApiValidations/Request/build_living_space.py index abb1ae7..d39dd2a 100644 --- a/ApiValidations/Request/build_living_space.py +++ b/ApiValidations/Request/build_living_space.py @@ -1,44 +1,14 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, -) +from ApiValidations.Request import BaseModelRegular + +# from api_validations.validations_request import ( +# PydanticBaseModel, +# PydanticBaseModelValidation, +# ) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel -class BuildLivingSpaceValidation: - 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): +class InsertBuildLivingSpace(BaseModelRegular): person_uu_id: str build_parts_uu_id: str occupant_type_uu_id: str @@ -46,7 +16,7 @@ class InsertBuildLivingSpace(BaseModelRegular, BuildLivingSpaceValidation): expiry_ends: Optional[str] = None -class UpdateBuildLivingSpace(PydanticBaseModel, BuildLivingSpaceValidation): +class UpdateBuildLivingSpace(PydanticBaseModel): is_tenant_live: Optional[bool] = None build_parts_uu_id: Optional[str] = None person_uu_id: Optional[str] = None diff --git a/ApiValidations/Request/build_part.py b/ApiValidations/Request/build_part.py index 0386a3b..ae6d104 100644 --- a/ApiValidations/Request/build_part.py +++ b/ApiValidations/Request/build_part.py @@ -1,81 +1,18 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel -class BuildTypesUpdateValidation: - 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): +class InsertBuildTypes(BaseModelRegular): function_code: str type_code: str lang: str type_name: str -class UpdateBuildTypes(PydanticBaseModel, BuildTypesUpdateValidation): ... +class UpdateBuildTypes(PydanticBaseModel): ... -class BuildPartsValidation: - 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): +class InsertBuildParts(BaseModelRegular): build_uu_id: str address_gov_code: str part_no: int @@ -90,40 +27,7 @@ class InsertBuildParts(BaseModelRegular, BuildPartsValidation): ref_id: Optional[str] = None -class UpdateBuildPartsValidation: - 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): +class UpdateBuildParts(PydanticBaseModel): address_gov_code: Optional[str] = None part_no: Optional[int] = None part_level: Optional[int] = None diff --git a/ApiValidations/Request/building.py b/ApiValidations/Request/building.py index 1efa2ac..7d81bdc 100644 --- a/ApiValidations/Request/building.py +++ b/ApiValidations/Request/building.py @@ -1,57 +1,9 @@ from typing import Optional from datetime import datetime -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, - CrudRecordValidation, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel -class BuildValidation: - 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): +class InsertBuild(BaseModelRegular): gov_address_code: str build_name: str @@ -72,18 +24,7 @@ class InsertBuild(BaseModelRegular, BuildValidation): garage_count: Optional[int] = None -class BuildUpdateValidation: - tr = { - **BuildValidation.tr, - **PydanticBaseModelValidation.tr, - } - en = { - **BuildValidation.en, - **PydanticBaseModelValidation.en, - } - - -class UpdateBuild(PydanticBaseModel, BuildUpdateValidation): +class UpdateBuild(PydanticBaseModel): gov_address_code: Optional[str] = None build_name: Optional[str] = None build_no: Optional[str] = None diff --git a/ApiValidations/Request/company.py b/ApiValidations/Request/company.py index 22a3787..59cf061 100644 --- a/ApiValidations/Request/company.py +++ b/ApiValidations/Request/company.py @@ -1,26 +1,8 @@ from typing import Optional, List -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel -class CompanyValidation: - 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): +class InsertCompany(BaseModelRegular): formal_name: str company_type: str commercial_type: str @@ -33,18 +15,7 @@ class InsertCompany(BaseModelRegular, CompanyValidation): # parent_uu_id: Optional[int] = None -class CompanyUpdateValidation: - tr = { - **CompanyValidation.tr, - **PydanticBaseModelValidation.tr, - } - en = { - **CompanyValidation.tr, - **PydanticBaseModelValidation.en, - } - - -class UpdateCompany(PydanticBaseModel, CompanyUpdateValidation): +class UpdateCompany(PydanticBaseModel): company_uu_id: str public_name: Optional[str] = None formal_name: Optional[str] = None @@ -55,20 +26,7 @@ class UpdateCompany(PydanticBaseModel, CompanyUpdateValidation): official_address_uu_id: Optional[str] = None -class MatchCompany2CompanyValidation: - 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): +class MatchCompany2Company(PydanticBaseModel): match_company_uu_id: List[str] duty_uu_id: str show_only: Optional[bool] = None diff --git a/ApiValidations/Request/core_request_validations.py b/ApiValidations/Request/core_request_validations.py index 37081a4..0c303a9 100644 --- a/ApiValidations/Request/core_request_validations.py +++ b/ApiValidations/Request/core_request_validations.py @@ -1,6 +1,6 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular +from ApiValidations.Request import BaseModelRegular class ListOptionsValidation: diff --git a/ApiValidations/Request/decision_book.py b/ApiValidations/Request/decision_book.py index 1c1f8f4..61fc3a4 100644 --- a/ApiValidations/Request/decision_book.py +++ b/ApiValidations/Request/decision_book.py @@ -1,127 +1,34 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, - ListOptions, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel, ListOptions -class DecisionBookDecisionBookInvitationsValidation: - 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 -): +class DecisionBookDecisionBookInvitations(BaseModelRegular): build_decision_book_uu_id: str message: str planned_date: str -class DecisionBookDecisionBookInvitationsAttendValidation: - tr = { - "token": "Token", - "is_attend": "Katılacak mı?", - } - en = { - "token": "Token", - "is_attend": "Is Attend?", - } - - -class DecisionBookDecisionBookInvitationsAttend( - BaseModelRegular, DecisionBookDecisionBookInvitationsAttendValidation -): +class DecisionBookDecisionBookInvitationsAttend(BaseModelRegular): token: str is_attend: bool -class DecisionBookDecisionBookInvitationsAssignValidation: - 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 -): +class DecisionBookDecisionBookInvitationsAssign(BaseModelRegular): token: str build_living_space_uu_id: str occupant_type_uu_id: str -class DecisionBookDecisionBookInvitationsUpdateValidation: - 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 -): +class DecisionBookDecisionBookInvitationsUpdate(PydanticBaseModel): token: str occupant_type_uu_id: Optional[str] = None -class ListDecisionBookValidation: - tr = { - "build_decision_book_uu_id": "Karar Defteri UUID", - } - en = { - "build_decision_book_uu_id": "Decision Book UUID", - } - - -class ListDecisionBook(ListOptions, ListDecisionBookValidation): +class ListDecisionBook(ListOptions): build_decision_book_uu_id: Optional[str] = None -class InsertDecisionBookValidation: - 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): +class InsertDecisionBook(PydanticBaseModel): build_uu_id: str decision_type: str meeting_date: str @@ -131,44 +38,12 @@ class InsertDecisionBook(PydanticBaseModel, InsertDecisionBookValidation): resp_company_uu_id: Optional[str] = None -class InsertDecisionBookCompletedValidation: - 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 -): +class InsertDecisionBookCompleted(BaseModelRegular): build_decision_book_uu_id: str meeting_completed_date: str -class InsertDecisionBookPersonValidation: - 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): +class InsertDecisionBookPerson(BaseModelRegular): person_uu_id: str build_decision_book_uu_id: str management_typecode_uu_id: str @@ -178,67 +53,18 @@ class InsertDecisionBookPerson(BaseModelRegular, InsertDecisionBookPersonValidat dues_percent_discount: Optional[int] = None -class UpdateDecisionBookPersonValidation: - 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): +class UpdateDecisionBookPerson(PydanticBaseModel): dues_fix_discount: Optional[float] = None dues_percent_discount: Optional[int] = None -class RemoveDecisionBookPersonValidation: - 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): +class RemoveDecisionBookPerson(PydanticBaseModel): person_uu_id: str build_decision_book_person_uu_id: str -class UpdateDecisionBookValidation: - 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): +class UpdateDecisionBook(PydanticBaseModel): decision_book_pdf_path: Optional[str] = None is_out_sourced: Optional[bool] = None contact_agreement_path: Optional[str] = None @@ -250,34 +76,7 @@ class UpdateDecisionBook(PydanticBaseModel, UpdateDecisionBookValidation): resp_company_uu_id: Optional[str] = None -class InsertBuildDecisionBookItemsValidation: - 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 -): +class InsertBuildDecisionBookItems(BaseModelRegular): token: str info_type_uu_id: str item_comment: str @@ -293,64 +92,19 @@ class InsertBuildDecisionBookItems( # item_objection: Optional[str] = None -class UpdateBuildDecisionBookItemsValidation: - 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 -): +class UpdateBuildDecisionBookItems(PydanticBaseModel): item_comment: Optional[str] = None item_objection: Optional[str] = None -class InsertBuildDecisionBookItemDebitsValidation: - 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 -): +class InsertBuildDecisionBookItemDebits(BaseModelRegular): build_decision_book_item_uu_id: str dues_values: dict # dues_types_uu_id: str # decision_taken: Optional[bool] = None -class UpdateBuildDecisionBookItemDebitsValidation: - 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 -): +class UpdateBuildDecisionBookItemDebits(PydanticBaseModel): dues_types_uu_id: Optional[str] = None dues_values: Optional[dict] = None decision_taken: Optional[bool] = None diff --git a/ApiValidations/Request/departments.py b/ApiValidations/Request/departments.py index 03c61e1..377b119 100644 --- a/ApiValidations/Request/departments.py +++ b/ApiValidations/Request/departments.py @@ -1,28 +1,10 @@ from typing import Optional -from api_validations.validations_request import ( +from ApiValidations.Request import ( PydanticBaseModel, - PydanticBaseModelValidation, ) -class DepartmentsPydanticValidation: - 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): +class DepartmentsPydantic(PydanticBaseModel): department_code: Optional[str] department_name: Optional[str] diff --git a/ApiValidations/Request/employee.py b/ApiValidations/Request/employee.py index 163928a..2735304 100644 --- a/ApiValidations/Request/employee.py +++ b/ApiValidations/Request/employee.py @@ -1,176 +1,51 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel -class BindEmployees2PeopleValidation: - 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): +class BindEmployees2People(PydanticBaseModel): staff_uu_id: str people_uu_id: str expiry_starts: Optional[str] = None -class UnBindEmployees2PeopleValidation: - 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): +class UnBindEmployees2People(PydanticBaseModel): people_uu_id: str expiry_ends: str -class InsertEmployeesValidation: - 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): +class InsertEmployees(BaseModelRegular): staff_uu_id: str people_uu_id: Optional[str] = None -class InsertCompanyDutyValidation: - 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): +class InsertCompanyDuty(BaseModelRegular): duty_code: str duty_name: str duty_description: Optional[str] = None -class SelectDutiesValidation: - tr = { - "duty_uu_id": "Görev UUID", - } - en = { - "duty_uu_id": "Duty UUID", - } - - -class SelectDuties(BaseModelRegular, SelectDutiesValidation): +class SelectDuties(BaseModelRegular): duty_uu_id: Optional[str] = None -class InsertDutiesValidation: - 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): +class InsertDuties(BaseModelRegular): duties_uu_id: str department_uu_id: str 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): duties_uu_id: Optional[str] = None department_uu_id: Optional[str] = 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): duty_code: Optional[str] = None duty_name: 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): gross_salary: float net_salary: float @@ -179,25 +54,6 @@ class InsertCompanyEmployeesSalaries(BaseModelRegular): 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): gross_salary: Optional[float] = None net_salary: Optional[float] = None @@ -206,24 +62,8 @@ class UpdateCompanyEmployeesSalaries(PydanticBaseModel): 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, InsertCompanyEmployeesValidation): +class InsertCompanyEmployees(BaseModelRegular): employee_description: Optional[str] = None person_uu_id: str @@ -233,19 +73,7 @@ class InsertCompanyEmployees(BaseModelRegular, InsertCompanyEmployeesValidation) 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, UpdateCompanyEmployeesValidation): +class UpdateCompanyEmployees(PydanticBaseModel): stop_date: Optional[str] = None employee_description: Optional[str] = None diff --git a/ApiValidations/Request/events.py b/ApiValidations/Request/events.py index 0cfe276..98f4db9 100644 --- a/ApiValidations/Request/events.py +++ b/ApiValidations/Request/events.py @@ -1,5 +1,5 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular +from ApiValidations.Request import BaseModelRegular class RegisterEvents2EmployeeValidation: diff --git a/ApiValidations/Request/modules.py b/ApiValidations/Request/modules.py index 42076d3..e6fcc67 100644 --- a/ApiValidations/Request/modules.py +++ b/ApiValidations/Request/modules.py @@ -1,4 +1,4 @@ -from api_validations.core_validations import BaseModelRegular +from ApiValidations.Request import BaseModelRegular class RegisterModules2OccupantValidation: diff --git a/ApiValidations/Request/people.py b/ApiValidations/Request/people.py index 36182ec..281f355 100644 --- a/ApiValidations/Request/people.py +++ b/ApiValidations/Request/people.py @@ -1,29 +1,8 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel -class InsertPersonValidation: - 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): +class InsertPerson(BaseModelRegular): firstname: str surname: str sex_code: str @@ -38,18 +17,7 @@ class InsertPerson(BaseModelRegular, InsertPersonValidation): ref_id: Optional[str] = None -class UpdatePersonValidation: - tr = { - **PydanticBaseModelValidation.tr, - **InsertPersonValidation.tr, - } - en = { - **PydanticBaseModelValidation.en, - **InsertPersonValidation.tr, - } - - -class UpdatePerson(PydanticBaseModel, UpdatePersonValidation): +class UpdatePerson(PydanticBaseModel): firstname: Optional[str] = None surname: Optional[str] = None middle_name: Optional[str] diff --git a/ApiValidations/Request/project_decision_book.py b/ApiValidations/Request/project_decision_book.py index 71fc1e4..6004243 100644 --- a/ApiValidations/Request/project_decision_book.py +++ b/ApiValidations/Request/project_decision_book.py @@ -1,31 +1,8 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, - PydanticBaseModelValidation, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel -class InsertBuildDecisionBookProjectItemsValidation: - tr = { - "build_decision_book_project_uu_id": "Proje UUID", - "item_header": "Başlık", - "item_comment": "Açı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 -): +class InsertBuildDecisionBookProjectItems(BaseModelRegular): build_decision_book_project_uu_id: str item_header: str item_comment: str @@ -33,17 +10,6 @@ class InsertBuildDecisionBookProjectItems( item_objection: Optional[str] = None -class UpdateBuildDecisionBookProjectItemsValidation: - tr = { - **InsertBuildDecisionBookProjectItemsValidation.tr, - **PydanticBaseModelValidation.tr, - } - en = { - **InsertBuildDecisionBookProjectItemsValidation.en, - **PydanticBaseModelValidation.en, - } - - class UpdateBuildDecisionBookProjectItems(PydanticBaseModel): item_header: Optional[str] = None item_comment: Optional[str] = None @@ -52,30 +18,7 @@ class UpdateBuildDecisionBookProjectItems(PydanticBaseModel): build_decision_book_project_uu_id: Optional[str] = None -class InsertBuildDecisionBookProjectPersonValidation: - 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 -): +class InsertBuildDecisionBookProjectPerson(BaseModelRegular): dues_percent_discount: Optional[int] = None job_fix_wage: Optional[float] = None bid_price: Optional[float] = None @@ -85,20 +28,7 @@ class InsertBuildDecisionBookProjectPerson( project_team_type_uu_id: str -class UpdateBuildDecisionBookProjectPersonValidation: - tr = { - **InsertBuildDecisionBookProjectPersonValidation.tr, - **PydanticBaseModelValidation.tr, - } - en = { - **InsertBuildDecisionBookProjectPersonValidation.en, - **PydanticBaseModelValidation.en, - } - - -class UpdateBuildDecisionBookProjectPerson( - PydanticBaseModel, UpdateBuildDecisionBookProjectPersonValidation -): +class UpdateBuildDecisionBookProjectPerson(PydanticBaseModel): dues_percent_discount: Optional[int] = None job_fix_wage: Optional[float] = None bid_price: Optional[float] = None @@ -108,47 +38,8 @@ class UpdateBuildDecisionBookProjectPerson( 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( - BaseModelRegular, InsertBuildDecisionBookProjectsValidation + BaseModelRegular ): build_decision_book_item_uu_id: str project_responsible_person_uu_id: str @@ -169,19 +60,8 @@ class InsertBuildDecisionBookProjects( resp_company_uu_id: Optional[str] = None -class UpdateBuildDecisionBookProjectsValidation: - tr = { - **InsertBuildDecisionBookProjectsValidation.tr, - **PydanticBaseModelValidation.tr, - } - en = { - **InsertBuildDecisionBookProjectsValidation.en, - **PydanticBaseModelValidation.en, - } - - class UpdateBuildDecisionBookProjects( - PydanticBaseModel, UpdateBuildDecisionBookProjectsValidation + PydanticBaseModel ): build_decision_book_project_uu_id: str is_out_sourced: Optional[bool] = False @@ -196,23 +76,9 @@ class UpdateBuildDecisionBookProjects( 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( - PydanticBaseModel, ApprovalsBuildDecisionBookProjectsValidation + PydanticBaseModel ): build_decision_book_project_uu_id: 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( - PydanticBaseModel, InsertBuildDecisionBookProjectItemDebitsValidation + PydanticBaseModel ): build_decision_book_project_item_uu_id: str payment_date: str @@ -255,19 +100,8 @@ class InsertBuildDecisionBookProjectItemDebits( decision_taken: Optional[bool] = None -class UpdateBuildDecisionBookProjectItemDebitsValidation: - tr = { - **InsertBuildDecisionBookProjectItemDebitsValidation.tr, - **PydanticBaseModelValidation.tr, - } - en = { - **InsertBuildDecisionBookProjectItemDebitsValidation.en, - **PydanticBaseModelValidation.en, - } - - class UpdateBuildDecisionBookProjectItemDebits( - PydanticBaseModel, UpdateBuildDecisionBookProjectItemDebitsValidation + PydanticBaseModel ): dues_values: Optional[str] = None discount_value: Optional[float] = None diff --git a/ApiValidations/Request/rules.py b/ApiValidations/Request/rules.py index 23f22c7..c9f9845 100644 --- a/ApiValidations/Request/rules.py +++ b/ApiValidations/Request/rules.py @@ -1,8 +1,6 @@ from typing import Optional, List -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, -) +from ApiValidations.Request import BaseModelRegular +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel class CheckEndpointAccess(BaseModelRegular): diff --git a/ApiValidations/Request/services.py b/ApiValidations/Request/services.py index 6ce55b4..54712c9 100644 --- a/ApiValidations/Request/services.py +++ b/ApiValidations/Request/services.py @@ -1,4 +1,4 @@ -from api_validations.core_validations import BaseModelRegular +from ApiValidations.Request import BaseModelRegular class RegisterServices2OccupantValidation: diff --git a/ApiValidations/Request/staff.py b/ApiValidations/Request/staff.py index 6222b2d..03cdadb 100644 --- a/ApiValidations/Request/staff.py +++ b/ApiValidations/Request/staff.py @@ -1,8 +1,5 @@ from typing import Optional -from api_validations.core_validations import BaseModelRegular -from api_validations.validations_request import ( - PydanticBaseModel, -) +from ApiValidations.Request import BaseModelRegular, PydanticBaseModel class InsertStaffValidation: diff --git a/ApiValidations/Request/user.py b/ApiValidations/Request/user.py index 99f89c8..7583a1b 100644 --- a/ApiValidations/Request/user.py +++ b/ApiValidations/Request/user.py @@ -1,7 +1,5 @@ from typing import Optional -from api_validations.validations_request import ( - PydanticBaseModel, -) +from ApiValidations.Request import PydanticBaseModel class InsertUsersValidation: diff --git a/ApiValidations/Response/__init__.py b/ApiValidations/Response/__init__.py index e69de29..5af54b7 100644 --- a/ApiValidations/Response/__init__.py +++ b/ApiValidations/Response/__init__.py @@ -0,0 +1,3 @@ +from .account_responses import AccountRecordResponse + +__all__ = ["AccountRecordResponse"] diff --git a/ApiValidations/Response/account_responses.py b/ApiValidations/Response/account_responses.py new file mode 100644 index 0000000..e349046 --- /dev/null +++ b/ApiValidations/Response/account_responses.py @@ -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 diff --git a/DockerApiServices/AllApiNeeds/app.py b/DockerApiServices/AllApiNeeds/app.py index fe7c11f..35e22a1 100644 --- a/DockerApiServices/AllApiNeeds/app.py +++ b/DockerApiServices/AllApiNeeds/app.py @@ -10,14 +10,53 @@ This module initializes and configures the FastAPI application with: """ import uvicorn -import routers - -from create_file import create_app +from fastapi import FastAPI +from create_routes import get_all_routers from prometheus_fastapi_instrumentator import Instrumentator 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 setup_middleware(app) # Configure middleware and exception handlers diff --git a/DockerApiServices/AllApiNeeds/create_file.py b/DockerApiServices/AllApiNeeds/create_file.py index 9bcb4ea..bf1977e 100644 --- a/DockerApiServices/AllApiNeeds/create_file.py +++ b/DockerApiServices/AllApiNeeds/create_file.py @@ -9,15 +9,14 @@ This module provides functionality to create and configure a FastAPI application - Security requirements for protected endpoints """ -from types import ModuleType -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Tuple from fastapi import FastAPI, APIRouter from fastapi.responses import JSONResponse, RedirectResponse 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]: """ @@ -27,15 +26,18 @@ def setup_security_schema() -> Dict[str, Any]: Dict[str, Any]: Security schema configuration """ return { - "Bearer": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "Enter the token", + "components": { + "securitySchemes": { + "Bearer": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "Enter the token" + } + } } } - def configure_route_security( path: str, method: str, schema: Dict[str, Any], protected_paths: List[str] ) -> None: @@ -49,42 +51,13 @@ def configure_route_security( protected_paths: List of paths that require authentication """ if path in protected_paths: - if "paths" not in schema: - schema["paths"] = {} + if "paths" in schema and path in schema["paths"]: + if method.lower() in schema["paths"][path]: + schema["paths"][path][method.lower()]["security"] = [{"Bearer": []}] - if path not in schema["paths"]: - 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]: +def create_app() -> FastAPI: """ - Extract all routers from the routers module. - - 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 + Create and configure a FastAPI application with dynamic route creation. Returns: FastAPI: Configured FastAPI application instance @@ -95,53 +68,39 @@ def create_app(routers: ModuleType) -> FastAPI: description=Config.DESCRIPTION, default_response_class=JSONResponse, ) - - # Add home route that redirects to API documentation + @app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION)) async def home() -> RedirectResponse: """Redirect root path to API documentation.""" return RedirectResponse(url="/docs") - # Get all routers - router_instances = get_routers(routers) - - # Find protected paths - protected_paths = [] - 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: + # Get all routers and protected routes using the dynamic route creation + routers, protected_routes = get_all_routers() + + # Include all routers + for router in routers: app.include_router(router) - - # Configure custom OpenAPI schema + + # Configure OpenAPI schema with security def custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema = get_openapi( - title=Config.TITLE, - version="1.0.0", - description=Config.DESCRIPTION, + title="WAG Management API", + version="4.0.0", + description="WAG Management API Service", routes=app.routes, ) - # Add security schemes - openapi_schema["components"] = {"securitySchemes": setup_security_schema()} + # Add security scheme + security_schema = setup_security_schema() + openapi_schema.update(security_schema) - # Configure security for each route - for route in app.routes: - if isinstance(route, APIRoute): - configure_route_security( - route.path, - route.methods.pop().lower(), - openapi_schema, - protected_paths, - ) + # 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 diff --git a/DockerApiServices/AllApiNeeds/create_routes.py b/DockerApiServices/AllApiNeeds/create_routes.py new file mode 100644 index 0000000..a3bee04 --- /dev/null +++ b/DockerApiServices/AllApiNeeds/create_routes.py @@ -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 \ No newline at end of file diff --git a/DockerApiServices/AllApiNeeds/middleware/auth_middleware.py b/DockerApiServices/AllApiNeeds/middleware/auth_middleware.py index 49124a9..6ee83f9 100644 --- a/DockerApiServices/AllApiNeeds/middleware/auth_middleware.py +++ b/DockerApiServices/AllApiNeeds/middleware/auth_middleware.py @@ -113,6 +113,7 @@ class MiddlewareModule: raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr") except Exception as e: raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr") + return wrapper diff --git a/DockerApiServices/AllApiNeeds/routers/__init__.py b/DockerApiServices/AllApiNeeds/routers/__init__.py deleted file mode 100644 index 3e0088c..0000000 --- a/DockerApiServices/AllApiNeeds/routers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .base_router import test_route - -__all__ = ["test_route"] diff --git a/DockerApiServices/AllApiNeeds/routers/base_router.py b/DockerApiServices/AllApiNeeds/routers/base_router.py deleted file mode 100644 index 21afe00..0000000 --- a/DockerApiServices/AllApiNeeds/routers/base_router.py +++ /dev/null @@ -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"} - diff --git a/DockerApiServices/AuthServiceApi/Dockerfile b/DockerApiServices/AuthServiceApi/Dockerfile index 5ddca69..008dc07 100644 --- a/DockerApiServices/AuthServiceApi/Dockerfile +++ b/DockerApiServices/AuthServiceApi/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-slim +FROM python:3.12-slim WORKDIR /app @@ -19,7 +19,6 @@ RUN poetry config virtualenvs.create false \ && rm -rf ~/.cache/pypoetry # Copy application code - COPY DockerApiServices/AllApiNeeds /app/ COPY ErrorHandlers /app/ErrorHandlers COPY LanguageModels /app/LanguageModels diff --git a/DockerApiServices/EventServiceApi/Dockerfile b/DockerApiServices/EventServiceApi/Dockerfile index 186477a..d7414b0 100644 --- a/DockerApiServices/EventServiceApi/Dockerfile +++ b/DockerApiServices/EventServiceApi/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-slim +FROM python:3.12-slim WORKDIR /app diff --git a/DockerApiServices/ValidationServiceApi/Dockerfile b/DockerApiServices/ValidationServiceApi/Dockerfile index 186477a..d7414b0 100644 --- a/DockerApiServices/ValidationServiceApi/Dockerfile +++ b/DockerApiServices/ValidationServiceApi/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-slim +FROM python:3.12-slim WORKDIR /app diff --git a/DockerApiServices/pyproject.toml b/DockerApiServices/pyproject.toml index 398238d..bea12c3 100644 --- a/DockerApiServices/pyproject.toml +++ b/DockerApiServices/pyproject.toml @@ -36,6 +36,9 @@ pytest-cov = "^4.1.0" prometheus-client = "^0.19.0" prometheus-fastapi-instrumentator = "^6.1.0" +# Cryptography +cryptography = "^43.0.3" + # Utilities python-dateutil = "^2.8.2" typing-extensions = "^4.8.0" diff --git a/ErrorHandlers/ErrorHandlers/api_exc_handler.py b/ErrorHandlers/ErrorHandlers/api_exc_handler.py index 277ecdf..46cc4ed 100644 --- a/ErrorHandlers/ErrorHandlers/api_exc_handler.py +++ b/ErrorHandlers/ErrorHandlers/api_exc_handler.py @@ -18,6 +18,7 @@ class HTTPExceptionApiHandler: @staticmethod def retrieve_error_status_code(exc: HTTPExceptionApi) -> int: from ErrorHandlers import DEFAULT_ERROR + error_by_codes = BaseErrorModelClass.retrieve_error_by_codes() grab_status_code = error_by_codes.get( str(exc.error_code).upper(), DEFAULT_ERROR @@ -27,12 +28,15 @@ class HTTPExceptionApiHandler: @staticmethod def retrieve_error_message(exc: HTTPExceptionApi, error_languages) -> str: from ErrorHandlers import DEFAULT_ERROR + return error_languages.get(str(exc.error_code).upper(), DEFAULT_ERROR) async def handle_exception( self, request: Union[Request, WebSocket], exc: Exception ) -> 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): error_languages = MergedErrorLanguageModels.get_language_models( language=exc.lang @@ -45,6 +49,7 @@ class HTTPExceptionApiHandler: "message": error_message, "lang": exc.lang, "request": request_string, + "loc": exc.loc, }, ) return self.RESPONSE_MODEL( @@ -53,5 +58,6 @@ class HTTPExceptionApiHandler: "message": "Internal Server Error", "lang": "def", "request": request_string, + "loc": exc.loc, }, - ) # Handle other exceptions with a generic 500 error + ) # Handle other exceptions with a generic 500 error diff --git a/ErrorHandlers/Exceptions/api_exc.py b/ErrorHandlers/Exceptions/api_exc.py index 2373dd9..2fcf713 100644 --- a/ErrorHandlers/Exceptions/api_exc.py +++ b/ErrorHandlers/Exceptions/api_exc.py @@ -1,5 +1,6 @@ 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.lang = lang + self.loc = loc diff --git a/ErrorHandlers/__init__.py b/ErrorHandlers/__init__.py index f7a6b12..fae403a 100644 --- a/ErrorHandlers/__init__.py +++ b/ErrorHandlers/__init__.py @@ -4,10 +4,7 @@ from ErrorHandlers.ErrorHandlers.api_exc_handler import ( from ErrorHandlers.Exceptions.api_exc import ( HTTPExceptionApi, ) + DEFAULT_ERROR = "UNKNOWN_ERROR" -__all__ = [ - "HTTPExceptionApiHandler", - "HTTPExceptionApi", - "DEFAULT_ERROR" -] +__all__ = ["HTTPExceptionApiHandler", "HTTPExceptionApi", "DEFAULT_ERROR"] diff --git a/ErrorHandlers/base.py b/ErrorHandlers/base.py index 2e290ee..f6b32ec 100644 --- a/ErrorHandlers/base.py +++ b/ErrorHandlers/base.py @@ -11,4 +11,3 @@ class BaseError: NOT_ACCEPTABLE: int = 406 INVALID_DATA: int = 422 UNKNOWN_ERROR: int = 502 - diff --git a/ErrorHandlers/bases.py b/ErrorHandlers/bases.py index 587dd80..e7ee6a3 100644 --- a/ErrorHandlers/bases.py +++ b/ErrorHandlers/bases.py @@ -16,4 +16,3 @@ class BaseErrorModelClass: } language_model_status.update(clean_dict) return language_model_status - diff --git a/Schemas/building/budget.py b/Schemas/building/budget.py index 7bbdf52..37af08c 100644 --- a/Schemas/building/budget.py +++ b/Schemas/building/budget.py @@ -37,7 +37,7 @@ class DecisionBookBudgetBooks(CrudCollection): Index( "_decision_book_budget_companies_book_ndx_00", company_id, - CrudCollection.created_at, + "created_at", ), {"comment": "budget Book Information"}, ) diff --git a/Schemas/company/company.py b/Schemas/company/company.py index cda857d..dea49af 100644 --- a/Schemas/company/company.py +++ b/Schemas/company/company.py @@ -1,6 +1,4 @@ from fastapi.exceptions import HTTPException - - from sqlalchemy import ( String, Integer, @@ -13,13 +11,13 @@ from sqlalchemy import ( ) 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 ( InsertCompany, UpdateCompany, MatchCompany2Company, ) -from api_objects.auth.token_objects import EmployeeTokenObject from LanguageModels.Database.company.company import ( RelationshipDutyCompanyLanguageModel, CompaniesLanguageModel, diff --git a/Schemas/identity/identity.py b/Schemas/identity/identity.py index 8446bbc..e390528 100644 --- a/Schemas/identity/identity.py +++ b/Schemas/identity/identity.py @@ -18,6 +18,7 @@ from sqlalchemy.orm import mapped_column, relationship, Mapped from ApiLibrary.date_time_actions.date_functions import system_arrow from AllConfigs.Token.config import Auth, ApiStatic +from ApiLibrary.extensions.select import SelectAction, SelectActionWithEmployee from Services.PostgresDb import CrudCollection @@ -64,6 +65,10 @@ class UsersTokens(CrudCollection): # users = relationship("Users", back_populates="tokens", foreign_keys=[user_id]) +class UserLoginModule: + pass + + class Users(CrudCollection, UserLoginModule, SelectAction): """ Application User frame to connect to API with assigned token-based HTTP connection diff --git a/Schemas/others/enums.py b/Schemas/others/enums.py index 9a1e9a3..72949a2 100644 --- a/Schemas/others/enums.py +++ b/Schemas/others/enums.py @@ -101,6 +101,3 @@ class ApiEnumDropdown(CrudCollection): None, ) ) - - -ApiEnumDropdown.set_session(ApiEnumDropdown.__session__) diff --git a/Services/PostgresDb/Models/base_model.py b/Services/PostgresDb/Models/base_model.py index fa95209..0df4e18 100644 --- a/Services/PostgresDb/Models/base_model.py +++ b/Services/PostgresDb/Models/base_model.py @@ -2,6 +2,7 @@ from contextlib import contextmanager from typing import Any, Dict, Optional, Generator from sqlalchemy.orm import Session from sqlalchemy import inspect + 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 - def get_session(self) -> Session: + @classmethod + def new_session(cls) -> Session: """Get database session.""" from Services.PostgresDb.database import get_db diff --git a/Services/PostgresDb/Models/filter_functions.py b/Services/PostgresDb/Models/filter_functions.py index fd78621..b72b402 100644 --- a/Services/PostgresDb/Models/filter_functions.py +++ b/Services/PostgresDb/Models/filter_functions.py @@ -438,7 +438,7 @@ class FilterAttributes: @classmethod def filter_all( - cls: Type[T], db: Session, *args: BinaryExpression, system: bool = False + cls: Type[T], *args: Any, db: Session, system: bool = False ) -> PostgresResponse: """ Filter multiple records by expressions. @@ -473,8 +473,8 @@ class FilterAttributes: @classmethod def filter_one( cls: Type[T], + *args: Any, db: Session, - *args: BinaryExpression, system: bool = False, expired: bool = False, ) -> PostgresResponse: diff --git a/Services/PostgresDb/Models/mixins.py b/Services/PostgresDb/Models/mixins.py index 72c9d12..94d1c61 100644 --- a/Services/PostgresDb/Models/mixins.py +++ b/Services/PostgresDb/Models/mixins.py @@ -110,13 +110,13 @@ class CrudMixin( # Common timestamp fields for all models expiry_starts: Mapped[TIMESTAMP] = mapped_column( - TIMESTAMP(timezone=True), + type_=TIMESTAMP(timezone=True), server_default=func.now(), nullable=False, comment="Record validity start timestamp", ) expiry_ends: Mapped[TIMESTAMP] = mapped_column( - TIMESTAMP(timezone=True), + type_=TIMESTAMP(timezone=True), default="2099-12-31", server_default="2099-12-31", comment="Record validity end timestamp", @@ -434,7 +434,7 @@ class BaseCollection(CrudMixin): __abstract__ = True __repr__ = ReprMixin.__repr__ - id: Mapped[int] = mapped_column(primary_key=True) + id: Mapped[int] = mapped_column(Integer, primary_key=True) class CrudCollection(CrudMixin): @@ -454,7 +454,7 @@ class CrudCollection(CrudMixin): __repr__ = ReprMixin.__repr__ # 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( UUID, server_default=text("gen_random_uuid()"), diff --git a/Services/PostgresDb/Models/response.py b/Services/PostgresDb/Models/response.py index 001e320..60d8cf0 100644 --- a/Services/PostgresDb/Models/response.py +++ b/Services/PostgresDb/Models/response.py @@ -42,6 +42,11 @@ class PostgresResponse(Generic[T]): self._data: Optional[Union[List[T], T]] = None self._count: Optional[int] = None + @property + def query(self) -> Query: + """Get query object.""" + return self._query + @property def data(self) -> Union[List[T], T, None]: """ diff --git a/Services/PostgresDb/database.py b/Services/PostgresDb/database.py index 0fb604d..f1d70ca 100644 --- a/Services/PostgresDb/database.py +++ b/Services/PostgresDb/database.py @@ -25,13 +25,13 @@ Base = declarative_base() @lru_cache() def get_session_factory() -> scoped_session: """Create a thread-safe session factory.""" - SessionLocal = sessionmaker( + session_local = sessionmaker( bind=engine, autocommit=False, autoflush=False, expire_on_commit=False, # Prevent expired object issues ) - return scoped_session(SessionLocal) + return scoped_session(session_local) @contextmanager diff --git a/pyproject.toml b/pyproject.toml index 228fa42..775bf00 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,11 @@ [tool.poetry] name = "wag-management-api-services" -version = "0.1.1" +version = "0.1.0" description = "WAG Management API Service" authors = ["Karatay Berkay "] [tool.poetry.dependencies] -python = "^3.9" +python = "^3.12" # FastAPI and Web fastapi = "^0.104.1" uvicorn = "^0.24.0"