diff --git a/ApiServices/AuthService/Dockerfile b/ApiServices/AuthService/Dockerfile
index 18d9b89..f25db95 100644
--- a/ApiServices/AuthService/Dockerfile
+++ b/ApiServices/AuthService/Dockerfile
@@ -5,20 +5,21 @@ ENV PYTHONUNBUFFERED 1
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
-COPY ../service_app/requirements.txt .
+COPY ApiServices/AuthService/pyproject.toml .
RUN uv venv
-RUN uv pip install -r requirements.txt
+RUN uv pip install -r pyproject.toml
-COPY ../service_app ./service_app
+COPY ApiServices/AuthService ./service_app
+COPY ApiServices/api_handlers ./service_app/api_handlers
-COPY ../databases ./service_app/databases
-COPY ../api_services ./service_app/api_services
-COPY ../api_objects ./service_app/api_objects
-COPY ../api_configs ./service_app/api_configs
-COPY ../api_events ./service_app/api_events
-COPY ../api_library ./service_app/api_library
-COPY ../api_validations ./service_app/api_validations
+COPY databases ./service_app/databases
+COPY api_services ./service_app/api_services
+COPY api_objects ./service_app/api_objects
+COPY api_configs ./service_app/api_configs
+COPY api_events ./service_app/api_events
+COPY api_library ./service_app/api_library
+COPY api_validations ./service_app/api_validations
WORKDIR /service_app
diff --git a/ApiServices/AuthService/application/create_file.py b/ApiServices/AuthService/application/create_file.py
index b492475..4ef80ce 100644
--- a/ApiServices/AuthService/application/create_file.py
+++ b/ApiServices/AuthService/application/create_file.py
@@ -1,11 +1,11 @@
+from fastapi import FastAPI
+from fastapi.responses import JSONResponse
+from fastapi.openapi.utils import get_openapi
+from fastapi.responses import RedirectResponse
+from api_configs.configs import Config
+
+
def create_app(routers):
- from fastapi import FastAPI
- from fastapi.responses import JSONResponse
- from fastapi.openapi.utils import get_openapi
- from fastapi.responses import RedirectResponse
-
- from api_configs import Config
-
api_app = FastAPI(title=str(Config.TITLE), default_response_class=JSONResponse)
@api_app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION))
diff --git a/ApiServices/AuthService/routers/__init__.py b/ApiServices/AuthService/routers/__init__.py
index e69de29..a9a2c5b 100644
--- a/ApiServices/AuthService/routers/__init__.py
+++ b/ApiServices/AuthService/routers/__init__.py
@@ -0,0 +1 @@
+__all__ = []
diff --git a/ApiServices/EventService/Dockerfile b/ApiServices/EventService/Dockerfile
index 18d9b89..56267db 100644
--- a/ApiServices/EventService/Dockerfile
+++ b/ApiServices/EventService/Dockerfile
@@ -5,20 +5,21 @@ ENV PYTHONUNBUFFERED 1
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
-COPY ../service_app/requirements.txt .
+COPY ApiServices/EventService/pyproject.toml .
RUN uv venv
-RUN uv pip install -r requirements.txt
+RUN uv pip install -r pyproject.toml
-COPY ../service_app ./service_app
+COPY ApiServices/EventService ./service_app
+COPY ApiServices/api_handlers ./service_app/api_handlers
-COPY ../databases ./service_app/databases
-COPY ../api_services ./service_app/api_services
-COPY ../api_objects ./service_app/api_objects
-COPY ../api_configs ./service_app/api_configs
-COPY ../api_events ./service_app/api_events
-COPY ../api_library ./service_app/api_library
-COPY ../api_validations ./service_app/api_validations
+COPY databases ./service_app/databases
+COPY api_services ./service_app/api_services
+COPY api_objects ./service_app/api_objects
+COPY api_configs ./service_app/api_configs
+COPY api_events ./service_app/api_events
+COPY api_library ./service_app/api_library
+COPY api_validations ./service_app/api_validations
WORKDIR /service_app
diff --git a/ApiServices/EventService/routers/__init__.py b/ApiServices/EventService/routers/__init__.py
index e69de29..b680692 100644
--- a/ApiServices/EventService/routers/__init__.py
+++ b/ApiServices/EventService/routers/__init__.py
@@ -0,0 +1 @@
+__all__ = []
\ No newline at end of file
diff --git a/ApiServices/ValidationService/Dockerfile b/ApiServices/ValidationService/Dockerfile
index 18d9b89..99cf4e3 100644
--- a/ApiServices/ValidationService/Dockerfile
+++ b/ApiServices/ValidationService/Dockerfile
@@ -5,20 +5,21 @@ ENV PYTHONUNBUFFERED 1
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
-COPY ../service_app/requirements.txt .
+COPY ApiServices/ValidationService/pyproject.toml .
RUN uv venv
-RUN uv pip install -r requirements.txt
+RUN uv pip install -r pyproject.toml
-COPY ../service_app ./service_app
+COPY ApiServices/ValidationService ./service_app
+COPY ApiServices/api_handlers ./service_app/api_handlers
-COPY ../databases ./service_app/databases
-COPY ../api_services ./service_app/api_services
-COPY ../api_objects ./service_app/api_objects
-COPY ../api_configs ./service_app/api_configs
-COPY ../api_events ./service_app/api_events
-COPY ../api_library ./service_app/api_library
-COPY ../api_validations ./service_app/api_validations
+COPY databases ./service_app/databases
+COPY api_services ./service_app/api_services
+COPY api_objects ./service_app/api_objects
+COPY api_configs ./service_app/api_configs
+COPY api_events ./service_app/api_events
+COPY api_library ./service_app/api_library
+COPY api_validations ./service_app/api_validations
WORKDIR /service_app
diff --git a/ApiServices/ValidationService/routers/__init__.py b/ApiServices/ValidationService/routers/__init__.py
index e69de29..a9a2c5b 100644
--- a/ApiServices/ValidationService/routers/__init__.py
+++ b/ApiServices/ValidationService/routers/__init__.py
@@ -0,0 +1 @@
+__all__ = []
diff --git a/ApiServices/__init__.py b/ApiServices/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ApiServices/api_handlers/__init__.py b/ApiServices/api_handlers/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ApiServices/api_handlers/core_response.py b/ApiServices/api_handlers/core_response.py
new file mode 100644
index 0000000..851b8da
--- /dev/null
+++ b/ApiServices/api_handlers/core_response.py
@@ -0,0 +1,147 @@
+from typing import Any, Union
+from fastapi import status
+from fastapi.responses import JSONResponse
+
+from databases.sql_models.response_model import AlchemyResponse
+
+
+class AlchemyJsonResponse:
+ status_code: status
+ message: str
+ result: AlchemyResponse
+ completed: bool
+ filter_attributes: Any = None
+ response_model: Any = None
+ cls_object: Any = None
+
+ @staticmethod
+ def get_total_count(cls_object, filter_attributes):
+ total_page_number = 1
+ count_to_use = cls_object.total_count / int(filter_attributes.size)
+ if cls_object.total_count > int(filter_attributes.size):
+ if isinstance(count_to_use, int):
+ total_page_number = round(count_to_use, 0)
+ elif isinstance(count_to_use, float):
+ total_page_number = round(count_to_use, 0) + 1
+ return total_page_number
+
+ def __new__(
+ cls,
+ message: str,
+ status_code: str = "HTTP_200_OK",
+ result: Union[Any, list] = None,
+ completed: bool = True,
+ response_model: Any = None,
+ cls_object: Any = None,
+ filter_attributes: Any = None,
+ ):
+ cls.status_code = getattr(status, status_code, "HTTP_200_OK")
+ cls.message = message
+ cls.result = result
+ cls.completed = completed
+ cls.response_model = response_model
+
+ pagination_dict = {
+ "size/total_count": [10, 10],
+ "page/total_page": [1, 1],
+ "order_field": "id",
+ "order_type": "asc",
+ }
+ if filter_attributes:
+ total_page_number = cls.get_total_count(cls_object, filter_attributes)
+ pagination_dict = {
+ "size/total_count": [filter_attributes.size, cls_object.total_count],
+ "page/total_page": [filter_attributes.page, total_page_number],
+ "order_field": filter_attributes.order_field,
+ "order_type": filter_attributes.order_type,
+ }
+
+ if isinstance(cls.result, dict) or isinstance(cls.result, list):
+ return JSONResponse(
+ status_code=cls.status_code,
+ content=dict(
+ total_count=len(cls.result),
+ count=len(cls.result),
+ pagination=pagination_dict,
+ completed=cls.completed,
+ message=cls.message,
+ data=cls.result,
+ ),
+ )
+
+ first_item = getattr(cls.result, "data", None)
+ if not first_item:
+ return JSONResponse(
+ status_code=cls.status_code,
+ content=dict(
+ total_count=0,
+ count=0,
+ pagination=pagination_dict,
+ completed=cls.completed,
+ message=cls.message,
+ data=[],
+ ),
+ )
+
+ if cls.result.first:
+ return JSONResponse(
+ status_code=cls.status_code,
+ content=dict(
+ total_count=1,
+ count=1,
+ pagination=pagination_dict,
+ completed=cls.completed,
+ message=cls.message,
+ data=cls.result.data.get_dict(),
+ ),
+ )
+
+ if not cls.result.get(1).filter_attr and isinstance(cls.result.data, list):
+ counts = cls.result.count
+ return JSONResponse(
+ status_code=cls.status_code,
+ content=dict(
+ total_count=counts,
+ count=counts,
+ pagination=pagination_dict,
+ completed=cls.completed,
+ message=cls.message,
+ data=[result_data.get_dict() for result_data in cls.result.data],
+ ),
+ )
+
+ # filter_model = cls.result.get(1).filter_attr
+ total_count = cls.result.get(1).query.limit(None).offset(None).count()
+ total_page_number = cls.get_total_count(cls_object, filter_attributes)
+ pagination_dict = {
+ "size/total_count": [filter_attributes.size, cls_object.total_count],
+ "page/total_page": [filter_attributes.page, total_page_number],
+ "order_field": filter_attributes.order_field,
+ "order_type": filter_attributes.order_type,
+ }
+ include_joins = dict(
+ include_joins=(
+ filter_attributes.include_joins
+ if filter_attributes.include_joins
+ else []
+ )
+ )
+ data = []
+ for data_object in cls.result.data:
+ data_dict = data_object.get_dict(include_joins=include_joins)
+ if cls.response_model:
+ data_dict = cls.response_model(
+ **data_object.get_dict(include_joins=include_joins)
+ ).dump()
+ data.append(data_dict)
+ return JSONResponse(
+ status_code=cls.status_code,
+ content=dict(
+ total_count=total_count or 1,
+ count=cls.result.count,
+ pagination=pagination_dict,
+ message=cls.message,
+ completed=cls.completed,
+ data=data,
+ ),
+ )
diff --git a/ApiServices/local-docker-compose.yml b/ApiServices/local-docker-compose.yml
deleted file mode 100644
index 7caf323..0000000
--- a/ApiServices/local-docker-compose.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-services:
-
- wag_management_auth_service:
- container_name: wag_management_auth_service
- restart: on-failure
- build:
- context: .
- dockerfile: AuthService/Dockerfile
- ports:
- - "11:41575"
-
- wag_management_event_service:
- container_name: wag_management_event_service
- restart: on-failure
- build:
- context: .
- dockerfile: EventService/Dockerfile
- ports:
- - "12:41575"
-
- wag_management_validation_service:
- container_name: wag_management_validation_service
- restart: on-failure
- build:
- context: .
- dockerfile: ValidationService/Dockerfile
- ports:
- - "13:41575"
-
diff --git a/README.md b/README.md
index 8872145..5ebb4cb 100644
--- a/README.md
+++ b/README.md
@@ -12,11 +12,11 @@ On Linux
Connectors:
commercial_main_mongo_service:
-http://localhost:11777
+http://10.10.2.36:11777
commercial_main_memory_service:
-http://localhost:11222
+http://10.10.2.36:11222
postgres_main_commercial:
-http://localhost:5444
+http://10.10.2.36:5444
make sure
set lang and timezone on login
@@ -24,5 +24,12 @@ BaseMixin || CrudMixin add
http_exception = fastapi.HTTPException
status = fastapi.status
+On debian
+> docker compose -f ./ApiServices/debian-docker-compose.yml up --build -d
+On Linux
+> docker compose -f ./ApiServices/local-docker-compose.yml up --build -d
+> http://localhost:1111/docs | wag_management_auth_service
+> http://localhost:1112/docs | wag_management_event_service
+> http://localhost:1113/docs | wag_management_validation_service
diff --git a/a_project_files/later_use_codes/authentication.py b/a_project_files/later_use_codes/authentication.py
index 567fab3..439f713 100644
--- a/a_project_files/later_use_codes/authentication.py
+++ b/a_project_files/later_use_codes/authentication.py
@@ -47,7 +47,6 @@ from api_configs import ApiStatic, Auth
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
-from api_validations.core_response import AlchemyJsonResponse
class AuthenticationLoginEventMethods(MethodToEvent):
diff --git a/a_project_files/later_use_codes/events_bind_events.py b/a_project_files/later_use_codes/events_bind_events.py
index 4a4d207..c146b51 100644
--- a/a_project_files/later_use_codes/events_bind_events.py
+++ b/a_project_files/later_use_codes/events_bind_events.py
@@ -15,7 +15,6 @@ from databases import (
from api_validations.validations_request import RegisterEvents2Occupant
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
-from api_validations.core_response import AlchemyJsonResponse
class EventBindOccupantEventMethods(MethodToEvent):
diff --git a/ApiServices/debian-docker-compose.yml b/api-docker-compose.yml
similarity index 62%
rename from ApiServices/debian-docker-compose.yml
rename to api-docker-compose.yml
index 7caf323..2619739 100644
--- a/ApiServices/debian-docker-compose.yml
+++ b/api-docker-compose.yml
@@ -2,28 +2,28 @@ services:
wag_management_auth_service:
container_name: wag_management_auth_service
- restart: on-failure
+# restart: on-failure
build:
context: .
- dockerfile: AuthService/Dockerfile
+ dockerfile: ApiServices/AuthService/Dockerfile
ports:
- - "11:41575"
+ - "1111:41575"
wag_management_event_service:
container_name: wag_management_event_service
restart: on-failure
build:
context: .
- dockerfile: EventService/Dockerfile
+ dockerfile: ApiServices/EventService/Dockerfile
ports:
- - "12:41575"
+ - "1112:41575"
wag_management_validation_service:
container_name: wag_management_validation_service
restart: on-failure
build:
context: .
- dockerfile: ValidationService/Dockerfile
+ dockerfile: ApiServices/ValidationService/Dockerfile
ports:
- - "13:41575"
+ - "1113:41575"
diff --git a/api_configs/__init__.py b/api_configs/__init__.py
index 5d667a6..46e7b4e 100644
--- a/api_configs/__init__.py
+++ b/api_configs/__init__.py
@@ -1,29 +1,47 @@
-from api_configs.configs import (
- Config,
- ApiStatic,
- Auth,
+from .databaseConfigs import (
WagDatabase,
WagRedis,
- TestRedis,
- HagRedis,
MongoConfig,
- TestMongo,
- RelationAccess,
+
+)
+from .emailConfigs import (
EmailConfig,
- TestDatabase,
+)
+from .configs import (
+ Config,
)
__all__ = [
- "Config",
- "ApiStatic",
- "Auth",
"WagDatabase",
"WagRedis",
- "TestRedis",
- "HagRedis",
"MongoConfig",
- "TestMongo",
- "RelationAccess",
"EmailConfig",
- "TestDatabase",
+ "Config",
]
+
+# from api_configs.configs import (
+# Config,
+# ApiStatic,
+# Auth,
+# WagDatabase,
+# WagRedis,
+# TestRedis,
+# HagRedis,
+# MongoConfig,
+# TestMongo,
+# RelationAccess,
+# EmailConfig,
+# TestDatabase,
+# )
+# "Config",
+# "ApiStatic",
+# "Auth",
+# "WagDatabase",
+# "WagRedis",
+# "TestRedis",
+# "HagRedis",
+# "MongoConfig",
+# "TestMongo",
+# "RelationAccess",
+# "EmailConfig",
+# "TestDatabase",
\ No newline at end of file
diff --git a/api_configs/databaseConfigs.py b/api_configs/databaseConfigs.py
index c930eb4..5ef24b6 100644
--- a/api_configs/databaseConfigs.py
+++ b/api_configs/databaseConfigs.py
@@ -1,3 +1,5 @@
+
+
storeHost = "10.10.2.36"
diff --git a/api_configs/emailConfigs.py b/api_configs/emailConfigs.py
new file mode 100644
index 0000000..3cc27aa
--- /dev/null
+++ b/api_configs/emailConfigs.py
@@ -0,0 +1,6 @@
+
+
+class EmailConfig:
+ EMAIL_HOST: str = "10.10.2.34"
+ EMAIL_USERNAME: str = "karatay@mehmetkaratay.com.tr"
+ EMAIL_PASSWORD: str = "system"
diff --git a/api_events/__init__.py b/api_events/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/__init__.py b/api_events/events/__init__.py
new file mode 100644
index 0000000..415a028
--- /dev/null
+++ b/api_events/events/__init__.py
@@ -0,0 +1,291 @@
+from api_events.events.identity.people import (
+ PeopleListEventMethod,
+ PeopleCreateEventMethod,
+ PeopleUpdateEventMethod,
+ PeoplePatchEventMethod,
+)
+from api_events.events.address.address import (
+ AddressListEventMethod,
+ AddressCreateEventMethod,
+ AddressUpdateEventMethod,
+ AddressPatchEventMethod,
+ AddressSearchEventMethod,
+ AddressPostCodeCreateEventMethod,
+ AddressPostCodeUpdateEventMethod,
+ AddressPostCodeListEventMethod,
+)
+from api_events.events.application.authentication import (
+ AuthenticationLoginEventMethod,
+ AuthenticationSelectEventMethod,
+ AuthenticationCheckTokenEventMethod,
+ AuthenticationRefreshEventMethod,
+ AuthenticationChangePasswordEventMethod,
+ AuthenticationCreatePasswordEventMethod,
+ AuthenticationResetPasswordEventMethod,
+ AuthenticationDisconnectUserEventMethod,
+ AuthenticationLogoutEventMethod,
+ AuthenticationRefreshTokenEventMethod,
+ AuthenticationForgotPasswordEventMethod,
+ AuthenticationDownloadAvatarEventMethod,
+)
+from api_events.events.account.account_records import (
+ AccountRecordsListEventMethod,
+ AccountRecordsCreateEventMethod,
+ AccountRecordsUpdateEventMethod,
+ AccountRecordsPatchEventMethod,
+)
+from api_events.events.identity.users import (
+ UserListEventMethod,
+ UserCreateEventMethod,
+ UserUpdateEventMethod,
+ UserPatchEventMethod,
+)
+from api_events.events.building.building_build import (
+ BuildListEventMethod,
+ BuildCreateEventMethod,
+ BuildUpdateEventMethod,
+ BuildPatchEventMethod,
+)
+from api_events.events.building.building_build_parts import (
+ BuildingBuildPartsListEventMethod,
+ BuildingBuildPartsCreateEventMethod,
+ BuildingBuildPartsUpdateEventMethod,
+ BuildingBuildPartsPatchEventMethod,
+)
+from api_events.events.building.building_build_area import (
+ BuildAreaListEventMethod,
+ BuildAreaCreateEventMethod,
+ BuildAreaUpdateEventMethod,
+ BuildAreaPatchEventMethod,
+)
+from api_events.events.building.building_build_sites import (
+ BuildSitesListEventMethod,
+ BuildSitesCreateEventMethod,
+ BuildSitesUpdateEventMethod,
+)
+from api_events.events.building.building_build_types import (
+ BuildTypesListEventMethod,
+)
+from api_events.events.company.company_company import (
+ CompanyListEventMethod,
+ CompanyCreateEventMethod,
+ CompanyUpdateEventMethod,
+ CompanyPatchEventMethod,
+)
+from api_events.events.company.company_department import (
+ DepartmentListEventMethod,
+ DepartmentCreateEventMethod,
+ DepartmentUpdateEventMethod,
+ DepartmentPatchEventMethod,
+)
+from api_events.events.company.company_duties import (
+ DutiesListEventMethod,
+ DutiesGetByUUIDEventMethod,
+ DutiesCreateEventMethod,
+ DutiesUpdateEventMethod,
+ DutiesPatchEventMethod,
+)
+from api_events.events.company.company_duty import (
+ DutyListEventMethod,
+ DutyCreateEventMethod,
+ DutyUpdateEventMethod,
+ DutyPatchEventMethod,
+)
+from api_events.events.company.company_employee import (
+ EmployeeListEventMethod,
+ EmployeeCreateEventMethod,
+ EmployeeUpdateEventMethod,
+ EmployeePatchEventMethod,
+ Employee2PeopleEmployEventMethod,
+ Employee2PeopleFireEventMethod,
+)
+from api_events.events.company.company_staff import (
+ StaffListEventMethod,
+ StaffCreateEventMethod,
+ StaffGetByUUIDEventMethod,
+ StaffUpdateEventMethod,
+ StaffPatchEventMethod,
+)
+from api_events.events.building.building_living_spaces import (
+ BuildingLivingSpacesListEventMethod,
+ BuildingLivingSpacesCreateEventMethod,
+ BuildingLivingSpacesUpdateEventMethod,
+)
+from api_events.events.decision_book.decision_book_decision_book import (
+ DecisionBookListEventMethod,
+ DecisionBookCreateEventMethod,
+ DecisionBookUpdateEventMethod,
+ DecisionBookPatchEventMethod,
+ DecisionBookApprovalEventMethod,
+)
+from api_events.events.decision_book.decision_book_decision_book_items import (
+ DecisionBookDecisionBookItemsListEventMethod,
+ DecisionBookDecisionBookItemsCreateEventMethod,
+ DecisionBookDecisionBookItemsUpdateEventMethod,
+ DecisionBookDecisionBookItemsPatchEventMethod,
+)
+from api_events.events.decision_book.project_decision_book import (
+ ProjectDecisionBookListEventMethod,
+ ProjectDecisionBookCreateEventMethod,
+ ProjectDecisionBookUpdateEventMethod,
+ ProjectDecisionBookApprovalEventMethod,
+ ProjectDecisionBookPatchEventMethod,
+)
+from api_events.events.decision_book.project_decision_book_person import (
+ ProjectDecisionBookPersonListEventMethod,
+ ProjectDecisionBookPersonCreateEventMethod,
+ ProjectDecisionBookPersonUpdateEventMethod,
+ ProjectDecisionBookPersonPatchEventMethod,
+)
+from api_events.events.decision_book.project_decision_book_items import (
+ BuildDecisionBookProjectItemsPatchEventMethod,
+ BuildDecisionBookProjectItemsUpdateEventMethod,
+ BuildDecisionBookProjectItemsCreateEventMethod,
+ BuildDecisionBookProjectItemsListEventMethod,
+)
+
+# from api_events.events.events.events_ import (
+# EventBindOccupantEventMethod,
+# EventBindEmployeeEventMethod,
+# )
+from api_events.events.events.events_bind_services import (
+ ServiceBindOccupantEventMethod,
+ ServiceBindEmployeeEventMethod,
+)
+from api_events.events.decision_book.decision_book_decision_book_person import (
+ DecisionBookPersonListEventMethod,
+ DecisionBookPersonAddEventMethod,
+ DecisionBookPersonRemoveEventMethod,
+ DecisionBookPersonAttendEventMethod,
+ DecisionBookPersonAssignOccupantEventMethod,
+)
+from api_events.events.decision_book.decision_book_invitations import (
+ BuildDecisionBookInvitationsListEventMethod,
+ BuildDecisionBookInvitationsCreateEventMethod,
+ BuildDecisionBookInvitationsUpdateEventMethod,
+)
+from api_events.events.events.events_events import (
+ EventsBindEventToEmployeeMethod,
+ EventsBindEventToOccupantMethod,
+ EventsListEventMethod,
+)
+
+
+__all__ = [
+ "AddressListEventMethod",
+ "AddressCreateEventMethod",
+ "AddressUpdateEventMethod",
+ "AddressPatchEventMethod",
+ "AddressSearchEventMethod",
+ "AddressPostCodeCreateEventMethod",
+ "AddressPostCodeUpdateEventMethod",
+ "AddressPostCodeListEventMethod",
+ "PeopleListEventMethod",
+ "PeopleUpdateEventMethod",
+ "PeoplePatchEventMethod",
+ "PeopleCreateEventMethod",
+ "AuthenticationLoginEventMethod",
+ "AuthenticationSelectEventMethod",
+ "AuthenticationCheckTokenEventMethod",
+ "AuthenticationRefreshEventMethod",
+ "AuthenticationChangePasswordEventMethod",
+ "AuthenticationCreatePasswordEventMethod",
+ "AuthenticationResetPasswordEventMethod",
+ "AuthenticationDisconnectUserEventMethod",
+ "AuthenticationLogoutEventMethod",
+ "AuthenticationRefreshTokenEventMethod",
+ "AuthenticationForgotPasswordEventMethod",
+ "AuthenticationDownloadAvatarEventMethod",
+ "AccountRecordsListEventMethod",
+ "AccountRecordsCreateEventMethod",
+ "AccountRecordsUpdateEventMethod",
+ "AccountRecordsPatchEventMethod",
+ "UserListEventMethod",
+ "UserCreateEventMethod",
+ "UserUpdateEventMethod",
+ "UserPatchEventMethod",
+ "BuildListEventMethod",
+ "BuildCreateEventMethod",
+ "BuildUpdateEventMethod",
+ "BuildPatchEventMethod",
+ "BuildingBuildPartsListEventMethod",
+ "BuildingBuildPartsCreateEventMethod",
+ "BuildingBuildPartsUpdateEventMethod",
+ "BuildingBuildPartsPatchEventMethod",
+ "BuildingLivingSpacesListEventMethod",
+ "BuildingLivingSpacesCreateEventMethod",
+ "BuildingLivingSpacesUpdateEventMethod",
+ "BuildAreaListEventMethod",
+ "BuildAreaCreateEventMethod",
+ "BuildAreaUpdateEventMethod",
+ "BuildAreaPatchEventMethod",
+ "BuildSitesListEventMethod",
+ "BuildSitesCreateEventMethod",
+ "BuildSitesUpdateEventMethod",
+ "BuildTypesListEventMethod",
+ "DecisionBookListEventMethod",
+ "DecisionBookCreateEventMethod",
+ "DecisionBookUpdateEventMethod",
+ "DecisionBookPatchEventMethod",
+ "DecisionBookApprovalEventMethod",
+ "DecisionBookPersonListEventMethod",
+ "DecisionBookPersonAddEventMethod",
+ "DecisionBookPersonRemoveEventMethod",
+ "DecisionBookDecisionBookItemsListEventMethod",
+ "DecisionBookDecisionBookItemsCreateEventMethod",
+ "DecisionBookDecisionBookItemsUpdateEventMethod",
+ "DecisionBookDecisionBookItemsPatchEventMethod",
+ "ProjectDecisionBookListEventMethod",
+ "ProjectDecisionBookCreateEventMethod",
+ "ProjectDecisionBookUpdateEventMethod",
+ "ProjectDecisionBookApprovalEventMethod",
+ "ProjectDecisionBookPatchEventMethod",
+ "ProjectDecisionBookPersonListEventMethod",
+ "ProjectDecisionBookPersonCreateEventMethod",
+ "ProjectDecisionBookPersonUpdateEventMethod",
+ "ProjectDecisionBookPersonPatchEventMethod",
+ "BuildDecisionBookProjectItemsPatchEventMethod",
+ "BuildDecisionBookProjectItemsUpdateEventMethod",
+ "BuildDecisionBookProjectItemsCreateEventMethod",
+ "BuildDecisionBookProjectItemsListEventMethod",
+ "CompanyPatchEventMethod",
+ "CompanyCreateEventMethod",
+ "CompanyUpdateEventMethod",
+ "CompanyListEventMethod",
+ "DepartmentListEventMethod",
+ "DepartmentCreateEventMethod",
+ "DepartmentUpdateEventMethod",
+ "DepartmentPatchEventMethod",
+ "DutiesListEventMethod",
+ "DutiesGetByUUIDEventMethod",
+ "DutiesCreateEventMethod",
+ "DutiesUpdateEventMethod",
+ "DutiesPatchEventMethod",
+ "DutyListEventMethod",
+ "DutyCreateEventMethod",
+ "DutyUpdateEventMethod",
+ "DutyPatchEventMethod",
+ "EmployeeListEventMethod",
+ "EmployeeCreateEventMethod",
+ "EmployeeUpdateEventMethod",
+ "EmployeePatchEventMethod",
+ "Employee2PeopleEmployEventMethod",
+ "Employee2PeopleFireEventMethod",
+ "StaffListEventMethod",
+ "StaffCreateEventMethod",
+ "StaffGetByUUIDEventMethod",
+ "StaffUpdateEventMethod",
+ "StaffPatchEventMethod",
+ # "EventBindOccupantEventMethod",
+ # "EventBindEmployeeEventMethod",
+ "ServiceBindOccupantEventMethod",
+ "ServiceBindEmployeeEventMethod",
+ "BuildDecisionBookInvitationsListEventMethod",
+ "BuildDecisionBookInvitationsCreateEventMethod",
+ "BuildDecisionBookInvitationsUpdateEventMethod",
+ "DecisionBookPersonAttendEventMethod",
+ "DecisionBookPersonAssignOccupantEventMethod",
+ "EventsBindEventToEmployeeMethod",
+ "EventsBindEventToOccupantMethod",
+ "EventsListEventMethod",
+]
diff --git a/api_events/events/abstract_class.py b/api_events/events/abstract_class.py
new file mode 100644
index 0000000..e2c8a16
--- /dev/null
+++ b/api_events/events/abstract_class.py
@@ -0,0 +1,72 @@
+import typing
+from abc import ABC
+from fastapi.exceptions import HTTPException
+
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+
+
+class ActionsSchema(ABC):
+
+ def __init__(self, endpoint: str = None):
+ self.endpoint = endpoint
+
+ def retrieve_action_from_endpoint(self):
+ from databases import EndpointRestriction
+
+ endpoint_restriction = EndpointRestriction.filter_one(
+ EndpointRestriction.endpoint_name.ilike(f"%{self.endpoint}%"), system=True
+ ).data
+ if not endpoint_restriction:
+ raise HTTPException(
+ status_code=404,
+ detail=f"Endpoint {self.endpoint} not found in the database",
+ )
+ return endpoint_restriction
+
+
+class ActionsSchemaFactory:
+
+ def __init__(self, action: ActionsSchema):
+ self.action = action
+ try:
+ self.action_match = self.action.retrieve_action_from_endpoint()
+ except Exception as e:
+ err = e
+ print(f"ActionsSchemaFactory Error: {e}")
+
+
+class MethodToEvent(ABC, ActionsSchemaFactory):
+
+ action_key: str = None
+ event_type: str = None
+ event_description: str = ""
+ event_category: str = ""
+
+ __event_keys__: dict = {}
+ __event_validation__: dict = {}
+
+ @classmethod
+ def call_event_method(cls, method_uu_id: str, *args, **kwargs):
+ function_name = cls.__event_keys__.get(method_uu_id)
+ return getattr(cls, function_name)(*args, **kwargs)
+
+ @classmethod
+ def ban_token_objects(
+ cls,
+ token: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ban_list: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ from fastapi import status
+ from fastapi.exceptions import HTTPException
+
+ if token.user_type == ban_list.user_type:
+ if isinstance(token, EmployeeTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_406_NOT_ACCEPTABLE,
+ detail="No employee can reach this event. An notification is send to admin about event registration",
+ )
+ if isinstance(token, OccupantTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_406_NOT_ACCEPTABLE,
+ detail="No occupant can reach this event. An notification is send to admin about event registration",
+ )
diff --git a/api_events/events/account/__init__.py b/api_events/events/account/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/account/account_records.py b/api_events/events/account/account_records.py
new file mode 100644
index 0000000..a7d6fa0
--- /dev/null
+++ b/api_events/events/account/account_records.py
@@ -0,0 +1,347 @@
+import typing
+
+from api_library.date_time_actions.date_functions import system_arrow
+from api_validations.validations_request import (
+ InsertAccountRecord,
+ UpdateAccountRecord,
+ ListOptions,
+)
+
+from api_validations.core_response import AlchemyJsonResponse
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.validations_response.account import AccountListResponse
+from databases import (
+ AccountRecords,
+ BuildIbans,
+)
+from databases.sql_models.building.build import Build, BuildLivingSpace
+from databases.sql_models.building.decision_book import BuildDecisionBookPayments
+from databases.sql_models.others.enums import ApiEnumDropdown
+
+
+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": AccountListResponse,
+ "208e6273-17ef-44f0-814a-8098f816b63a": AccountListResponse,
+ }
+
+ @classmethod
+ def account_records_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ AccountRecords.pre_query = AccountRecords.filter_all(
+ AccountRecords.company_id
+ == token_dict.selected_occupant.responsible_company_id,
+ )
+ elif isinstance(token_dict, EmployeeTokenObject):
+ AccountRecords.pre_query = AccountRecords.filter_all(
+ AccountRecords.company_id == token_dict.selected_company.company_id,
+ )
+ AccountRecords.filter_attr = list_options
+ records = AccountRecords.filter_all()
+ return AlchemyJsonResponse(
+ completed=True, message="List Build record", result=records
+ )
+
+ @classmethod
+ def account_records_list_flt_res(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ 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 dict(completed=True, message="List Build record", result=return_list)
+
+
+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):
+ build_iban = BuildIbans.filter_one(
+ BuildIbans.iban == data.iban,
+ BuildIbans.build_id == token_dict.selected_occupant.build_id,
+ ).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,
+ },
+ )
+ account_record = AccountRecords.find_or_create(**data.excluded_dump())
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Update Build record",
+ result=account_record.get_dict(),
+ )
+ 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.find_or_create(**data_dict)
+ account_record.save()
+ account_record.update(is_confirmed=True)
+ account_record.save()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Create Account record are successful",
+ result=account_record.get_dict(),
+ )
+
+
+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
+
+ return AlchemyJsonResponse(
+ completed=False,
+ message="Update Build record",
+ result=None,
+ )
+
+
+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],
+ ):
+ return AlchemyJsonResponse(
+ completed=False,
+ message="Patch Build record",
+ result=None,
+ )
+
+
+AccountRecordsListEventMethod = AccountRecordsListEventMethods(
+ action=ActionsSchema(endpoint="/account/records/list")
+)
+AccountRecordsCreateEventMethod = AccountRecordsCreateEventMethods(
+ action=ActionsSchema(endpoint="/account/records/create")
+)
+AccountRecordsUpdateEventMethod = AccountRecordsUpdateEventMethods(
+ action=ActionsSchema(endpoint="/account/records/update")
+)
+AccountRecordsPatchEventMethod = AccountRecordsPatchEventMethods(
+ action=ActionsSchema(endpoint="/account/records/patch")
+)
diff --git a/api_events/events/address/__init__.py b/api_events/events/address/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/address/address.py b/api_events/events/address/address.py
new file mode 100644
index 0000000..0e290d6
--- /dev/null
+++ b/api_events/events/address/address.py
@@ -0,0 +1,499 @@
+from typing import Union
+
+from fastapi.exceptions import HTTPException
+from fastapi.responses import JSONResponse
+
+from api_validations.validations_response.address import (
+ ListAddressResponse,
+ AddressPostCodeResponse,
+)
+from databases import (
+ AddressPostcode,
+ Addresses,
+ RelationshipEmployee2PostCode,
+ AddressStreet,
+)
+
+from api_validations.validations_request import (
+ ListOptions,
+ InsertAddress,
+ UpdateAddress,
+ InsertPostCode,
+ UpdatePostCode,
+ SearchAddress,
+)
+from api_validations.core_response import AlchemyJsonResponse
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+
+
+class AddressListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ event_description = "List Address records"
+ event_category = "Address"
+
+ __event_keys__ = {
+ "9c251d7d-da70-4d63-a72c-e69c26270442": "address_list_super_user",
+ "52afe375-dd95-4f4b-aaa2-4ec61bc6de52": "address_list_employee",
+ }
+ __event_validation__ = {
+ "9c251d7d-da70-4d63-a72c-e69c26270442": ListAddressResponse,
+ "52afe375-dd95-4f4b-aaa2-4ec61bc6de52": ListAddressResponse,
+ }
+
+ @classmethod
+ def address_list_super_user(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ post_code_list = RelationshipEmployee2PostCode.filter_all(
+ RelationshipEmployee2PostCode.company_id
+ == token_dict.selected_company.company_id,
+ ).data
+ post_code_id_list = [post_code.member_id for post_code in post_code_list]
+ if not post_code_id_list:
+ raise HTTPException(
+ status_code=404,
+ detail="User has no post code registered. User can not list addresses.",
+ )
+ get_street_ids = [
+ street_id[0]
+ for street_id in AddressPostcode.select_only(
+ AddressPostcode.id.in_(post_code_id_list),
+ select_args=[AddressPostcode.street_id],
+ order_by=AddressPostcode.street_id.desc(),
+ ).data
+ ]
+ if not get_street_ids:
+ raise HTTPException(
+ status_code=404,
+ detail="User has no street registered. User can not list addresses.",
+ )
+ Addresses.pre_query = Addresses.filter_all(
+ Addresses.street_id.in_(get_street_ids),
+ ).query
+ Addresses.filter_attr = list_options
+ records = Addresses.filter_all().data
+ return AlchemyJsonResponse(
+ completed=True,
+ message="List Address records",
+ result=records,
+ )
+
+ @classmethod
+ def address_list_employee(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ Addresses.filter_attr = list_options
+ records = Addresses.list_via_employee(
+ token_dict=token_dict,
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="List Address records",
+ result=records,
+ )
+
+
+class AddressCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "ffdc445f-da10-4ce4-9531-d2bdb9a198ae": "create_address",
+ }
+ __event_validation__ = {
+ "ffdc445f-da10-4ce4-9531-d2bdb9a198ae": InsertAddress,
+ }
+
+ @classmethod
+ def create_address(
+ cls,
+ data: InsertAddress,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ post_code = AddressPostcode.filter_one(
+ AddressPostcode.uu_id == data.post_code_uu_id,
+ ).data
+ if not post_code:
+ raise HTTPException(
+ status_code=404,
+ detail="Post code not found. User can not create address without post code.",
+ )
+
+ data_dict = data.excluded_dump()
+ data_dict["street_id"] = post_code.street_id
+ data_dict["street_uu_id"] = str(post_code.street_uu_id)
+ del data_dict["post_code_uu_id"]
+ address = Addresses.find_or_create(**data_dict)
+ address.save()
+ address.update(is_confirmed=True)
+ address.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Address record",
+ "data": address.get_dict(),
+ },
+ status_code=200,
+ )
+
+
+class AddressSearchEventMethods(MethodToEvent):
+
+ event_type = "SEARCH"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "e0ac1269-e9a7-4806-9962-219ac224b0d0": "search_address",
+ }
+ __event_validation__ = {
+ "e0ac1269-e9a7-4806-9962-219ac224b0d0": SearchAddress,
+ }
+
+ @classmethod
+ def search_address(
+ cls,
+ data: SearchAddress,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ import databases.sql_models
+ from time import perf_counter
+
+ st = perf_counter()
+
+ pre_query_first = AddressStreet.search_address_text(search_text=data.search)
+ query, schemas, new_data_list = (
+ pre_query_first.get("query"),
+ pre_query_first.get("schema"),
+ [],
+ )
+ filter_list = data.list_options.dump()
+ filter_table = AddressStreet
+ if filter_list.get("order_field") not in schemas:
+ filter_list["order_field"] = "uu_id"
+ else:
+ filter_table = getattr(
+ databases.sql_models, str(filter_list.get("order_field")).split(".")[0]
+ )
+ filter_list["order_field"] = str(filter_list.get("order_field")).split(".")[
+ 1
+ ]
+
+ order = (
+ getattr(filter_table, filter_list.get("order_field")).desc()
+ if str(filter_list.get("order_type"))[0] == "d"
+ else getattr(filter_table, filter_list.get("order_field")).asc()
+ )
+
+ query = (
+ query.order_by(order)
+ .limit(int(filter_list.get("size")))
+ .offset(int((filter_list.get("page")) - 1) * int(filter_list.get("size")))
+ .populate_existing()
+ )
+
+ records = list(query.all())
+ print(perf_counter() - st)
+
+ for item in records:
+ new_data_dict = {}
+ for index, schema in enumerate(schemas):
+ new_data_dict[schema] = str(item[index])
+ if "uu_id" in str(item[index]):
+ new_data_dict[schema] = str(new_data_dict.get(schema))
+ new_data_list.append(new_data_dict)
+
+ return JSONResponse(
+ content={
+ "completed": True,
+ "pagination": filter_list,
+ "count": len(new_data_list),
+ "data": new_data_list,
+ "message": "Search Address records",
+ },
+ status_code=200,
+ )
+
+
+class AddressUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27": "update_address",
+ }
+ __event_validation__ = {
+ "1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27": UpdateAddress,
+ }
+
+ @classmethod
+ def update_address(
+ cls,
+ address_uu_id: str,
+ data: UpdateAddress,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ address = Addresses.filter_one(
+ Addresses.uu_id == address_uu_id,
+ ).data
+ if not address:
+ raise HTTPException(
+ status_code=404,
+ detail=f"Address not found. User can not update with given address uuid : {address_uu_id}",
+ )
+
+ data_dict = data.excluded_dump()
+ updated_address = address.update(**data_dict)
+ updated_address.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Address record",
+ "data": updated_address.get_dict(),
+ },
+ status_code=200,
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ raise HTTPException(
+ status_code=403,
+ detail="Occupant can not update address.",
+ )
+
+
+class AddressPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d": "patch_address",
+ }
+ __event_validation__ = {
+ "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d": None,
+ }
+
+ @classmethod
+ def patch_address(
+ cls,
+ address_uu_id: str,
+ data: InsertAddress,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ address = Addresses.filter_one(
+ Addresses.uu_id == address_uu_id,
+ ).data
+ post_code = RelationshipEmployee2PostCode.filter_one(
+ RelationshipEmployee2PostCode.member_id == address.post_code_id,
+ )
+ if not post_code:
+ raise HTTPException(
+ status_code=404,
+ detail="Post code not found. User can not patch address without post code.",
+ )
+
+ data_dict = data.excluded_dump()
+ data_dict["post_code_id"] = post_code.id
+ del data_dict["post_code_uu_id"]
+
+ patched_address = address.patch(**data_dict)
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Patch Address record",
+ "data": patched_address.get_dict(),
+ },
+ status_code=200,
+ )
+
+
+class AddressPostCodeCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "6f1406ac-577d-4f2c-8077-71fff2252c5f": "create_post_code_address",
+ }
+ __event_validation__ = {
+ "6f1406ac-577d-4f2c-8077-71fff2252c5f": InsertPostCode,
+ }
+
+ @classmethod
+ def create_post_code_address(
+ cls,
+ data: InsertPostCode,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ data_dump = data.excluded_dump()
+ street = AddressStreet.filter_one(
+ AddressStreet.uu_id == data.street_uu_id,
+ ).data
+ if not street:
+ raise HTTPException(
+ status_code=404,
+ detail="Street not found. User can not create post code without street.",
+ )
+ data_dump["street_id"] = street.id
+ data_dump["postcode"] = data.post_code
+ del data_dump["post_code"]
+
+ post_code = AddressPostcode.find_or_create(**data_dump)
+ relation_table = AddressPostcode.__many__table__.find_or_create(
+ member_id=post_code.id,
+ employee_id=token_dict.selected_company.employee_id,
+ company_id=token_dict.selected_company.company_id,
+ )
+ post_code.save()
+ post_code.update(is_confirmed=True)
+ post_code.save()
+ relation_table.update(is_confirmed=True)
+ relation_table.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Post Code record",
+ "data": post_code.get_dict(),
+ },
+ status_code=200,
+ )
+
+
+class AddressPostCodeUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "df18e489-a63c-477f-984c-aa52d30640ad": "update_post_code_address",
+ }
+ __event_validation__ = {
+ "df18e489-a63c-477f-984c-aa52d30640ad": UpdatePostCode,
+ }
+
+ @classmethod
+ def update_post_code_address(
+ cls,
+ post_code_uu_id: str,
+ data: UpdatePostCode,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ AddressPostcode.pre_query = AddressPostcode.select_action(
+ employee_id=token_dict.selected_company.employee_id,
+ )
+ post_code = AddressPostcode.filter_one(
+ AddressPostcode.uu_id == post_code_uu_id,
+ ).data
+ if not post_code:
+ raise HTTPException(
+ status_code=404,
+ detail="Street not found. User can not update post code without street.",
+ )
+
+ data_dict = data.excluded_dump()
+ updated_post_code = post_code.update(**data_dict)
+ updated_post_code.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Post Code record",
+ "data": updated_post_code.get_dict(),
+ },
+ status_code=200,
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ raise HTTPException(
+ status_code=403,
+ detail="Occupant can not update post code.",
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Post Code record",
+ "data": {},
+ },
+ status_code=404,
+ )
+
+
+class AddressPostCodeListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "88d37b78-1ac4-4513-9d25-090ac3a24f31": "list_post_code_address",
+ }
+ __event_validation__ = {
+ "88d37b78-1ac4-4513-9d25-090ac3a24f31": AddressPostCodeResponse,
+ }
+
+ @classmethod
+ def list_post_code_address(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ post_code_list = AddressPostcode.__many__table__.filter_all(
+ AddressPostcode.__many__table__.company_id
+ == token_dict.selected_company.company_id,
+ ).data
+ if not post_code_list:
+ raise HTTPException(
+ status_code=404,
+ detail="User has no post code registered or not yet any post code created.",
+ )
+
+ AddressPostcode.pre_query = AddressPostcode.filter_all(
+ AddressPostcode.id.in_(
+ [post_code.member_id for post_code in post_code_list]
+ ),
+ ).query
+ AddressPostcode.filter_attr = list_options
+ records = AddressPostcode.filter_all().data
+ return AlchemyJsonResponse(
+ completed=True,
+ message="List Address records",
+ result=records,
+ )
+
+
+AddressListEventMethod = AddressListEventMethods(
+ action=ActionsSchema(endpoint="/address/list")
+)
+AddressCreateEventMethod = AddressCreateEventMethods(
+ action=ActionsSchema(endpoint="/address/create")
+)
+AddressUpdateEventMethod = AddressUpdateEventMethods(
+ action=ActionsSchema(endpoint="/address/update")
+)
+AddressPatchEventMethod = AddressPatchEventMethods(
+ action=ActionsSchema(endpoint="/address/patch")
+)
+AddressPostCodeCreateEventMethod = AddressPostCodeCreateEventMethods(
+ action=ActionsSchema(endpoint="/postcode/create")
+)
+AddressPostCodeUpdateEventMethod = AddressPostCodeUpdateEventMethods(
+ action=ActionsSchema(endpoint="/postcode/update")
+)
+AddressPostCodeListEventMethod = AddressPostCodeListEventMethods(
+ action=ActionsSchema(endpoint="/postcode/list")
+)
+AddressSearchEventMethod = AddressSearchEventMethods(
+ action=ActionsSchema(endpoint="/address/search")
+)
diff --git a/api_events/events/application/__init__.py b/api_events/events/application/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/application/api.py b/api_events/events/application/api.py
new file mode 100644
index 0000000..d250455
--- /dev/null
+++ b/api_events/events/application/api.py
@@ -0,0 +1,5 @@
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+
+
+class DecisionBookEvents(MethodToEvent): ...
diff --git a/api_events/events/application/application.py b/api_events/events/application/application.py
new file mode 100644
index 0000000..9dbf257
--- /dev/null
+++ b/api_events/events/application/application.py
@@ -0,0 +1,5 @@
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+
+
+class ApplicationEvents(MethodToEvent): ...
diff --git a/api_events/events/application/authentication.py b/api_events/events/application/authentication.py
new file mode 100644
index 0000000..c7fbf40
--- /dev/null
+++ b/api_events/events/application/authentication.py
@@ -0,0 +1,844 @@
+import datetime
+import json
+import typing
+from typing import Union
+
+import arrow
+from fastapi import status
+from fastapi.requests import Request
+from fastapi.exceptions import HTTPException
+from fastapi.responses import JSONResponse
+
+from databases import (
+ Companies,
+ Staff,
+ Duties,
+ Departments,
+ Employees,
+ BuildLivingSpace,
+ BuildParts,
+ Build,
+ Duty,
+ Event2Occupant,
+ Event2Employee,
+ Users,
+ UsersTokens,
+ OccupantTypes,
+ RelationshipEmployee2Build,
+)
+
+from api_services import (
+ redis_cli,
+ send_email,
+ get_object_via_access_key,
+ get_object_via_user_uu_id,
+ save_access_token_to_redis,
+ update_selected_to_redis,
+ password_is_changed_template,
+ change_your_password_template,
+)
+
+from api_configs import ApiStatic, Auth
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects import (
+ OccupantToken,
+ CompanyToken,
+ EmployeeTokenObject,
+ OccupantTokenObject,
+)
+from api_library.date_time_actions.date_functions import system_arrow
+
+from databases.no_sql_models.login_handlers import load_user_with_erp_details
+
+from api_validations.validations_request import (
+ Login,
+ Logout,
+ ChangePassword,
+ Remember,
+ Forgot,
+ CreatePassword,
+ OccupantSelection,
+ EmployeeSelection,
+)
+
+
+class AuthenticationLoginEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Login via domain and access key : [email] | [phone]"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
+ }
+ __event_validation__ = {
+ "e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
+ }
+
+ @classmethod
+ def authentication_login_with_domain_and_creds(
+ cls,
+ data: Login,
+ request,
+ ):
+ access_dict = Users.login_user_with_credentials(data=data, request=request)
+ found_user = access_dict.get("user", None)
+ if not found_user:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
+ )
+
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "User is logged in successfully",
+ "access_token": access_dict.get("access_token"),
+ "refresh_token": access_dict.get("refresher_token"),
+ "access_object": access_dict.get("access_object"),
+ "user": found_user.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class AuthenticationSelectEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Select Employee Duty or Occupant Type"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
+ }
+ __event_validation__ = {
+ "cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
+ }
+
+ @classmethod
+ def authentication_select_company_or_occupant_type(
+ cls,
+ request: Request,
+ data: Union[EmployeeSelection, OccupantSelection],
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ from api_objects import OccupantToken, CompanyToken
+
+ if isinstance(token_dict, EmployeeTokenObject):
+ if data.company_uu_id not in token_dict.companies_uu_id_list:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Company is not found in users company list",
+ },
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ )
+ if selected_company := Companies.filter_one(
+ Companies.uu_id == data.company_uu_id,
+ ).data:
+ department_ids = [
+ department.id
+ for department in Departments.filter_all(
+ Departments.company_id == selected_company.id,
+ ).data
+ ]
+ duties_ids = [
+ duties.id
+ for duties in Duties.filter_all(
+ Duties.company_id == selected_company.id,
+ ).data
+ ]
+ staff_ids = [
+ staff.id
+ for staff in Staff.filter_all(
+ Staff.duties_id.in_(duties_ids),
+ ).data
+ ]
+ employee = Employees.filter_one(
+ Employees.people_id == token_dict.person_id,
+ Employees.staff_id.in_(staff_ids),
+ ).data
+ reachable_event_list_id = Event2Employee.get_event_id_by_employee_id(
+ employee_id=employee.id
+ )
+ staff = Staff.filter_one(
+ Staff.id == employee.staff_id,
+ ).data
+ duties = Duties.filter_one(
+ Duties.id == staff.duties_id,
+ ).data
+ department = Departments.filter_one(
+ Departments.id == duties.department_id,
+ ).data
+ bulk_id = Duty.filter_by_one(system=True, duty_code="BULK").data
+ bulk_duty_id = Duties.filter_by_one(
+ company_id=selected_company.id,
+ duties_id=bulk_id.id,
+ **Duties.valid_record_dict,
+ ).data
+ update_selected_to_redis(
+ request=request,
+ add_payload=CompanyToken(
+ company_uu_id=selected_company.uu_id.__str__(),
+ company_id=selected_company.id,
+ department_id=department.id,
+ department_uu_id=department.uu_id.__str__(),
+ duty_id=duties.id,
+ duty_uu_id=duties.uu_id.__str__(),
+ bulk_duties_id=bulk_duty_id.id,
+ staff_id=staff.id,
+ staff_uu_id=staff.uu_id.__str__(),
+ employee_id=employee.id,
+ employee_uu_id=employee.uu_id.__str__(),
+ reachable_event_list_id=reachable_event_list_id,
+ ),
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Company is selected successfully",
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ occupant_type = OccupantTypes.filter_by_one(
+ system=True, uu_id=data.occupant_uu_id
+ ).data
+ if not occupant_type:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Occupant Type is not found",
+ )
+ build_part = BuildParts.filter_by_one(
+ system=True, uu_id=data.build_part_uu_id
+ ).data
+ if not build_part:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Build Part is not found",
+ )
+ build = Build.filter_one(
+ Build.id == build_part.build_id,
+ ).data
+ related_company = RelationshipEmployee2Build.filter_one(
+ RelationshipEmployee2Build.member_id == build.id,
+ ).data
+ company_related = Companies.filter_one(
+ Companies.id == related_company.company_id,
+ ).data
+ responsible_employee = Employees.filter_one(
+ Employees.id == related_company.employee_id,
+ ).data
+ if selected_occupant_type := BuildLivingSpace.filter_one(
+ BuildLivingSpace.occupant_type == occupant_type.id,
+ BuildLivingSpace.person_id == token_dict.person_id,
+ BuildLivingSpace.build_parts_id == build_part.id,
+ ).data:
+ reachable_event_list_id = (
+ Event2Occupant.get_event_id_by_build_living_space_id(
+ build_living_space_id=selected_occupant_type.id
+ )
+ )
+ update_selected_to_redis(
+ request=request,
+ add_payload=OccupantToken(
+ living_space_id=selected_occupant_type.id,
+ living_space_uu_id=selected_occupant_type.uu_id.__str__(),
+ occupant_type_id=occupant_type.id,
+ occupant_type_uu_id=occupant_type.uu_id.__str__(),
+ occupant_type=occupant_type.occupant_type,
+ build_id=build.id,
+ build_uuid=build.uu_id.__str__(),
+ build_part_id=build_part.id,
+ build_part_uuid=build_part.uu_id.__str__(),
+ responsible_employee_id=responsible_employee.id,
+ responsible_employee_uuid=responsible_employee.uu_id.__str__(),
+ responsible_company_id=company_related.id,
+ responsible_company_uuid=company_related.uu_id.__str__(),
+ reachable_event_list_id=reachable_event_list_id,
+ ),
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Occupant is selected successfully",
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": False, "message": "Invalid data provided"},
+ status_code=status.HTTP_418_IM_A_TEAPOT,
+ )
+
+
+class AuthenticationCheckTokenEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Check Token is valid for user"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
+ }
+ __event_validation__ = {
+ "73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
+ }
+
+ @classmethod
+ def authentication_check_token_is_valid(
+ cls,
+ request,
+ ):
+ if get_object_via_access_key(request=request):
+ return JSONResponse(
+ content={"completed": True, "message": "Access Token is valid"},
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": False, "message": "Access Token is NOT valid"},
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ )
+
+
+class AuthenticationRefreshEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = (
+ "Refresher Token for refreshing access token without credentials"
+ )
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
+ }
+ __event_validation__ = {
+ "48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
+ }
+
+ @classmethod
+ def authentication_refresh_user_info(
+ cls,
+ request,
+ token_dict: typing.Union[EmployeeSelection, OccupantSelection],
+ ):
+ access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
+ if token_user := get_object_via_access_key(request=request):
+ if found_user := Users.filter_one(
+ Users.uu_id == token_user.get("uu_id")
+ ).data:
+ user_token = UsersTokens.filter_one(
+ UsersTokens.domain == found_user.domain_name,
+ UsersTokens.user_id == found_user.id,
+ UsersTokens.token_type == "RememberMe",
+ ).data
+ access_dict = {
+ "access_token": access_token,
+ "refresh_token": getattr(user_token, "token", None),
+ }
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "User is logged in successfully via refresh token",
+ "data": load_user_with_erp_details(found_user, access_dict),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": False, "message": "Invalid data", "data": {}},
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ )
+
+
+class AuthenticationChangePasswordEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Change password with access token implemented on request headers without password reset token"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
+ }
+ __event_validation__ = {
+ "f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
+ }
+
+ @classmethod
+ def authentication_change_password(
+ cls,
+ data: ChangePassword,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ if found_user := Users.filter_one(Users.uu_id == token_dict.uu_id).data:
+ if found_user.check_password(data.old_password):
+ found_user.set_password(data.new_password)
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Password is changed successfully",
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Old password is not correct",
+ },
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ )
+ return JSONResponse(
+ content={"completed": False, "message": "Invalid data"},
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ )
+
+
+class AuthenticationCreatePasswordEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Create password with password reset token requested via email"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
+ }
+ __event_validation__ = {
+ "c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
+ }
+
+ @classmethod
+ def authentication_create_password(cls, data: CreatePassword):
+
+ if not data.re_password == data.password:
+ raise HTTPException(
+ status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
+ )
+ if found_user := Users.filter_one(
+ Users.password_token == data.password_token
+ ).data:
+ found_user.create_password(found_user=found_user, password=data.password)
+ found_user.password_token = ""
+ found_user.save()
+ send_email_completed = send_email(
+ subject=f"Dear {found_user.user_tag}, your password has been changed.",
+ receivers=[str(found_user.email)],
+ html=password_is_changed_template(user_name=found_user.user_tag),
+ )
+ if not send_email_completed:
+ raise HTTPException(
+ status_code=400, detail="Email can not be sent. Try again later"
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Password is created successfully",
+ "data": found_user.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Record not found",
+ "data": {},
+ },
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+
+
+class AuthenticationDisconnectUserEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Disconnect all sessions of user in access token"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
+ }
+ __event_validation__ = {
+ "8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
+ }
+
+ @classmethod
+ def authentication_disconnect_user(
+ cls, data: Logout, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
+ ):
+ found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
+ if not found_user:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Invalid data",
+ "data": None,
+ },
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+ if already_tokens := get_object_via_user_uu_id(user_id=str(found_user.uu_id)):
+ for key, token_user in already_tokens.items():
+ redis_cli.delete(key)
+ selected_user = Users.filter_one(
+ Users.uu_id == token_user.get("uu_id"),
+ ).data
+ selected_user.remove_refresher_token(
+ domain=data.domain, disconnect=True
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "All sessions are disconnected",
+ "data": selected_user.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": False, "message": "Invalid data", "data": None},
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+
+
+class AuthenticationLogoutEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Logout only single session of user which domain is provided"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
+ }
+ __event_validation__ = {
+ "5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
+ }
+
+ @classmethod
+ def authentication_logout_user(
+ cls, request: Request, data: Logout, token_dict: dict = None
+ ):
+ token_user = None
+ if already_tokens := get_object_via_access_key(request=request):
+ for key in already_tokens:
+ token_user = json.loads(redis_cli.get(key) or {})
+ if token_user.get("domain") == data.domain:
+ redis_cli.delete(key)
+ selected_user = Users.filter_one(
+ Users.uu_id == token_user.get("uu_id"),
+ ).data
+ selected_user.remove_refresher_token(domain=data.domain)
+
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Session is logged out",
+ "data": token_user,
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Logout is not successfully completed",
+ "data": None,
+ },
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+
+
+class AuthenticationRefreshTokenEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Refresh access token with refresher token"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
+ }
+ __event_validation__ = {
+ "c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
+ }
+
+ @classmethod
+ def authentication_refresher_token(
+ cls, request: Request, data: Remember, token_dict: dict = None
+ ):
+ token_refresher = UsersTokens.filter_by_one(
+ token=data.refresh_token,
+ domain=data.domain,
+ **UsersTokens.valid_record_dict,
+ ).data
+ if not token_refresher:
+ return JSONResponse(
+ content={"completed": False, "message": "Invalid data", "data": {}},
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+ if found_user := Users.filter_one(
+ Users.id == token_refresher.user_id,
+ ).data:
+ found_user: Users = found_user
+ access_key = save_access_token_to_redis(
+ request=request, found_user=found_user, domain=data.domain
+ )
+ found_user.last_agent = request.headers.get("User-Agent", None)
+ found_user.last_platform = request.headers.get("Origin", None)
+ found_user.last_remote_addr = getattr(
+ request, "remote_addr", None
+ ) or request.headers.get("X-Forwarded-For", None)
+ found_user.last_seen = str(system_arrow.now())
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "User is logged in successfully via refresher token",
+ "data": load_user_with_erp_details(
+ found_user,
+ {
+ "access_token": access_key,
+ "refresh_token": data.refresh_token,
+ },
+ ),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": False, "message": "Invalid data", "data": {}},
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+
+
+class AuthenticationForgotPasswordEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Send an email to user for a valid password reset token"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
+ }
+ __event_validation__ = {
+ "e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
+ }
+
+ @classmethod
+ def authentication_forgot_password(
+ cls,
+ request: Request,
+ data: Forgot,
+ ):
+ found_user: Users = Users.check_user_exits(
+ access_key=data.access_key, domain=data.domain
+ )
+ forgot_key = save_access_token_to_redis(
+ request=request, found_user=found_user, domain=data.domain
+ )
+ forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key)
+ send_email_completed = send_email(
+ subject=f"Dear {found_user.user_tag}, your forgot password link has been sent.",
+ receivers=[str(found_user.email)],
+ html=change_your_password_template(
+ user_name=found_user.user_tag, forgot_link=forgot_link
+ ),
+ )
+ if not send_email_completed:
+ raise HTTPException(
+ status_code=400, detail="Email can not be sent. Try again later"
+ )
+ found_user.password_token = forgot_key
+ found_user.password_token_is_valid = str(system_arrow.shift(days=1))
+ found_user.save()
+
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Password is change link is sent to your email or phone",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class AuthenticationResetPasswordEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "af9e121e-24bb-44ac-a616-471d5754360e": "authentication_reset_password",
+ }
+
+ @classmethod
+ def authentication_reset_password(cls, data: Forgot):
+ from sqlalchemy import or_
+
+ found_user = Users.query.filter(
+ or_(
+ Users.email == str(data.access_key).lower(),
+ Users.phone_number == str(data.access_key).replace(" ", ""),
+ ),
+ ).first()
+ if not found_user:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Given access key or domain is not matching with the any user record.",
+ )
+
+ reset_password_token = found_user.reset_password_token(found_user=found_user)
+ send_email_completed = send_email(
+ subject=f"Dear {found_user.user_tag}, a password reset request has been received.",
+ receivers=[str(found_user.email)],
+ html=change_your_password_template(
+ user_name=found_user.user_tag,
+ forgot_link=ApiStatic.forgot_link(forgot_key=reset_password_token),
+ ),
+ )
+ if not send_email_completed:
+ raise found_user.raise_http_exception(
+ status_code=400, message="Email can not be sent. Try again later"
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Password change link is sent to your email or phone",
+ "data": found_user.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
+
+ event_type = "LOGIN"
+ event_description = "Download avatar icon and profile info of user"
+ event_category = "AUTHENTICATION"
+
+ __event_keys__ = {
+ "c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
+ }
+ __event_validation__ = {
+ "c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
+ }
+
+ @classmethod
+ def authentication_download_avatar(
+ cls, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
+ ):
+ if found_user := Users.filter_one(Users.id == token_dict.user_id).data:
+ expired_starts = str(
+ system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
+ )
+ expired_int = (
+ system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
+ ).days
+
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Avatar and profile is shared via user credentials",
+ "data": {
+ "lang": token_dict.lang,
+ "full_name": found_user.person.full_name,
+ "avatar": found_user.avatar,
+ "remember_me": found_user.remember_me,
+ "expiry_ends": str(found_user.expiry_ends),
+ "expired_str": expired_starts,
+ "expired_int": int(expired_int),
+ },
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": False, "message": "Invalid data", "data": {}},
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+
+
+AuthenticationLoginEventMethod = AuthenticationLoginEventMethods(
+ action=ActionsSchema(endpoint="/authentication/login")
+)
+AuthenticationSelectEventMethod = AuthenticationSelectEventMethods(
+ action=ActionsSchema(endpoint="/authentication/select")
+)
+AuthenticationCheckTokenEventMethod = AuthenticationCheckTokenEventMethods(
+ action=ActionsSchema(endpoint="/authentication/valid")
+)
+AuthenticationRefreshEventMethod = AuthenticationRefreshEventMethods(
+ action=ActionsSchema(endpoint="/authentication/refresh")
+)
+AuthenticationChangePasswordEventMethod = AuthenticationChangePasswordEventMethods(
+ action=ActionsSchema(endpoint="/authentication/change_password")
+)
+AuthenticationCreatePasswordEventMethod = AuthenticationCreatePasswordEventMethods(
+ action=ActionsSchema(endpoint="/authentication/create_password")
+)
+AuthenticationDisconnectUserEventMethod = AuthenticationDisconnectUserEventMethods(
+ action=ActionsSchema(endpoint="/authentication/disconnect")
+)
+AuthenticationLogoutEventMethod = AuthenticationLogoutEventMethods(
+ action=ActionsSchema(endpoint="/authentication/logout")
+)
+AuthenticationRefreshTokenEventMethod = AuthenticationRefreshTokenEventMethods(
+ action=ActionsSchema(endpoint="/authentication/refresher")
+)
+AuthenticationForgotPasswordEventMethod = AuthenticationForgotPasswordEventMethods(
+ action=ActionsSchema(endpoint="/authentication/forgot")
+)
+AuthenticationDownloadAvatarEventMethod = AuthenticationDownloadAvatarEventMethods(
+ action=ActionsSchema(endpoint="/authentication/avatar")
+)
+AuthenticationResetPasswordEventMethod = AuthenticationResetPasswordEventMethods(
+ action=ActionsSchema(endpoint="/authentication/reset_password")
+)
+
+# UserLogger.log_error(
+# str(
+# dict(
+# user_id=found_user.id,
+# domain=data.domain,
+# access_key=token_user.get("access_input"),
+# agent=request.headers.get("User-Agent", None),
+# ip=getattr(request, "remote_addr", None)
+# or request.headers.get("X-Forwarded-For", None),
+# platform=request.headers.get("Origin", None),
+# login_date=datetime.datetime.utcnow().__str__(),
+# is_login=False,
+# )
+# )
+# )
+
+# UserLogger.log_error(
+# str(
+# dict(
+# user_id=found_user.id,
+# domain=data.domain,
+# access_key=data.access_key,
+# agent=request.headers.get("User-Agent", None),
+# ip=getattr(request, "remote_addr", None)
+# or request.headers.get("X-Forwarded-For", None),
+# platform=request.headers.get("Origin", None),
+# login_date=str(DateTimeLocal.now()),
+# is_login=False,
+# )
+# )
+# )
+# UserLogger.log_error(
+# str(
+# dict(
+# user_id=found_user.id,
+# domain=data.domain,
+# access_key="via_refresher",
+# agent=request.headers.get("User-Agent", None),
+# ip=getattr(request, "remote_addr", None)
+# or request.headers.get("X-Forwarded-For", None),
+# platform=request.headers.get("Origin", None),
+# login_date=datetime.datetime.utcnow().__str__(),
+# is_login=False,
+# )
+# )
+# )
+# UserLogger.log_error(
+# str(
+# dict(
+# user_id=selected_user.id,
+# domain=data.domain,
+# access_key=token_user.get("access_input"),
+# agent=request.headers.get("User-Agent", None),
+# ip=getattr(request, "remote_addr", None)
+# or request.headers.get("X-Forwarded-For", None),
+# platform=request.headers.get("Origin", None),
+# login_date=datetime.datetime.utcnow().__str__(),
+# is_login=False,
+# )
+# )
+# )
diff --git a/api_events/events/application/rules.py b/api_events/events/application/rules.py
new file mode 100644
index 0000000..61e684a
--- /dev/null
+++ b/api_events/events/application/rules.py
@@ -0,0 +1,5 @@
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+
+
+class RulesEvents(MethodToEvent): ...
diff --git a/api_events/events/building/__init__.py b/api_events/events/building/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/building/building_build.py b/api_events/events/building/building_build.py
new file mode 100644
index 0000000..e492d2f
--- /dev/null
+++ b/api_events/events/building/building_build.py
@@ -0,0 +1,308 @@
+import typing
+from typing import Union
+
+from fastapi import status, HTTPException
+from fastapi.responses import JSONResponse
+
+from databases import (
+ Build,
+ RelationshipEmployee2Build,
+ Addresses,
+ BuildParts,
+ BuildTypes,
+ ApiEnumDropdown,
+)
+
+from api_validations.validations_request import (
+ InsertBuild,
+ UpdateBuild,
+ PatchRecord,
+ ListOptions,
+)
+from api_validations.validations_response import ListBuildingResponse
+
+from api_validations.core_response import AlchemyJsonResponse
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+
+
+class BuildListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "68b3b5ed-b74c-4a27-820f-3959214e94e9": "build_list",
+ }
+ __event_validation__ = {
+ "68b3b5ed-b74c-4a27-820f-3959214e94e9": ListBuildingResponse,
+ }
+
+ @classmethod
+ def build_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ Build.pre_query = Build.filter_all(
+ Build.id == token_dict.selected_occupant.build_id,
+ ).query
+ elif isinstance(token_dict, EmployeeTokenObject):
+ Build.pre_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ Build.filter_attr = list_options
+ records = Build.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Building Records are listed",
+ result=records,
+ response_model=ListBuildingResponse,
+ )
+
+
+class BuildCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ event_description = ""
+ event_category = ""
+ __event_keys__ = {
+ "a2271854-6b90-43da-a440-a62b70d90528": "build_create",
+ "b67ee709-0992-4604-9f90-fb1da10d5cf9": "create_building_employee",
+ }
+ __event_validation__ = {
+ "a2271854-6b90-43da-a440-a62b70d90528": InsertBuild,
+ "b67ee709-0992-4604-9f90-fb1da10d5cf9": InsertBuild,
+ }
+
+ @classmethod
+ def build_create(cls, data: InsertBuild, token_dict: EmployeeTokenObject):
+ if not token_dict.selected_company.employee_id:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail=f"Employee id is not found for {token_dict.selected_company.employee_uu_id}",
+ )
+
+ if not token_dict.selected_company.company_id:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail=f"Company id is not found for {token_dict.selected_company.company_uu_id}",
+ )
+
+ created_build = Build.create_action(data=data, token=token_dict)
+ build_type = BuildTypes.filter_by_one(
+ **BuildTypes.valid_record_dict, type_code="APT_YNT"
+ ).data
+ if not build_type:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Build type APT_YNT is not found. Please contact with your system administrator.",
+ )
+ api_enum = ApiEnumDropdown.filter_by_one(enum_class="Directions", key="NN").data
+ if not api_enum:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Api Enum NN is not found. Please contact with your system administrator.",
+ )
+ build_parts = dict(
+ address_gov_code=f"{data.gov_address_code}-M",
+ build_id=int(created_build.id),
+ build_uu_id=str(created_build.uu_id),
+ part_no="0",
+ part_type_id=int(build_type.id),
+ part_type_uu_id=str(build_type.uu_id),
+ part_direction_id=int(api_enum.id),
+ part_direction_uu_id=str(api_enum.uu_id),
+ part_code="MAN-ROOM",
+ human_livable=False,
+ )
+ man_build_part = BuildParts.find_or_create(**build_parts)
+ created_build.save()
+ created_build.update(management_room_id=man_build_part.id)
+ created_build.save()
+ man_build_part.update(is_confirmed=True)
+ man_build_part.save()
+ # created_build_relation = RelationshipEmployee2Build.find_or_create(
+ # company_id=token_dict.selected_company.company_id,
+ # member_id=created_build.id,
+ # employee_id=token_dict.selected_company.employee_id,
+ # )
+ # created_build_relation.update(is_confirmed=True)
+ # created_build_relation.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Build record completed. This build is assigned to you.",
+ "data": created_build.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+ @classmethod
+ def create_building_employee(
+ cls, data: InsertBuild, token_dict: EmployeeTokenObject
+ ):
+ records = Addresses.list_via_employee(
+ token_dict=token_dict, filter_expr=[Addresses.uu_id == data.address_uu_id]
+ ).data
+ if not records:
+ raise HTTPException(
+ status_code=404,
+ detail=f"This address {data.address_uu_id} is not found in the user's address list.",
+ )
+
+ if not token_dict.selected_company.employee_id:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail=f"Employee id is not found for {token_dict.selected_company.employee_uu_id}",
+ )
+
+ if not token_dict.selected_company.company_id:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail=f"Company id is not found for {token_dict.selected_company.company_uu_id}",
+ )
+
+ created_build = Build.create_action(data=data, token=token_dict)
+
+ created_build_relation = RelationshipEmployee2Build.find_or_create(
+ company_id=token_dict.selected_company.company_id,
+ member_id=created_build.id,
+ employee_id=token_dict.selected_company.employee_id,
+ )
+ created_build.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Build record completed. This build is assigned to you.",
+ "data": created_build.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class BuildUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ event_description = ""
+ event_category = ""
+
+ __class_key__ = ""
+ __event_keys__ = {
+ "5ad38a66-1189-451e-babb-77de2d63d757": "build_update",
+ }
+ __event_validation__ = {
+ "5ad38a66-1189-451e-babb-77de2d63d757": UpdateBuild,
+ }
+
+ @classmethod
+ def build_update(
+ cls,
+ build_uu_id: str,
+ data: UpdateBuild,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ Build.pre_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ updated_build = Build.update_action(
+ data=data, token=token_dict, build_uu_id=build_uu_id
+ )
+ Build.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Build record",
+ "data": updated_build.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ elif isinstance(token_dict, EmployeeTokenObject):
+ find_one_build = Build.filter_one(
+ Build.uu_id == build_uu_id,
+ ).data
+ access_authorized_build = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id,
+ filter_expr=[Build.id == find_one_build.id],
+ )
+ if access_authorized_build.count:
+ updated_build = Build.update_action(
+ data=data, token=token_dict, build_uu_id=build_uu_id
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Build record",
+ "data": updated_build.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail=f"This user can not modify {build_uu_id} - building.",
+ )
+
+
+class BuildPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ event_description = ""
+ event_category = ""
+
+ __event_keys__ = {
+ "e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch",
+ }
+ __event_validation__ = {
+ "e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch",
+ }
+
+ @classmethod
+ def build_patch(cls, build_uu_id: str, data: PatchRecord, token_dict):
+ find_one_build = Build.filter_one(
+ Build.uu_id == build_uu_id,
+ )
+ access_authorized_build = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id,
+ filter_expr=[Build.id == find_one_build.id],
+ )
+ if access_authorized_build.count:
+ action = data.excluded_dump()
+ find_one_build.active = bool(action.get("active", find_one_build.active))
+ find_one_build.is_confirmed = bool(
+ action.get("confirm", find_one_build.is_confirmed)
+ )
+ find_one_build.deleted = bool(action.get("delete", find_one_build.deleted))
+ find_one_build.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Patch Build record completed",
+ "data": find_one_build.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Patch Build record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+BuildListEventMethod = BuildListEventMethods(
+ action=ActionsSchema(endpoint="/building/build/list")
+)
+BuildCreateEventMethod = BuildCreateEventMethods(
+ action=ActionsSchema(endpoint="/building/build/create")
+)
+BuildUpdateEventMethod = BuildUpdateEventMethods(
+ action=ActionsSchema(endpoint="/building/build/update")
+)
+BuildPatchEventMethod = BuildPatchEventMethods(
+ action=ActionsSchema(endpoint="/building/build/patch")
+)
diff --git a/api_events/events/building/building_build_area.py b/api_events/events/building/building_build_area.py
new file mode 100644
index 0000000..735e4d8
--- /dev/null
+++ b/api_events/events/building/building_build_area.py
@@ -0,0 +1,176 @@
+import typing
+
+from databases import (
+ Build,
+ BuildArea,
+)
+
+from api_validations.validations_request import (
+ InsertBuildArea,
+ UpdateBuildArea,
+ ListOptions,
+)
+
+from api_validations.core_response import AlchemyJsonResponse
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+
+
+class BuildAreaListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "0bb51845-65a2-4340-8872-a3b5aad95468": "build_area_list",
+ }
+ __event_validation__ = {
+ "0bb51845-65a2-4340-8872-a3b5aad95468": None,
+ }
+
+ @classmethod
+ def build_area_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ build_ids = Build.filter_all(
+ Build.id == token_dict.selected_occupant.build_id,
+ ).data
+ BuildArea.pre_query = BuildArea.filter_all(
+ BuildArea.build_id.in_([build.id for build in build_ids]),
+ ).query
+ elif isinstance(token_dict, EmployeeTokenObject):
+ build_ids = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ BuildArea.pre_query = BuildArea.filter_all(
+ BuildArea.build_id.in_([build.id for build in build_ids]),
+ ).query
+ BuildArea.filter_attr = list_options
+ records = BuildArea.filter_all()
+ return AlchemyJsonResponse(
+ completed=True, message="List of Build Area", result=records
+ )
+
+
+class BuildAreaCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "a10571fa-ac1d-4546-9272-cacb911d8004": "build_area_create",
+ }
+ __event_validation__ = {
+ "a10571fa-ac1d-4546-9272-cacb911d8004": InsertBuildArea,
+ }
+
+ @classmethod
+ def build_area_create(
+ cls,
+ data: InsertBuildArea,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ data_dict = data.excluded_dump()
+ selected_build = None
+ if isinstance(token_dict, OccupantTokenObject):
+ if not token_dict.selected_occupant.build_uuid == data.build_uu_id:
+ BuildArea.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Occupant can not create build area for {data.build_uu_id}",
+ data={
+ "build_uu_id": data.build_uu_id,
+ },
+ )
+ selected_build = Build.filter_by_one(
+ system=True, uu_id=data.build_uu_id
+ ).data
+ elif isinstance(token_dict, EmployeeTokenObject):
+ build_ids = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ ).all()
+ if not str(data.build_uu_id) in [str(build.uu_id) for build in build_ids]:
+ BuildArea.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Employee can not create build area for {data.build_uu_id}",
+ data={
+ "build_uu_id": data.build_uu_id,
+ },
+ )
+ selected_build = Build.filter_by_one(
+ system=True, uu_id=data.build_uu_id
+ ).data
+
+ data_dict["build_id"] = selected_build.id
+ data_dict["build_uu_id"] = str(selected_build.uu_id)
+ created_build_part = BuildArea.find_or_create(**data_dict)
+ created_build_part.save()
+ created_build_part.update(is_confirmed=True)
+ created_build_part.save()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Created Build Area",
+ result=created_build_part.get_dict(),
+ )
+
+
+class BuildAreaUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "58178738-7489-4f8f-954e-5c8f083c1845": "build_area_update",
+ }
+ __event_validation__ = {
+ "58178738-7489-4f8f-954e-5c8f083c1845": UpdateBuildArea,
+ }
+
+ @classmethod
+ def build_area_update(
+ cls,
+ build_uu_id: str,
+ data: UpdateBuildArea,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return AlchemyJsonResponse(
+ completed=False,
+ message="Update Build record",
+ result=None,
+ )
+
+
+class BuildAreaPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "d6bd8a5f-fa76-49da-b82e-4a95f1bcce39": "build_area_patch",
+ }
+ __event_validation__ = {
+ "d6bd8a5f-fa76-49da-b82e-4a95f1bcce39": None,
+ }
+
+ @classmethod
+ def build_area_patch(
+ cls,
+ build_uu_id: str,
+ data,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return AlchemyJsonResponse(
+ completed=False,
+ message="Patch Build record",
+ result=None,
+ )
+
+
+BuildAreaListEventMethod = BuildAreaListEventMethods(
+ action=ActionsSchema(endpoint="/building/area/list")
+)
+BuildAreaCreateEventMethod = BuildAreaCreateEventMethods(
+ action=ActionsSchema(endpoint="/building/area/create")
+)
+BuildAreaUpdateEventMethod = BuildAreaUpdateEventMethods(
+ action=ActionsSchema(endpoint="/building/area/update")
+)
+BuildAreaPatchEventMethod = BuildAreaPatchEventMethods(
+ action=ActionsSchema(endpoint="/building/area/patch")
+)
diff --git a/api_events/events/building/building_build_parts.py b/api_events/events/building/building_build_parts.py
new file mode 100644
index 0000000..49e23f6
--- /dev/null
+++ b/api_events/events/building/building_build_parts.py
@@ -0,0 +1,165 @@
+from typing import Union
+
+from fastapi.responses import JSONResponse
+from fastapi import status
+
+from api_validations.validations_response.parts import BuildPartsListResponse
+from databases import (
+ Build,
+ BuildParts,
+)
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+from api_validations.validations_request import (
+ InsertBuildParts,
+ UpdateBuildParts,
+ ListOptions,
+)
+
+
+class BuildingBuildPartsListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "b860e37a-e19b-4c45-9543-461241f7587c": "building_build_parts_list"
+ }
+ __event_validation__ = {
+ "b860e37a-e19b-4c45-9543-461241f7587c": BuildPartsListResponse
+ }
+
+ @classmethod
+ def building_build_parts_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ build_list_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id,
+ )
+ build_list_ids = [build.id for build in build_list_query.all()]
+ BuildParts.pre_query = BuildParts.filter_all(
+ BuildParts.build_id.in_(build_list_ids),
+ ).query
+ BuildParts.filter_attr = list_options
+ records = BuildParts.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Building Parts Records are listed",
+ result=records,
+ cls_object=BuildParts,
+ response_model=BuildPartsListResponse,
+ filter_attributes=list_options,
+ )
+
+
+class BuildingBuildPartsCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": "building_build_parts_create"
+ }
+ __event_validation__ = {"fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": InsertBuildParts}
+
+ @classmethod
+ def building_build_parts_create(
+ cls,
+ data: InsertBuildParts,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ created_build = BuildParts.create_action(data=data, token=token_dict)
+ created_build.save()
+ created_build.update(is_confirmed=True)
+ created_build.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Build Parts record",
+ "data": created_build.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class BuildingBuildPartsUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "58fdf95e-2110-4ed6-9c26-95f4be87eaee": "building_build_parts_update"
+ }
+ __event_validation__ = {"58fdf95e-2110-4ed6-9c26-95f4be87eaee": UpdateBuildParts}
+
+ @classmethod
+ def building_build_parts_update(
+ cls,
+ data: UpdateBuildParts,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ updated_build = BuildParts.update_action(data=data, token=token_dict)
+ updated_build.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Build Parts record",
+ "data": updated_build,
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class BuildingBuildPartsPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "87a15ade-3474-4206-b574-bbf8580cbb14": "building_build_parts_patch"
+ }
+ __event_validation__ = {"87a15ade-3474-4206-b574-bbf8580cbb14": None}
+
+ @classmethod
+ def building_build_parts_patch(cls, data, token_dict):
+ find_one_build = BuildParts.filter_one(
+ BuildParts.uu_id == data.uu_id,
+ ).data
+ access_authorized_build = BuildParts.select_action(
+ duty_id=token_dict.selected_company.duty_id,
+ filter_expr=[BuildParts.id == find_one_build.id],
+ )
+ if access_authorized_build.count:
+ action = data.excluded_dump()
+ find_one_build.active = bool(action.get("active", find_one_build.active))
+ find_one_build.is_confirmed = bool(
+ action.get("confirm", find_one_build.is_confirmed)
+ )
+ find_one_build.deleted = bool(action.get("delete", find_one_build.deleted))
+ find_one_build.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Build Parts record",
+ "data": find_one_build.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Update Build Parts record",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+BuildingBuildPartsListEventMethod = BuildingBuildPartsListEventMethods(
+ action=ActionsSchema(endpoint="/building/parts/list")
+)
+BuildingBuildPartsCreateEventMethod = BuildingBuildPartsCreateEventMethods(
+ action=ActionsSchema(endpoint="/building/parts/create")
+)
+BuildingBuildPartsUpdateEventMethod = BuildingBuildPartsUpdateEventMethods(
+ action=ActionsSchema(endpoint="/building/parts/update")
+)
+BuildingBuildPartsPatchEventMethod = BuildingBuildPartsPatchEventMethods(
+ action=ActionsSchema(endpoint="/building/parts/patch")
+)
diff --git a/api_events/events/building/building_build_sites.py b/api_events/events/building/building_build_sites.py
new file mode 100644
index 0000000..f8a5a61
--- /dev/null
+++ b/api_events/events/building/building_build_sites.py
@@ -0,0 +1,175 @@
+import typing
+
+from databases import (
+ Build,
+ BuildSites,
+)
+
+from api_validations.validations_request import (
+ InsertBuildArea,
+ UpdateBuildArea,
+ ListOptions,
+)
+
+from api_validations.core_response import AlchemyJsonResponse
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from databases.sql_models.identity.identity import Addresses
+
+
+class BuildSitesListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "6798414c-6c7d-47f0-9d8b-6935a0f51c2e": "build_sites_list",
+ }
+ __event_validation__ = {
+ "6798414c-6c7d-47f0-9d8b-6935a0f51c2e": None,
+ }
+
+ @classmethod
+ def build_sites_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ occupants_build = Build.filter_one(
+ Build.id == token_dict.selected_occupant.build_id,
+ ).data
+ BuildSites.pre_query = BuildSites.filter_all(
+ BuildSites.address_id == occupants_build.address_id,
+ ).query
+ elif isinstance(token_dict, EmployeeTokenObject):
+ employees_build = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ employees_build_list = [build.address_id for build in employees_build.all()]
+ if not employees_build_list:
+ BuildSites.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message="Employee has no build sites registered",
+ data={},
+ )
+ BuildSites.pre_query = BuildSites.filter_all(
+ BuildSites.address_id.in_(employees_build_list)
+ ).query
+ BuildSites.filter_attr = list_options
+ records = BuildSites.filter_all()
+ return AlchemyJsonResponse(
+ completed=True, message="Update Build record", result=records
+ )
+
+
+class BuildSitesCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "57edc8bf-8f29-4e75-b5e1-9ca0139a3fda": "build_sites_create",
+ }
+ __event_validation__ = {
+ "57edc8bf-8f29-4e75-b5e1-9ca0139a3fda": InsertBuildArea,
+ }
+
+ @classmethod
+ def build_area_create(
+ cls,
+ data: InsertBuildArea,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ if not token_dict.selected_occupant.build_uuid == data.build_uu_id:
+ BuildSites.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Occupant can not create build sites for {data.build_uu_id}",
+ data={
+ "build_uu_id": data.build_uu_id,
+ },
+ )
+ elif isinstance(token_dict, EmployeeTokenObject):
+ build_ids = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ ).all()
+ if not str(data.build_uu_id) in [str(build.uu_id) for build in build_ids]:
+ BuildSites.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Employee can not create build sites for {data.build_uu_id}",
+ data={
+ "build_uu_id": data.build_uu_id,
+ },
+ )
+ data_dict = data.excluded_dump()
+ created_build_part = BuildSites.find_or_create(**data_dict)
+ created_build_part.save()
+ created_build_part.update(is_confirmed=True)
+ created_build_part.save()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Update Build record",
+ result=created_build_part,
+ )
+
+
+class BuildSitesUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "b18e8e37-a62b-4a84-9972-ba17121ed393": "build_sites_update",
+ }
+ __event_validation__ = {
+ "b18e8e37-a62b-4a84-9972-ba17121ed393": UpdateBuildArea,
+ }
+
+ @classmethod
+ def build_area_update(
+ cls,
+ build_uu_id: str,
+ data: UpdateBuildArea,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return AlchemyJsonResponse(
+ completed=False,
+ message="Update Build record",
+ result=None,
+ )
+
+
+class BuildSitesPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "39ba1d78-ff0d-4ec7-a363-b457cbf199a0": "build_sites_patch",
+ }
+ __event_validation__ = {
+ "39ba1d78-ff0d-4ec7-a363-b457cbf199a0": None,
+ }
+
+ @classmethod
+ def build_area_patch(
+ cls,
+ build_uu_id: str,
+ data,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return AlchemyJsonResponse(
+ completed=False,
+ message="Patch Build record",
+ result=None,
+ )
+
+
+BuildSitesListEventMethod = BuildSitesListEventMethods(
+ action=ActionsSchema(endpoint="/building/sites/list")
+)
+BuildSitesCreateEventMethod = BuildSitesCreateEventMethods(
+ action=ActionsSchema(endpoint="/building/sites/create")
+)
+BuildSitesUpdateEventMethod = BuildSitesUpdateEventMethods(
+ action=ActionsSchema(endpoint="/building/sites/update")
+)
+BuildSitesPatchEventMethod = BuildSitesPatchEventMethods(
+ action=ActionsSchema(endpoint="/building/sites/patch")
+)
diff --git a/api_events/events/building/building_build_types.py b/api_events/events/building/building_build_types.py
new file mode 100644
index 0000000..a2fa3a8
--- /dev/null
+++ b/api_events/events/building/building_build_types.py
@@ -0,0 +1,48 @@
+from typing import Union
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from api_validations.validations_request import (
+ ListOptions,
+)
+from databases.sql_models.building.build import BuildTypes
+
+
+class BuildTypesListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "5344d03c-fc47-43ec-8c44-6c2acd7e5d9f": "build_types_list",
+ }
+ __event_validation__ = {"5344d03c-fc47-43ec-8c44-6c2acd7e5d9f": None}
+
+ @classmethod
+ def build_types_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ from fastapi.exceptions import HTTPException
+
+ if isinstance(token_dict, EmployeeTokenObject):
+ BuildTypes.filter_attr = list_options
+ results = BuildTypes.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ result=results,
+ message="Build Types are listed successfully",
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ raise HTTPException(
+ status_code=403, detail="You are not authorized to access this endpoint"
+ )
+ else:
+ raise HTTPException(
+ status_code=403, detail="You are not authorized to access this endpoint"
+ )
+
+
+BuildTypesListEventMethod = BuildTypesListEventMethods(
+ action=ActionsSchema(endpoint="/building/types/list")
+)
diff --git a/api_events/events/building/building_living_spaces.py b/api_events/events/building/building_living_spaces.py
new file mode 100644
index 0000000..5d5602a
--- /dev/null
+++ b/api_events/events/building/building_living_spaces.py
@@ -0,0 +1,307 @@
+from typing import Union
+
+
+from api_events.events.events.events_bind_services import (
+ ServiceBindOccupantEventMethods,
+)
+from databases import (
+ Modules,
+ BuildParts,
+ Build,
+ BuildLivingSpace,
+ OccupantTypes,
+ People,
+)
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from api_validations.validations_request import (
+ InsertBuildLivingSpace,
+ UpdateBuildLivingSpace,
+ ListOptions,
+)
+from api_validations.validations_response.living_space import LivingSpaceListResponse
+from databases.sql_models.event.event import Services
+
+
+class BuildingLivingSpacesListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ event_description = ""
+ event_category = ""
+ __event_keys__ = {
+ "36961d8a-cefa-46cc-9f7c-9d841d6351b6": "building_live_space_list",
+ }
+ __event_validation__ = {
+ "36961d8a-cefa-46cc-9f7c-9d841d6351b6": LivingSpaceListResponse
+ }
+
+ @classmethod
+ def building_live_space_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ records, Build.filter_attr = [], None
+ if isinstance(token_dict, OccupantTokenObject):
+ occupants_build_id = Build.filter_one(
+ Build.id == token_dict.selected_occupant.build_id,
+ ).data
+ if not occupants_build_id:
+ Build.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Occupant has no build registered in the system. Contact with your company.",
+ data={},
+ )
+ occupants_build_parts = BuildParts.filter_all(
+ BuildParts.build_id.in_(occupants_build_id.id),
+ ).data
+ if not occupants_build_parts:
+ Build.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Occupant has no build parts registered in the system. Contact with your company.",
+ data={},
+ )
+ BuildLivingSpace.pre_query = BuildLivingSpace.filter_all(
+ BuildLivingSpace.build_parts_id.in_(
+ [build_part.id for build_part in occupants_build_parts]
+ ),
+ ).query
+ BuildLivingSpace.filter_attr = list_options
+ records = BuildLivingSpace.filter_all()
+ elif isinstance(token_dict, EmployeeTokenObject):
+ build_id_list_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ if not build_id_list_query:
+ Build.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Employee has no build registered in the system. Contact with your supervisor.",
+ data={},
+ )
+ build_part_id_list_query = BuildParts.filter_all(
+ BuildParts.build_id.in_(
+ [build.id for build in build_id_list_query.all()]
+ ),
+ ).data
+ if not build_part_id_list_query:
+ Build.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"Employee has no build parts registered in the system. Contact with your supervisor.",
+ data={},
+ )
+ BuildLivingSpace.pre_query = BuildLivingSpace.filter_all(
+ BuildLivingSpace.build_parts_id.in_(
+ [build_part.id for build_part in build_part_id_list_query]
+ ),
+ ).query
+ BuildLivingSpace.filter_attr = list_options
+ records = BuildLivingSpace.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Building Living Spaces are listed successfully",
+ result=records,
+ response_model=LivingSpaceListResponse,
+ cls_object=BuildLivingSpace,
+ filter_attributes=list_options,
+ )
+
+
+class BuildingLivingSpacesCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "46d90119-3b23-4784-8053-fe11da4a3584": "building_live_space_create"
+ }
+ __event_validation__ = {
+ "46d90119-3b23-4784-8053-fe11da4a3584": InsertBuildLivingSpace
+ }
+
+ @classmethod
+ def building_live_space_create(
+ cls,
+ data: InsertBuildLivingSpace,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ from api_library.date_time_actions.date_functions import system_arrow
+
+ data_dict = data.excluded_dump()
+ build_id_list_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ build_part = BuildParts.filter_one(
+ BuildParts.uu_id == data.build_parts_uu_id,
+ BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
+ ).data
+ if not build_part:
+ BuildLivingSpace.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="UNAUTHORIZED",
+ message=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
+ data={
+ "build_parts_uu_id": data.build_parts_uu_id,
+ },
+ )
+ life_person = People.filter_one(
+ People.uu_id == data.person_uu_id,
+ ).data
+ if not life_person:
+ BuildLivingSpace.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="UNAUTHORIZED",
+ message=f"{data.person_uu_id} - Living Person is not found in database.",
+ data={
+ "person_uu_id": data.person_uu_id,
+ },
+ )
+ occupant_type = OccupantTypes.filter_by_one(uu_id=data.occupant_type_uu_id).data
+ if not occupant_type:
+ BuildLivingSpace.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="UNAUTHORIZED",
+ message=f"{data.occupant_type_uu_id} - Occupant Type is not found in database. Check occupant type uu_id",
+ data={
+ "occupant_type_uu_id": data.occupant_type_uu_id,
+ },
+ )
+
+ data_dict["occupant_type"] = occupant_type.id
+ data_dict["occupant_type_uu_id"] = str(occupant_type.uu_id)
+ data_dict["build_parts_id"] = build_part.id
+ data_dict["build_parts_uu_id"] = str(build_part.uu_id)
+ data_dict["person_id"] = life_person.id
+ data_dict["person_uu_id"] = str(life_person.uu_id)
+
+ living_space_id = BuildLivingSpace.select_only(
+ BuildLivingSpace.build_parts_id == build_part.id,
+ BuildLivingSpace.person_id == life_person.id,
+ BuildLivingSpace.occupant_type == occupant_type.id,
+ select_args=[BuildLivingSpace.id],
+ order_by=BuildLivingSpace.expiry_starts.desc(),
+ limit=1,
+ ).data
+
+ last_living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.id == living_space_id[0] if living_space_id else None,
+ ).data
+ created_living_space = BuildLivingSpace.create_action(
+ data=data_dict, token_dict=token_dict
+ )
+ if last_living_space:
+ dt = system_arrow.get(last_living_space.expiry_ends)
+ if dt > system_arrow.now():
+ minute_df = int(dt.time().minute) - 10
+ last_living_space.expiry_ends = str(
+ dt.replace(
+ minute=60 - abs(minute_df) if minute_df < 0 else minute_df
+ )
+ )
+ last_living_space.save()
+
+ created_living_space.save_and_confirm()
+ occupants_service = Services.retrieve_service_via_occupant_code(
+ occupant_code=occupant_type.occupant_code
+ )
+ ServiceBindOccupantEventMethods.bind_services_occupant_system(
+ build_living_space_id=created_living_space.id,
+ service_id=occupants_service.id,
+ )
+ return created_living_space
+
+
+class BuildingLivingSpacesUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "c786e15c-c03e-4e8f-936c-7e5e5ec9bbcc": "building_live_space_update",
+ }
+ __event_validation__ = {
+ "c786e15c-c03e-4e8f-936c-7e5e5ec9bbcc": UpdateBuildLivingSpace
+ }
+
+ @classmethod
+ def building_live_space_update(
+ cls,
+ build_uu_id: str,
+ data: UpdateBuildLivingSpace,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ from api_library.date_time_actions.date_functions import system_arrow
+
+ if isinstance(token_dict, OccupantTokenObject):
+ data_dict = data.dump()
+ build_id_list_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ build_part = BuildParts.filter_one(
+ BuildParts.uu_id == data.build_parts_uu_id,
+ BuildParts.build_id.in_(
+ [build.id for build in build_id_list_query.all()]
+ ),
+ ).data
+ if not build_part:
+ BuildLivingSpace.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"{data.life_person_uu_id} - Living Person is not found in database.",
+ data={
+ "person_uu_id": data.life_person_uu_id,
+ },
+ )
+ life_person = People.filter_one(
+ People.uu_id == data.life_person_uu_id or ""
+ ).data
+ if not life_person:
+ BuildLivingSpace.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"{data.life_person_uu_id} - Living Person is not found in database.",
+ data={
+ "person_uu_id": data.life_person_uu_id,
+ },
+ )
+
+ living_space_id = BuildLivingSpace.select_only(
+ *BuildLivingSpace.valid_record_args(BuildLivingSpace),
+ select_args=[BuildLivingSpace.id],
+ order_by=BuildLivingSpace.expiry_starts.desc(),
+ limit=1,
+ ).get(1)
+
+ last_living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.id == living_space_id if living_space_id else None,
+ ).data
+
+ data_dict["expiry_starts"] = str(system_arrow.now())
+ data_dict["is_tenant_live"] = bool(data.is_tenant_live)
+ data_dict["build_parts_id"] = build_part.id
+ if data_dict["is_tenant_live"]:
+ owner_person = getattr(last_living_space, "owner_person_id", None)
+ if not owner_person:
+ BuildLivingSpace.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message="Owner person of build part is not defined. Please register owner of part first.",
+ data=build_part.get_dict(),
+ )
+ data_dict["life_person_id"] = life_person.id
+ data_dict["owner_person_id"] = owner_person
+ else:
+ data_dict["life_person_id"] = life_person.id
+ data_dict["owner_person_id"] = life_person.id
+ del data_dict["build_parts_uu_id"], data_dict["life_person_uu_id"]
+
+
+BuildingLivingSpacesListEventMethod = BuildingLivingSpacesListEventMethods(
+ action=ActionsSchema(endpoint="/building/living_space/list")
+)
+BuildingLivingSpacesCreateEventMethod = BuildingLivingSpacesCreateEventMethods(
+ action=ActionsSchema(endpoint="/building/living_space/create")
+)
+BuildingLivingSpacesUpdateEventMethod = BuildingLivingSpacesUpdateEventMethods(
+ action=ActionsSchema(endpoint="/building/living_space/update")
+)
diff --git a/api_events/events/company/__init__.py b/api_events/events/company/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/company/company_company.py b/api_events/events/company/company_company.py
new file mode 100644
index 0000000..52a68a3
--- /dev/null
+++ b/api_events/events/company/company_company.py
@@ -0,0 +1,189 @@
+import typing
+
+from fastapi import status
+from fastapi.responses import JSONResponse
+
+from databases import Companies
+
+from api_validations.validations_request import (
+ InsertCompany,
+ UpdateCompany,
+ ListOptions,
+ PatchRecord,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class CompanyListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": "company_list",
+ }
+ __event_validation__ = {"f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": None}
+
+ @classmethod
+ def company_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ Companies.pre_query = Companies.select_action(
+ duty_id_list=[
+ token_dict.selected_company.duty_id,
+ token_dict.selected_company.bulk_duties_id,
+ ]
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ Companies.pre_query = Companies.filter_all(
+ Companies.id == token_dict.selected_occupant.responsible_company_id
+ ).query
+ Companies.filter_attr = list_options
+ records = Companies.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Building Living Spaces are listed successfully",
+ result=records,
+ )
+
+
+class CompanyCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "76f11a08-5f4a-4e1f-961f-aaef21699acd": "company_create",
+ }
+ __event_validation__ = {"76f11a08-5f4a-4e1f-961f-aaef21699acd": InsertCompany}
+
+ @classmethod
+ def company_create(
+ cls,
+ data: InsertCompany,
+ token_dict: EmployeeTokenObject,
+ ):
+ created_company = Companies.create_action(data=data, token=token_dict)
+ created_company.update(
+ related_company=token_dict.selected_company.company_uu_id
+ )
+ created_company.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Company record",
+ "data": created_company.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class CompanyUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "41ea7f29-006a-4310-b5c4-b2a0e1a504bd": "company_update",
+ }
+ __event_validation__ = {
+ "41ea7f29-006a-4310-b5c4-b2a0e1a504bd": UpdateCompany,
+ }
+
+ @classmethod
+ def company_update(
+ cls, company_uu_id: str, data: UpdateCompany, token_dict: EmployeeTokenObject
+ ):
+ Companies.pre_query = Companies.select_action(
+ duty_id_list=[
+ token_dict.selected_company.bulk_duties_id,
+ token_dict.selected_company.duty_id,
+ ],
+ )
+ find_one_company = Companies.filter_one(
+ Companies.uu_id == company_uu_id,
+ ).data
+ if not find_one_company:
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Company record",
+ "data": {},
+ },
+ status_code=200,
+ )
+ updated_company = find_one_company.update(**data.excluded_dump())
+ Companies.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Company record",
+ "data": updated_company,
+ },
+ status_code=200,
+ )
+
+
+class CompanyPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "6320d696-1fd1-49f9-860a-8f22e5b8a68d": "company_patch",
+ }
+ __event_validation__ = {"6320d696-1fd1-49f9-860a-8f22e5b8a68d": None}
+
+ @classmethod
+ def company_patch(
+ cls, company_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
+ ):
+ find_one_company = Companies.filter_one(
+ Companies.uu_id == company_uu_id,
+ ).data
+ access_authorized_company = Companies.select_action(
+ duty_id_list=[
+ token_dict.selected_company.bulk_duties_id,
+ token_dict.selected_company.duty_id,
+ ],
+ )
+ if access_authorized_company.count:
+ action = data.excluded_dump()
+ find_one_company.active = bool(
+ action.get("active", find_one_company.active)
+ )
+ find_one_company.is_confirmed = bool(
+ action.get("confirm", find_one_company.is_confirmed)
+ )
+ find_one_company.deleted = bool(
+ action.get("delete", find_one_company.deleted)
+ )
+ find_one_company.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Patch Company record completed",
+ "data": find_one_company.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Patch Company record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+CompanyPatchEventMethod = CompanyListEventMethods(
+ action=ActionsSchema(endpoint="/company/list")
+)
+CompanyCreateEventMethod = CompanyCreateEventMethods(
+ action=ActionsSchema(endpoint="/company/create")
+)
+CompanyUpdateEventMethod = CompanyUpdateEventMethods(
+ action=ActionsSchema(endpoint="/company/update")
+)
+CompanyListEventMethod = CompanyPatchEventMethods(
+ action=ActionsSchema(endpoint="/company/patch")
+)
diff --git a/api_events/events/company/company_department.py b/api_events/events/company/company_department.py
new file mode 100644
index 0000000..71bd027
--- /dev/null
+++ b/api_events/events/company/company_department.py
@@ -0,0 +1,178 @@
+from typing import Optional
+from fastapi import status
+from fastapi.responses import JSONResponse
+
+from api_validations.validations_request import (
+ DepartmentsPydantic,
+ PatchRecord,
+ ListOptions,
+ BaseModelRegular,
+)
+
+from databases import Departments
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class DepartmentListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "2cb90331-c1b4-4923-8314-8111326b621a": "department_list",
+ }
+ __event_validation__ = {"2cb90331-c1b4-4923-8314-8111326b621a": None}
+
+ @classmethod
+ def department_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: EmployeeTokenObject,
+ ):
+ Departments.filter_attr = list_options
+ records = Departments.filter_all(
+ Departments.company_id == token_dict.selected_company.company_id,
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Departments are listed successfully",
+ result=records,
+ )
+
+
+class AdminUserInsertDepartments(BaseModelRegular):
+ department_code: str
+ department_name: str
+ company_uu_id: Optional[str] = None
+
+ department_description: str
+ parent_department_uu_id: Optional[int] = None
+
+
+class DepartmentCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": "super_user_department_create",
+ }
+ __event_validation__ = {"d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": DepartmentsPydantic}
+
+ @classmethod
+ def super_user_department_create(
+ cls,
+ data: DepartmentsPydantic,
+ token_dict: EmployeeTokenObject,
+ ):
+ data_dict = data.excluded_dump()
+ data_dict["company_id"] = token_dict.selected_company.company_id
+ data_dict["company_uu_id"] = token_dict.selected_company.company_uu_id
+ created_department = Departments.find_or_create(**data_dict)
+ Departments.save()
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Company record already exits here is the record",
+ "data": created_department.get_dict(),
+ },
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+
+
+class DepartmentUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "4172706f-06c9-4c38-9ac8-59085a72f80a": "department_update",
+ }
+ __event_validation__ = {"4172706f-06c9-4c38-9ac8-59085a72f80a": DepartmentsPydantic}
+
+ @classmethod
+ def department_update(
+ cls,
+ company_uu_id: str,
+ data: DepartmentsPydantic,
+ token_dict: EmployeeTokenObject,
+ ):
+ find_one_company = Departments.filter_one(Departments.uu_id == company_uu_id)
+ access_authorized_company = Departments.select_action(
+ duty_id=getattr(token_dict, "duty_id", 5),
+ filter_expr=[Departments.id == token_dict.get("")],
+ )
+ if access_authorized_company.count:
+ data_dict = data.excluded_dump()
+ updated_company = find_one_company.update(**data_dict)
+ Departments.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Company record",
+ "data": updated_company,
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": True, "message": "Update Company record", "data": {}},
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class DepartmentPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "1e272e4f-6c1e-418b-91a7-be8b06c875da": "department_patch",
+ }
+ __event_validation__ = {"1e272e4f-6c1e-418b-91a7-be8b06c875da": None}
+
+ @classmethod
+ def department_patch(
+ cls, company_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
+ ):
+ find_one_company = Departments.find_one_or_abort(uu_id=company_uu_id)
+ access_authorized_company = Departments.select_action(
+ duty_id=getattr(token_dict, "duty_id", 5),
+ filter_expr=[Departments.id == find_one_company.id],
+ )
+ if access_authorized_company.count:
+ action = data.excluded_dump()
+ find_one_company.active = bool(
+ action.get("active", find_one_company.active)
+ )
+ find_one_company.is_confirmed = bool(
+ action.get("confirm", find_one_company.is_confirmed)
+ )
+ find_one_company.deleted = bool(
+ action.get("delete", find_one_company.deleted)
+ )
+ find_one_company.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Patch Company record completed",
+ "data": find_one_company.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Patch Company record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+DepartmentListEventMethod = DepartmentListEventMethods(
+ action=ActionsSchema(endpoint="/department/list")
+)
+DepartmentCreateEventMethod = DepartmentCreateEventMethods(
+ action=ActionsSchema(endpoint="/department/create")
+)
+DepartmentUpdateEventMethod = DepartmentUpdateEventMethods(
+ action=ActionsSchema(endpoint="/department/update")
+)
+DepartmentPatchEventMethod = DepartmentPatchEventMethods(
+ action=ActionsSchema(endpoint="/department/patch")
+)
diff --git a/api_events/events/company/company_duties.py b/api_events/events/company/company_duties.py
new file mode 100644
index 0000000..743642a
--- /dev/null
+++ b/api_events/events/company/company_duties.py
@@ -0,0 +1,232 @@
+from fastapi import status
+from fastapi.responses import JSONResponse
+
+from api_validations.core_response import AlchemyJsonResponse
+from api_validations.validations_request import (
+ InsertDuties,
+ UpdateDuties,
+ SelectDuties,
+ PatchRecord,
+ ListOptions,
+)
+
+from databases import Departments, Duty, Duties
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject
+
+
+class DutiesListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "44b72beb-53a8-407b-a12a-76e74b65794d": "duties_list",
+ }
+ __event_validation__ = {"44b72beb-53a8-407b-a12a-76e74b65794d": None}
+
+ @classmethod
+ def duties_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: EmployeeTokenObject,
+ ):
+ Duties.filter_attr = list_options
+ records = Duties.filter_all(
+ Duties.company_id == token_dict.selected_company.company_id,
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ result=records,
+ message="List of Duties records",
+ )
+
+
+class DutiesGetByUUIDEventMethods(MethodToEvent):
+
+ event_type = "GET"
+ __event_keys__ = {
+ "30c54cce-3303-4d36-959a-b64e383ae177": "duties_get_by_uuid",
+ }
+ __event_validation__ = {"30c54cce-3303-4d36-959a-b64e383ae177": SelectDuties}
+
+ @classmethod
+ def duties_get_by_uuid(
+ cls,
+ data: SelectDuties,
+ token_dict: EmployeeTokenObject,
+ ):
+
+ duty = Duty.filter_one(Duty.uu_id == data.duty_uu_id).data
+ if not duty:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Duty record is not found",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ records = Duties.filter_all(
+ Duties.duties_id == duty.id,
+ Duties.company_id == token_dict.selected_company.company_id,
+ )
+ if not records.data:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Duties record is not found",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+ return {
+ "completed": True,
+ "status": "success",
+ "data": [record.get_dict() for record in records.data],
+ }
+
+
+class DutiesCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "3524ae42-0825-4af7-be85-7c890a4f65d3": "duties_create",
+ }
+ __event_validation__ = {"3524ae42-0825-4af7-be85-7c890a4f65d3": InsertDuties}
+
+ @classmethod
+ def duties_create(
+ cls,
+ data: InsertDuties,
+ token_dict: EmployeeTokenObject,
+ ):
+ duty = Duty.filter_one(Duty.uu_id == data.duties_uu_id).data
+ department = Departments.filter_one(Duty.uu_id == data.department_uu_id).data
+
+ created_duties = Duties.find_or_create(
+ company_id=token_dict.selected_company.company_id,
+ company_uu_id=token_dict.selected_company.company_uu_id,
+ duties_id=duty.id,
+ duties_uu_id=str(duty.uu_id),
+ department_id=department.id,
+ department_uu_id=str(department.uu_id),
+ is_confirmed=data.is_confirmed,
+ )
+ if data.is_default_duty:
+ created_duties.update(users_default_duty=created_duties.id)
+
+ if not created_duties:
+ Duty.save()
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Failed to create Duties record",
+ "data": {},
+ },
+ status_code=status.HTTP_400_BAD_REQUEST,
+ )
+ return {
+ "completed": created_duties.is_found,
+ "message": (
+ "Create Duties record"
+ if created_duties.is_found
+ else "This record is already created"
+ ),
+ "data": created_duties.get_dict(),
+ }
+
+
+class DutiesUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "3fc77829-f1ee-4511-a2ca-582daa03125b": "duties_update",
+ }
+ __event_validation__ = {"3fc77829-f1ee-4511-a2ca-582daa03125b": UpdateDuties}
+
+ @classmethod
+ def duties_update(
+ cls,
+ duties_uu_id: str,
+ data: UpdateDuties,
+ token_dict: EmployeeTokenObject,
+ ):
+ find_one_duties = Duties.find_one_or_abort(uu_id=duties_uu_id)
+ access_authorized_duties = Duties.select_action(
+ duty_id=getattr(token_dict, "duty_id", 5),
+ filter_expr=[Duties.id == find_one_duties.id],
+ )
+ if access_authorized_duties.count:
+ data_dict = data.excluded_dump()
+ updated_duties = find_one_duties.update(**data_dict)
+ Duties.save()
+ return {
+ "completed": True,
+ "message": "Update Duties record",
+ "data": updated_duties,
+ }
+ return {
+ "completed": False,
+ "message": "Update Duties record failed",
+ "data": {},
+ }
+
+
+class DutiesPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "ca81c6d1-975a-4288-a27b-1069aea84afe": "duties_patch",
+ }
+ __event_validation__ = {"ca81c6d1-975a-4288-a27b-1069aea84afe": None}
+
+ @classmethod
+ def duties_patch(
+ cls,
+ duties_uu_id: str,
+ data: PatchRecord,
+ token_dict: EmployeeTokenObject,
+ ):
+ find_one_duties = Duties.find_one_or_abort(uu_id=duties_uu_id)
+ access_authorized_duties = Duties.select_action(
+ duty_id=getattr(token_dict, "duty_id", 5),
+ filter_expr=[Duties.id == find_one_duties.id],
+ )
+ if access_authorized_duties.count:
+ action = data.excluded_dump()
+ find_one_duties.active = bool(action.get("active", find_one_duties.active))
+ find_one_duties.is_confirmed = bool(
+ action.get("confirm", find_one_duties.is_confirmed)
+ )
+ find_one_duties.deleted = bool(
+ action.get("delete", find_one_duties.deleted)
+ )
+ find_one_duties.save()
+ return {
+ "completed": True,
+ "message": "Patch Duties record completed",
+ "data": find_one_duties.get_dict(),
+ }
+ return {
+ "completed": False,
+ "message": "Patch Duties record failed",
+ "data": {},
+ }
+
+
+DutiesListEventMethod = DutiesListEventMethods(
+ action=ActionsSchema(endpoint="/duties/list")
+)
+DutiesGetByUUIDEventMethod = DutiesGetByUUIDEventMethods(
+ action=ActionsSchema(endpoint="/duties/get_by_duty_uuid")
+)
+DutiesCreateEventMethod = DutiesCreateEventMethods(
+ action=ActionsSchema(endpoint="/duties/create")
+)
+DutiesUpdateEventMethod = DutiesUpdateEventMethods(
+ action=ActionsSchema(endpoint="/duties/update")
+)
+DutiesPatchEventMethod = DutiesPatchEventMethods(
+ action=ActionsSchema(endpoint="/duties/patch")
+)
diff --git a/api_events/events/company/company_duty.py b/api_events/events/company/company_duty.py
new file mode 100644
index 0000000..6ca48f2
--- /dev/null
+++ b/api_events/events/company/company_duty.py
@@ -0,0 +1,163 @@
+from fastapi import status
+from fastapi.responses import JSONResponse
+
+from api_validations.validations_request import (
+ InsertCompanyDuty,
+ PatchRecord,
+ ListOptions,
+)
+
+from databases import Duty
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class DutyListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "23231c7d-4ff2-4b39-b71b-ea350d31fadf": "duty_list",
+ }
+ __event_validation__ = {"23231c7d-4ff2-4b39-b71b-ea350d31fadf": None}
+
+ @classmethod
+ def duty_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: EmployeeTokenObject,
+ ):
+ Duty.filter_attr = list_options
+ records = Duty.filter_all(system=True)
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Duty list is brought successfully",
+ result=records,
+ )
+
+
+class DutyCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "c6ea200e-fa17-4393-b390-37f5337c9c65": "duty_create",
+ }
+ __event_validation__ = {"c6ea200e-fa17-4393-b390-37f5337c9c65": InsertCompanyDuty}
+
+ @classmethod
+ def duty_create(
+ cls,
+ data: InsertCompanyDuty,
+ token_dict: EmployeeTokenObject,
+ ):
+ created_duty = Duty.find_or_create(**data.excluded_dump())
+ Duty.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Company record",
+ "data": created_duty.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class DutyUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "ad952647-bcf8-482d-9e05-b2ee8086483f": "duty_update",
+ }
+ __event_validation__ = {"ad952647-bcf8-482d-9e05-b2ee8086483f": None}
+
+ @classmethod
+ def duty_update(
+ cls,
+ company_uu_id: str,
+ data,
+ token_dict: EmployeeTokenObject,
+ ):
+ find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
+ access_authorized_company = Duty.select_action(
+ duty_id=getattr(token_dict, "duty_id", 5), # ?
+ filter_expr=[Duty.id == token_dict.get("")],
+ )
+ if access_authorized_company.count:
+ data_dict = data.excluded_dump()
+ updated_company = find_one_company.update(**data_dict)
+ Duty.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Company record",
+ "data": updated_company,
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": True, "message": "Update Company record", "data": {}},
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class DutyPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": "duty_patch",
+ }
+ __event_validation__ = {"d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": None}
+
+ @classmethod
+ def duty_patch(
+ cls,
+ company_uu_id: str,
+ data: PatchRecord,
+ token_dict: EmployeeTokenObject,
+ ):
+ find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
+ access_authorized_company = Duty.select_action(
+ duty_id=getattr(token_dict, "duty_id", 5),
+ filter_expr=[Duty.id == find_one_company.id],
+ )
+ if access_authorized_company.count:
+ action = data.excluded_dump()
+ find_one_company.active = bool(
+ action.get("active", find_one_company.active)
+ )
+ find_one_company.is_confirmed = bool(
+ action.get("confirm", find_one_company.is_confirmed)
+ )
+ find_one_company.deleted = bool(
+ action.get("delete", find_one_company.deleted)
+ )
+ find_one_company.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Patch Company record completed",
+ "data": find_one_company.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Patch Company record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+DutyListEventMethod = DutyListEventMethods(action=ActionsSchema(endpoint="/duty/list"))
+DutyCreateEventMethod = DutyCreateEventMethods(
+ action=ActionsSchema(endpoint="/duty/create")
+)
+DutyUpdateEventMethod = DutyUpdateEventMethods(
+ action=ActionsSchema(endpoint="/duty/update")
+)
+DutyPatchEventMethod = DutyPatchEventMethods(
+ action=ActionsSchema(endpoint="/duty/patch")
+)
diff --git a/api_events/events/company/company_employee.py b/api_events/events/company/company_employee.py
new file mode 100644
index 0000000..4724838
--- /dev/null
+++ b/api_events/events/company/company_employee.py
@@ -0,0 +1,343 @@
+from fastapi import status, HTTPException
+from fastapi.responses import JSONResponse
+
+from api_library.date_time_actions.date_functions import system_arrow
+from api_validations.validations_request import (
+ InsertEmployees,
+ BindEmployees2People,
+ PatchRecord,
+ ListOptions,
+)
+
+from databases import Employees, Staff, People, EmployeeHistory
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class EmployeeListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "cb677c92-6b05-4122-af5c-12766fae8095": "employee_list",
+ }
+ __event_validation__ = {"cb677c92-6b05-4122-af5c-12766fae8095": None}
+
+ @classmethod
+ def employee_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: EmployeeTokenObject,
+ ):
+ employees_staff = Staff.filter_all(
+ Staff.duties_id.in_(token_dict.duty_id_list),
+ ).data
+ Employees.filter_attr = list_options
+ records = Employees.filter_all(
+ Employees.staff_id.in_([staff.id for staff in employees_staff]),
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Employee are listed successfully",
+ result=records,
+ )
+
+
+class EmployeeCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "1e1632c3-bb0e-46a5-8e45-da3f6d88ac43": "employee_create",
+ }
+ __event_validation__ = {"1e1632c3-bb0e-46a5-8e45-da3f6d88ac43": InsertEmployees}
+
+ @classmethod
+ def employee_create(
+ cls,
+ data: InsertEmployees,
+ token_dict: EmployeeTokenObject,
+ ):
+ person = People.filter_one(
+ People.uu_id == data.people_uu_id,
+ ).data
+ staff = Staff.filter_one(
+ Staff.uu_id == data.staff_uu_id,
+ ).data
+ if not staff:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Staff record not found",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+ created_employee = Employees.find_or_create(
+ staff_id=staff.id,
+ staff_uu_id=str(staff.uu_id),
+ people_id=person.id if person else None,
+ people_uu_id=str(person.uu_id) if person else None,
+ )
+ Employees.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Employee record",
+ "data": created_employee.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class EmployeeUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "9015a076-d78c-463d-9474-ea343a125fb8": "employee_update",
+ }
+ __event_validation__ = {"9015a076-d78c-463d-9474-ea343a125fb8": None}
+
+ @classmethod
+ def employee_update(
+ cls,
+ employee_uu_id: str,
+ data: PatchRecord,
+ token_dict: EmployeeTokenObject,
+ ):
+ find_one_employee = Employees.filter_one(
+ Employees.uu_id == employee_uu_id,
+ ).data
+ access_authorized_employee = Employees.select_action(
+ employee_id=getattr(token_dict, "employee_id", 5),
+ filter_expr=[Employees.id == token_dict.get("")],
+ )
+ if access_authorized_employee.count:
+ data_dict = data.excluded_dump()
+ updated_employee = find_one_employee.update(**data_dict)
+ Employees.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update Employee record",
+ "data": updated_employee,
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Update Employee record",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class EmployeePatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "8446ce0b-9310-4b9f-93e2-61f56a9dacd1": "employee_patch",
+ }
+ __event_validation__ = {"8446ce0b-9310-4b9f-93e2-61f56a9dacd1": None}
+
+ @classmethod
+ def employee_patch(
+ cls,
+ employee_uu_id: str,
+ data: PatchRecord,
+ token_dict: EmployeeTokenObject,
+ ):
+ find_one_employee = Employees.find_one_or_abort(uu_id=employee_uu_id)
+ access_authorized_employee = Employees.select_action(
+ employee_id=getattr(token_dict, "employee_id", 5),
+ filter_expr=[Employees.id == find_one_employee.id],
+ )
+ if access_authorized_employee.count:
+ action = data.excluded_dump()
+ find_one_employee.active = bool(
+ action.get("active", find_one_employee.active)
+ )
+ find_one_employee.is_confirmed = bool(
+ action.get("confirm", find_one_employee.is_confirmed)
+ )
+ find_one_employee.deleted = bool(
+ action.get("delete", find_one_employee.deleted)
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Patch Employee record completed",
+ "data": find_one_employee.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Patch Employee record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class Employee2PeopleEmployEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "5eb04057-7a74-4555-b2c6-14eda32dae89": "company_employee_employ",
+ }
+ __event_validation__ = {
+ "5eb04057-7a74-4555-b2c6-14eda32dae89": BindEmployees2People
+ }
+
+ @classmethod
+ def company_employee_employ(
+ cls,
+ data: BindEmployees2People,
+ token_dict: EmployeeTokenObject,
+ ):
+ selected_staff = Staff.filter_one(
+ Staff.uu_id == data.staff_uu_id,
+ ).data
+ selected_people = People.filter_one(People.uu_id == data.people_uu_id).data
+ if not selected_staff:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Staff record not found",
+ )
+ if not selected_people:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="People record not found",
+ )
+
+ find_one_employee = Employees.filter_all(
+ Employees.staff_id == selected_staff.id,
+ ).data
+
+ staff_name_upper = str(selected_staff.staff_name).upper()
+ if not find_one_employee:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": f"There is no space for new Employee for given staff : {staff_name_upper}",
+ "data": {},
+ },
+ status_code=status.HTTP_406_NOT_ACCEPTABLE,
+ )
+ if not data.expiry_starts:
+ data.expiry_starts = str(system_arrow.now())
+ data.expiry_starts = str(system_arrow.get(str(data.expiry_starts)))
+
+ find_one_employee = find_one_employee.update(
+ people_id=selected_people.id,
+ expiry_starts=data.expiry_starts,
+ **token_dict.update_creds,
+ )
+ Employees.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Get Employee to People record",
+ "data": find_one_employee.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class Employee2PeopleFireEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "caf914fa-0899-4b0b-a85a-3d40fdaa06a5": "company_employee_fire",
+ }
+ __event_validation__ = {
+ "caf914fa-0899-4b0b-a85a-3d40fdaa06a5": BindEmployees2People
+ }
+
+ @classmethod
+ def company_employee_fire(
+ cls,
+ data: BindEmployees2People,
+ token_dict: EmployeeTokenObject,
+ ):
+ selected_people = People.filter_one(
+ People.uu_id == data.people_uu_id,
+ ).data
+ if not selected_people:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="People record not found",
+ )
+
+ find_one_employee: Employees = Employees.filter_one(
+ Employees.people_id == selected_people.id,
+ ).data
+ if not find_one_employee:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Employee record not found for given People",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ find_one_employee = find_one_employee.update(
+ people_id=None, **token_dict.update_creds
+ )
+ if not find_one_employee.people_id:
+ employee_history = EmployeeHistory.find_or_create(
+ staff_id=find_one_employee.staff_id,
+ expiry_ends=data.expiry_ends,
+ people_id=selected_people.id,
+ created_by_id=find_one_employee.created_by_id,
+ updated_by_id=find_one_employee.updated_by_id,
+ confirmed_by_id=find_one_employee.confirmed_by_id,
+ replication_id=find_one_employee.replication_id,
+ created_by=find_one_employee.created_by,
+ updated_by=find_one_employee.updated_by,
+ confirmed_by=find_one_employee.confirmed_by,
+ active=find_one_employee.active,
+ is_confirmed=find_one_employee.is_confirmed,
+ deleted=find_one_employee.deleted,
+ expiry_starts=find_one_employee.expiry_starts,
+ is_notification_send=find_one_employee.is_notification_send,
+ cryp_uu_id=find_one_employee.cryp_uu_id,
+ )
+ Employees.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Employee is fired from Staff",
+ "data": find_one_employee.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Employee record not found for given People",
+ )
+
+
+EmployeeListEventMethod = EmployeeListEventMethods(
+ action=ActionsSchema(endpoint="/employee/list")
+)
+EmployeeCreateEventMethod = EmployeeCreateEventMethods(
+ action=ActionsSchema(endpoint="/employee/create")
+)
+EmployeeUpdateEventMethod = EmployeeUpdateEventMethods(
+ action=ActionsSchema(endpoint="/employee/update")
+)
+EmployeePatchEventMethod = EmployeePatchEventMethods(
+ action=ActionsSchema(endpoint="/employee/patch")
+)
+Employee2PeopleEmployEventMethod = Employee2PeopleEmployEventMethods(
+ action=ActionsSchema(endpoint="/employee/employ")
+)
+Employee2PeopleFireEventMethod = Employee2PeopleFireEventMethods(
+ action=ActionsSchema(endpoint="/employee/fire")
+)
diff --git a/api_events/events/company/company_staff.py b/api_events/events/company/company_staff.py
new file mode 100644
index 0000000..9236e1e
--- /dev/null
+++ b/api_events/events/company/company_staff.py
@@ -0,0 +1,156 @@
+from fastapi import status
+from fastapi.responses import JSONResponse
+from fastapi.exceptions import HTTPException
+
+from api_validations.validations_request import (
+ InsertStaff,
+ SelectStaff,
+ PatchRecord,
+ ListOptions,
+)
+
+from databases import Staff, Duties
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class StaffListEventMethods(MethodToEvent):
+ event_type = "SELECT"
+ __event_keys__ = {
+ "8984a519-99bf-4f25-8f34-2e1aebba468c": "staff_list",
+ }
+ __event_validation__ = {"8984a519-99bf-4f25-8f34-2e1aebba468c": None}
+
+ @classmethod
+ def staff_list(cls, list_options: ListOptions, token_dict: EmployeeTokenObject):
+ Staff.filter_attr = list_options
+ records = Staff.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Staff are listed successfully",
+ result=records,
+ )
+
+
+class StaffCreateEventMethods(MethodToEvent):
+ event_type = "CREATE"
+ __event_keys__ = {
+ "8f619257-19fd-404f-b713-7392c588dc36": "staff_create",
+ }
+ __event_validation__ = {"8f619257-19fd-404f-b713-7392c588dc36": InsertStaff}
+
+ @classmethod
+ def staff_create(cls, data: InsertStaff, token_dict: EmployeeTokenObject):
+ data_dict = data.excluded_dump()
+ duties = Duties.filter_one(
+ Duties.uu_id == data.duties_uu_id,
+ ).data
+ if not duties:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Duties not found",
+ )
+ data_dict["duties_id"] = duties.id
+ created_duty = Staff.find_or_create(**data_dict)
+ Staff.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create Staff record",
+ "data": created_duty.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class StaffGetByUUIDEventMethods(MethodToEvent):
+
+ event_type = "GET"
+ __event_keys__ = {
+ "7724cfbb-c0ee-4261-959b-61b84e88a34f": "staff_get_by_uu_id",
+ }
+ __event_validation__ = {"7724cfbb-c0ee-4261-959b-61b84e88a34f": SelectStaff}
+
+ @classmethod
+ def staff_get_by_uu_id(cls, data: SelectStaff, token_dict: EmployeeTokenObject):
+ if data.duties_uu_id:
+ duties_id = Duties.filter_one(
+ Duties.uu_id == data.duties_uu_id,
+ ).data
+ selected_staffs = Staff.filter_all(Staff.duties_id == duties_id.id)
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Staff records are listed",
+ "data": [
+ selected_staff.get_dict()
+ for selected_staff in selected_staffs.data
+ ],
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Get Staff record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_202_ACCEPTED,
+ )
+
+
+class StaffUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "5329f35d-ff9d-4656-a831-ba9c8204e483": "staff_update",
+ }
+ __event_validation__ = {"5329f35d-ff9d-4656-a831-ba9c8204e483": None}
+
+ @classmethod
+ def staff_update(cls, staff_uu_id: str, data, token_dict: EmployeeTokenObject):
+ return JSONResponse(
+ content={"completed": True, "message": "Update Staff record", "data": {}},
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class StaffPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "b1cd7c0a-1458-472b-894f-3adc857c8512": "staff_patch",
+ }
+ __event_validation__ = {"b1cd7c0a-1458-472b-894f-3adc857c8512": None}
+
+ @classmethod
+ def staff_patch(
+ cls, staff_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
+ ):
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Patch Staff record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+StaffListEventMethod = StaffListEventMethods(
+ action=ActionsSchema(endpoint="/staff/list")
+)
+StaffCreateEventMethod = StaffCreateEventMethods(
+ action=ActionsSchema(endpoint="/staff/create")
+)
+StaffGetByUUIDEventMethod = StaffGetByUUIDEventMethods(
+ action=ActionsSchema(endpoint="/staff/get_by_duties_uu_id")
+)
+StaffUpdateEventMethod = StaffUpdateEventMethods(
+ action=ActionsSchema(endpoint="/staff/update")
+)
+StaffPatchEventMethod = StaffPatchEventMethods(
+ action=ActionsSchema(endpoint="/staff/patch")
+)
diff --git a/api_events/events/decision_book/__init__.py b/api_events/events/decision_book/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/decision_book/decision_book_decision_book.py b/api_events/events/decision_book/decision_book_decision_book.py
new file mode 100644
index 0000000..41b8dd6
--- /dev/null
+++ b/api_events/events/decision_book/decision_book_decision_book.py
@@ -0,0 +1,229 @@
+import typing
+
+from fastapi import status, HTTPException
+from fastapi.responses import JSONResponse
+
+from databases import (
+ Build,
+ BuildDecisionBook,
+ Companies,
+ OccupantTypes,
+)
+
+from api_validations.validations_request import (
+ InsertDecisionBook,
+ ListOptions,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from api_library.date_time_actions.date_functions import system_arrow
+
+
+class DecisionBookListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "5c10d6ae-2aee-4243-a7c3-94826d028d13": "building_decision_book_list",
+ }
+ __event_validation__ = {"5c10d6ae-2aee-4243-a7c3-94826d028d13": None}
+
+ @classmethod
+ def building_decision_book_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ records = []
+ if isinstance(token_dict, EmployeeTokenObject):
+ build_id_list_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ build_id_list = build_id_list_query.all()
+ if not build_id_list:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
+ )
+ BuildDecisionBook.filter_attr = list_options
+ records = BuildDecisionBook.filter_all(
+ BuildDecisionBook.build_id.in_([build.id for build in build_id_list]),
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ BuildDecisionBook.filter_attr = list_options
+ records = BuildDecisionBook.filter_all(
+ BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="DecisionBook are listed successfully",
+ result=records,
+ )
+
+
+class DecisionBookCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "0a68cb44-271a-4829-81f6-cd99a5f326b4": "building_decision_book_create",
+ }
+ __event_validation__ = {"0a68cb44-271a-4829-81f6-cd99a5f326b4": InsertDecisionBook}
+
+ @classmethod
+ def building_decision_book_create(
+ cls,
+ data: InsertDecisionBook,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ data_dict = data.excluded_dump()
+ if isinstance(token_dict, EmployeeTokenObject):
+ Build.pre_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id
+ )
+ build = Build.filter_one(
+ Build.uu_id == data.build_uu_id,
+ ).data
+ if not build:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Emloyee UUID {token_dict.selected_company.employee_uu_id} has no build with given UUID {data_dict.get('build_uu_id')}",
+ )
+ data_dict["build_id"] = build.id
+ if data.resp_company_uu_id:
+ Companies.pre_query = Companies.select_action(
+ duty_id_list=[
+ token_dict.selected_company.duty_id,
+ token_dict.selected_company.bulk_duties_id,
+ ]
+ )
+ company = Companies.filter_one(
+ Companies.uu_id == data.resp_company_uu_id,
+ ).data
+ if not company:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Duty UUID {token_dict.selected_company.duty_uu_id} has no company with given UUID {data_dict.get('resp_company_uu_id')}",
+ )
+ data_dict["resp_company_id"] = company.id
+ data_dict["resp_company_uu_id"] = str(company.uu_id)
+
+ decision_period_date = system_arrow.get(build.decision_period_date)
+ data_dict["expiry_starts"] = system_arrow.get(
+ system_arrow.now().date().year,
+ int(decision_period_date.date().month),
+ int(decision_period_date.date().day),
+ )
+ data_dict["expiry_ends"] = str(
+ data_dict["expiry_starts"].shift(years=1, days=-1)
+ )
+ data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
+ build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
+ build_decision_book.save_and_confirm()
+ return JSONResponse(
+ status_code=status.HTTP_200_OK,
+ content=dict(
+ message="Decision Book has created",
+ completed=True,
+ data=build_decision_book.get_dict(),
+ ),
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ occupant_manager = OccupantTypes.filter_by_one(
+ occupant_category_type="BU", occupant_code="BU-MNG"
+ ).data
+ if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail="Only Build Manager can create decision book",
+ )
+
+ occupant_build = Build.filter_one(
+ Build.id == token_dict.selected_occupant.build_id,
+ ).data
+ occupant_company = Companies.filter_one(
+ Companies.id == token_dict.selected_occupant.responsible_company_id,
+ ).data
+ data_dict["build_id"] = occupant_build.id
+ data_dict["build_uu_id"] = str(occupant_build.uu_id)
+ data_dict["resp_company_id"] = occupant_company.id
+ data_dict["resp_company_uu_id"] = str(occupant_company.uu_id)
+
+ decision_period_date = system_arrow.get(occupant_build.decision_period_date)
+ data_dict["expiry_starts"] = system_arrow.get(
+ system_arrow.now().date().year,
+ int(decision_period_date.date().month),
+ int(decision_period_date.date().day),
+ )
+ data_dict["expiry_ends"] = str(
+ data_dict["expiry_starts"].shift(years=1, days=-1)
+ )
+ data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
+ build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
+ build_decision_book.save()
+ build_decision_book.update(is_confirmed=True)
+ build_decision_book.save()
+ return JSONResponse(
+ status_code=status.HTTP_200_OK,
+ content=dict(
+ message="Decision Book has created",
+ completed=True,
+ data=build_decision_book.get_dict(),
+ ),
+ )
+
+
+class DecisionBookUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29": "building_decision_book_update",
+ }
+ __event_validation__ = {"6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29": None}
+
+ @classmethod
+ def building_decision_book_update(cls, data: InsertDecisionBook, token_dict: dict):
+ return
+
+
+class DecisionBookPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "7b58ed84-9a65-4588-994d-30df8366b050": "building_decision_book_patch",
+ }
+ __event_validation__ = {"7b58ed84-9a65-4588-994d-30df8366b050": None}
+
+ @classmethod
+ def building_decision_book_patch(cls, data: InsertDecisionBook, token_dict: dict):
+ return
+
+
+class DecisionBookApprovalEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "fc745142-3437-4ca2-89fa-c5a3e2b5c6c2": "building_decision_book_approval",
+ }
+ __event_validation__ = {"fc745142-3437-4ca2-89fa-c5a3e2b5c6c2": None}
+
+ @classmethod
+ def building_decision_book_approval(cls, data, token_dict):
+ return
+
+
+DecisionBookListEventMethod = DecisionBookListEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/list")
+)
+DecisionBookCreateEventMethod = DecisionBookCreateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/create")
+)
+DecisionBookUpdateEventMethod = DecisionBookUpdateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/update")
+)
+DecisionBookPatchEventMethod = DecisionBookPatchEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/patch")
+)
+DecisionBookApprovalEventMethod = DecisionBookApprovalEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/approval")
+)
diff --git a/api_events/events/decision_book/decision_book_decision_book_items.py b/api_events/events/decision_book/decision_book_decision_book_items.py
new file mode 100644
index 0000000..fc22c1d
--- /dev/null
+++ b/api_events/events/decision_book/decision_book_decision_book_items.py
@@ -0,0 +1,570 @@
+import typing
+
+from fastapi import status, HTTPException
+from fastapi.responses import JSONResponse
+
+from api_events.events.events.events_bind_services import (
+ ServiceBindOccupantEventMethods,
+)
+from databases import (
+ Build,
+ BuildParts,
+ BuildDecisionBook,
+ BuildDecisionBookItems,
+ BuildDecisionBookPerson,
+ BuildDecisionBookPayments,
+ BuildDecisionBookProjects,
+ BuildDecisionBookProjectPerson,
+ ApiEnumDropdown,
+ OccupantTypes,
+ Companies,
+ BuildLivingSpace,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from api_library.date_time_actions.date_functions import system_arrow, client_arrow
+
+from api_validations.validations_request import (
+ InsertBuildDecisionBookItems,
+ ListOptions,
+ ListDecisionBook,
+)
+from databases.sql_models.event.event import Services
+
+
+class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "eb36de59-8268-4d96-80b6-5d01c12bf0b1": "building_decision_book_items_list",
+ }
+ __event_validation__ = {"eb36de59-8268-4d96-80b6-5d01c12bf0b1": None}
+
+ @classmethod
+ def building_decision_book_items_list(
+ cls,
+ data: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ decision_book = BuildDecisionBook.filter_one(
+ BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
+ ).data
+ if not decision_book:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"No Decision Book is match with given UUID {data.build_decision_book_uu_id}",
+ )
+ if isinstance(token_dict, EmployeeTokenObject):
+ Build.pre_query = Build.select_action(
+ employee_id=token_dict.selected_company.employee_id,
+ filter_expr=[
+ Build.uu_id == str(decision_book.uu_id),
+ ],
+ )
+ reachable_building = Build.filter_all()
+ if not reachable_building.data:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
+ )
+
+ Companies.pre_query = Companies.select_action(
+ duty_id_list=[
+ token_dict.selected_company.duty_id,
+ token_dict.selected_company.bulk_duties_id,
+ ],
+ filter_expr=[Companies.id == decision_book.resp_company_id],
+ )
+ reachable_companies = Companies.filter_all()
+ if not reachable_companies.data:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
+ )
+ BuildDecisionBookItems.filter_attr = BuildDecisionBookItems.FilterModel(
+ **data.dump()
+ )
+ records = BuildDecisionBookItems.filter_all(
+ BuildDecisionBookItems.build_decision_book_id == decision_book.id
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="DecisionBook are listed successfully",
+ result=records,
+ )
+ # return JSONResponse(
+ # status_code=status.HTTP_200_OK,
+ # content=dict(
+ # total_count=records.count,
+ # count=len(records.data),
+ # message=f"Decision Book Items has found from given Decision Book UUID {data.build_decision_book_uu_id}",
+ # completed=True,
+ # data=[record.get_dict() for record in records.data],
+ # ),
+ # )
+ else:
+ # BuildDecisionBookItems.pre_query = BuildDecisionBookItems.select_action(
+ # occupant_id=token_dict.occupant_list["occupant_id"]
+ # )
+ # BuildDecisionBookItems.filter_attr = list_options
+ # records = BuildDecisionBookItems.filter_all(
+ # )
+ # return return_json_response_from_alchemy(response=records, pagination=list_options)
+ return
+
+
+class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "dce10509-0da5-46fb-af3c-a81d54d5481c": "building_decision_book_items_create",
+ }
+ __event_validation__ = {
+ "dce10509-0da5-46fb-af3c-a81d54d5481c": InsertBuildDecisionBookItems
+ }
+
+ @classmethod
+ def iterate_over_build_parts(
+ cls,
+ build_parts_list,
+ payment_types,
+ local_date,
+ end_date,
+ unit_price,
+ unit_type,
+ book_payment_dict,
+ unit_price_is_fixed,
+ ):
+ start_date, payment_return_dict = local_date, {}
+ for build_part_single in build_parts_list:
+ local_date = start_date
+ while local_date.is_between(start_date, end_date, "[]"):
+ local_date = system_arrow.find_last_day_of_month(local_date)
+ payment_amount = unit_price
+ if not unit_price_is_fixed:
+ unit_amount = int(build_part_single.part_net_size)
+ payment_amount = abs(unit_price * float(unit_amount)) * -1
+ payment_amount = -1 * (
+ abs(payment_amount) + (50 - float(abs(payment_amount)) % 50)
+ )
+ created_book_payment = BuildDecisionBookPayments.find_or_create(
+ build_parts_id=build_part_single.id,
+ build_parts_uu_id=str(build_part_single.uu_id),
+ payment_amount=payment_amount,
+ payment_types_id=payment_types.id,
+ payment_types_uu_id=str(payment_types.uu_id),
+ process_date=str(local_date),
+ process_date_m=int(local_date.month),
+ process_date_y=int(local_date.year),
+ period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}",
+ **book_payment_dict,
+ )
+ created_book_payment.save_and_confirm()
+ local_date = local_date.shift(days=2)
+ part_key = str(build_part_single.due_part_key).upper()
+ if part_key not in payment_return_dict:
+ payment_return_dict[part_key] = payment_amount
+ return payment_return_dict
+
+ @classmethod
+ def create_payment_records_for_each_build_part(
+ cls,
+ data_info_type,
+ build_id,
+ unit_price,
+ unit_type,
+ decision_book,
+ decision_book_item,
+ unit_price_is_fixed,
+ currency,
+ debit_start_date: str = None,
+ debit_end_date: str = None,
+ ):
+ build_parts_list = BuildParts.filter_all(
+ BuildParts.human_livable == True,
+ BuildParts.build_id == build_id,
+ )
+ print("data_info_type.key", data_info_type.key)
+ book_payment_dict = dict(
+ payment_plan_time_periods=str(data_info_type.key),
+ build_decision_book_item_id=decision_book_item.id,
+ build_decision_book_item_uu_id=str(decision_book_item.uu_id),
+ currency=currency,
+ )
+ payment_types = ApiEnumDropdown.get_debit_search(search_debit="DT-D")
+ if data_info_type.key == "BDT-D":
+ local_date = system_arrow.get(
+ system_arrow.get(decision_book.expiry_starts).date()
+ )
+ end_date = system_arrow.get(
+ system_arrow.get(decision_book.expiry_ends).date()
+ )
+ payment_return_dict = cls.iterate_over_build_parts(
+ build_parts_list=build_parts_list.data,
+ payment_types=payment_types,
+ local_date=local_date,
+ end_date=end_date,
+ unit_price=unit_price,
+ unit_type=unit_type,
+ unit_price_is_fixed=unit_price_is_fixed,
+ book_payment_dict=book_payment_dict,
+ )
+ return payment_return_dict
+ elif data_info_type.key == "BDT-A":
+ local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
+ end_date = system_arrow.get(system_arrow.get(debit_end_date).date())
+ payment_return_dict = cls.iterate_over_build_parts(
+ build_parts_list=build_parts_list.data,
+ payment_types=payment_types,
+ local_date=local_date,
+ end_date=end_date,
+ unit_price=unit_price,
+ unit_type=unit_type,
+ unit_price_is_fixed=unit_price_is_fixed,
+ book_payment_dict=book_payment_dict,
+ )
+ return payment_return_dict
+ elif data_info_type.key == "BDT-R" or data_info_type.key == "BDT-L":
+ local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
+ end_date = system_arrow.get(system_arrow.get(debit_end_date).date())
+ decision_date = system_arrow.get(decision_book.expiry_starts).date()
+ meeting_date = system_arrow.get(decision_book.meeting_date).date()
+
+ already_book_projects = BuildDecisionBookProjects.filter_all(
+ BuildDecisionBookProjects.build_decision_book_id == decision_book.id,
+ BuildDecisionBookProjects.project_type
+ == f"{decision_book.decision_type}_{data_info_type.key}",
+ system=True,
+ )
+ management_room = BuildParts.filter_one(
+ BuildParts.build_id == build_id, BuildParts.part_no == 0, system=True
+ ).data
+ occupant_man = OccupantTypes.filter_by_one(
+ system=True, occupant_code="MT-VPR", occupant_category_type="MT"
+ ).data
+ manager_living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.build_parts_id == management_room.id,
+ BuildLivingSpace.occupant_type == occupant_man.id,
+ ).data
+ if not manager_living_space:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=f"{occupant_man.occupant_description} Living Space is not found. Check manager living space and try again",
+ )
+ already_book_project_count = already_book_projects.count + 1
+ book_project_dict = dict(
+ project_no=f"{data_info_type.key}_{decision_date.year}_{already_book_project_count}",
+ project_name=f"{str(meeting_date)}_{decision_book.decision_type} Project {already_book_projects.count + 1}",
+ project_start_date=str(local_date),
+ project_stop_date=str(end_date),
+ project_type=f"{decision_book.decision_type}_{data_info_type.key}",
+ project_note=str(decision_book_item.item_comment),
+ build_decision_book_id=decision_book.id,
+ build_decision_book_uu_id=str(decision_book.uu_id),
+ build_decision_book_item_id=decision_book_item.id,
+ build_decision_book_item_uu_id=str(decision_book_item.uu_id),
+ project_response_living_space_id=manager_living_space.id,
+ project_response_living_space_uu_id=str(manager_living_space.uu_id),
+ )
+ book_project_created = BuildDecisionBookProjects.find_or_create(
+ **book_project_dict
+ )
+ book_project_created.save_and_confirm()
+ print("book_project_created", book_project_created)
+ item_comment_at_database = decision_book_item.item_comment
+ decision_book_item.update(
+ item_comment=f"{book_project_created.project_no}_{book_project_created.project_name} "
+ f"is assigned to {occupant_man.occupant_description} | {item_comment_at_database}"
+ )
+ decision_book_item.save_and_confirm()
+ project_lead = OccupantTypes.filter_by_one(
+ system=True, occupant_code="PRJ-LDR", occupant_category_type="PRJ"
+ ).data
+ build_new_president = OccupantTypes.filter_by_one(
+ system=True, occupant_code="MT-VPR", occupant_category_type="MT"
+ ).data
+
+ new_president = BuildLivingSpace.filter_one(
+ BuildLivingSpace.occupant_type == build_new_president.id,
+ BuildLivingSpace.build_parts_id == management_room.id,
+ ).data
+
+ project_leader = BuildLivingSpace.filter_one(
+ BuildLivingSpace.occupant_type == project_lead.id,
+ BuildLivingSpace.build_parts_id == management_room.id,
+ BuildLivingSpace.person_id == new_president.person_id,
+ ).data
+ if not project_leader:
+ project_leader = BuildLivingSpace.find_or_create(
+ person_id=new_president.person_id,
+ person_uu_id=str(new_president.person_uu_id),
+ build_parts_id=management_room.id,
+ build_parts_uu_id=str(management_room.uu_id),
+ occupant_type=project_lead.id,
+ occupant_type_uu_id=str(project_lead.uu_id),
+ )
+ project_leader.save_and_confirm()
+ related_service = Services.filter_by_one(
+ system=True,
+ related_responsibility=project_lead.occupant_code,
+ ).data
+ ServiceBindOccupantEventMethods.bind_services_occupant_system(
+ service_id=related_service.id,
+ build_living_space_id=project_leader.id,
+ )
+ project_person = BuildDecisionBookProjectPerson.find_or_create(
+ build_decision_book_project_id=book_project_created.id,
+ build_decision_book_project_uu_id=str(book_project_created.uu_id),
+ living_space_id=project_leader.id,
+ living_space_uu_id=str(project_leader.uu_id),
+ )
+ project_person.save_and_confirm()
+ book_project_created.update(
+ project_response_living_space_id=project_leader.id,
+ project_response_living_space_uu_id=str(project_leader.uu_id),
+ )
+ book_project_created.save()
+ return book_project_created
+ elif data_info_type.key == "BDT-S":
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="BDT-S is not implemented yet. Check info type and try again",
+ )
+ elif data_info_type.key == "BDT-I":
+ return
+ else:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Payment Info Type is not valid. Check payment type and try again",
+ )
+
+ @classmethod
+ def building_decision_book_items_create(
+ cls,
+ data: InsertBuildDecisionBookItems,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_406_NOT_ACCEPTABLE,
+ detail="No employee can reach this event. An notification is send to admin about event registration",
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ data_dict = data.dump()
+ occupant_wrt = OccupantTypes.filter_by_one(
+ system=True, occupant_code="MT-WRT", occupant_category_type="MT"
+ ).data
+
+ if token_dict.selected_occupant.occupant_type_id != occupant_wrt.id:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Only WRITER can create decision book item. Check your occupant type and try again",
+ )
+
+ decision_book_person = BuildDecisionBookPerson.filter_one(
+ BuildDecisionBookPerson.token == data.token,
+ ).data
+ decision_book = BuildDecisionBook.filter_one(
+ BuildDecisionBook.id == decision_book_person.build_decision_book_id,
+ ).data
+
+ book_items = BuildDecisionBookItems.filter_all(
+ BuildDecisionBookItems.build_decision_book_id == decision_book.id,
+ system=True,
+ )
+ if int(book_items.count) < 3:
+ BuildDecisionBookItems.check_meeting_is_valid_to_start_add_attendance(
+ decision_book=decision_book,
+ token_dict=token_dict,
+ )
+
+ book_items = BuildDecisionBookItems.filter_all(
+ BuildDecisionBookItems.build_decision_book_id == decision_book.id,
+ system=True,
+ )
+
+ data_dict["item_order"] = int(book_items.count) + 1
+ data_dict["build_decision_book_id"] = decision_book.id
+ data_dict["build_decision_book_uu_id"] = str(decision_book.uu_id)
+
+ data_info_type = ApiEnumDropdown.filter_by_one(
+ system=True,
+ enum_class="BuildDuesTypes",
+ key="BDT-I",
+ ).data
+ data_info_types = ApiEnumDropdown.due_type_search()
+ for info_type in data_info_types:
+ if str(info_type.uu_id) == data_dict["info_type_uu_id"]:
+ data_info_type = info_type
+ break
+
+ row_is_debit = str(data_info_type.key).upper() in ["BDT-A", "BDT-D"]
+ row_is_project = str(data_info_type.key).upper() in [
+ "BDT-R",
+ "BDT-L",
+ "BDT-S",
+ ]
+ debit_dates_required = (
+ not data_dict["debit_start_date"] or not data_dict["debit_end_date"]
+ )
+ if row_is_project and debit_dates_required:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Debit Start Date and Debit End Date is required for this payment type. "
+ "Check debit start date and debit end date and try again",
+ )
+
+ data_dict["info_type_id"] = data_info_type.id
+ data_dict["info_type_uu_id"] = str(data_info_type.uu_id)
+ unit_price, unit_type = float(data_dict["unit_price"]), str(
+ data_dict["unit_type"]
+ )
+
+ debit_start_date, debit_end_date = (
+ data_dict["debit_start_date"],
+ data_dict["debit_end_date"],
+ )
+ currency = data_dict["currency"]
+ del (
+ data_dict["token"],
+ data_dict["unit_price"],
+ data_dict["unit_type"],
+ data_dict["unit_price_is_fixed"],
+ data_dict["debit_start_date"],
+ data_dict["debit_end_date"],
+ data_dict["currency"],
+ )
+
+ new_decision_book_item = BuildDecisionBookItems.find_or_create(**data_dict)
+ new_decision_book_item.save_and_confirm()
+ print("new_decision_book_item", new_decision_book_item)
+ if created_payment_records_dict := cls.create_payment_records_for_each_build_part(
+ data_info_type=data_info_type,
+ build_id=decision_book.build_id,
+ unit_price=unit_price,
+ unit_type=unit_type.upper(),
+ decision_book=decision_book,
+ decision_book_item=new_decision_book_item,
+ unit_price_is_fixed=data.unit_price_is_fixed,
+ debit_start_date=debit_start_date,
+ debit_end_date=debit_end_date,
+ currency=currency,
+ ):
+ if row_is_debit:
+ if data_info_type.key == "BDT-D":
+ item_comment = "Regular Payment Plan : "
+ else:
+ item_comment = "Additional Payment Plan : "
+ for key, value in dict(
+ sorted(
+ created_payment_records_dict.items(),
+ key=lambda x: x[1],
+ reverse=True,
+ )
+ ).items():
+ item_comment += f" {key} | {abs(float(value))} {currency}, "
+ item_comment = item_comment[:-2]
+ new_decision_book_item.update(item_comment=item_comment)
+ new_decision_book_item.update(is_payment_created=True)
+ elif row_is_project:
+ project_no = str(created_payment_records_dict.project_no)
+ item_comment = (
+ f"{data.item_comment} | @ Project is created no : {project_no}."
+ )
+ new_decision_book_item.update(item_comment=item_comment)
+ new_decision_book_item.update(is_payment_created=True)
+ new_decision_book_item.save_and_confirm()
+
+ return JSONResponse(
+ status_code=status.HTTP_200_OK,
+ content=dict(
+ message=f"Decision Book Item has created for given Decision Book UUID {decision_book.uu_id}",
+ completed=True,
+ data=new_decision_book_item.get_dict(),
+ ),
+ )
+ # raise HTTPException(
+ # status_code=status.HTTP_400_BAD_REQUEST,
+ # detail="Decision Book Item is not created. Check info type and info no and try again. Unique constraint index is implemented for info type and info no",
+ # )
+
+
+class DecisionBookDecisionBookItemsUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": "building_decision_book_items_update",
+ }
+ __event_validation__ = {"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": None}
+
+ @classmethod
+ def building_decision_book_items_update(
+ cls,
+ data: InsertBuildDecisionBookItems,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+
+class DecisionBookDecisionBookItemsPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "42328809-b516-477b-82cc-2d6fadf28843": "building_decision_book_items_patch",
+ }
+ __event_validation__ = {"42328809-b516-477b-82cc-2d6fadf28843": None}
+
+ @classmethod
+ def building_decision_book_items_patch(
+ cls,
+ data: InsertBuildDecisionBookItems,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+
+DecisionBookDecisionBookItemsListEventMethod = (
+ DecisionBookDecisionBookItemsListEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/items/list")
+ )
+)
+DecisionBookDecisionBookItemsCreateEventMethod = (
+ DecisionBookDecisionBookItemsCreateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/items/create")
+ )
+)
+DecisionBookDecisionBookItemsUpdateEventMethod = (
+ DecisionBookDecisionBookItemsUpdateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/items/update")
+ )
+)
+DecisionBookDecisionBookItemsPatchEventMethod = (
+ DecisionBookDecisionBookItemsPatchEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/items/patch")
+ )
+)
+
+# if data.info_no is None:
+# data_dict["info_no"] = data_dict["item_order"]
+# elif data.occupant_types_uu_id:
+# data_dict["info_type"] = None
+# if occupant_type := OccupantTypes.find_one(
+# uu_id=data.occupant_types_uu_id
+# ):
+# if (
+# str(data.occupant_types_uu_id)
+# in OccupantTypes.get_manager_occupant_type()
+# ):
+# if BuildDecisionBookItems.find_one(
+# build_decision_book_id=decision_book.id,
+# occupant_type=occupant_type.id,
+# ):
+# raise HTTPException(
+# status_code=status.HTTP_400_BAD_REQUEST,
+# detail="This Occupant Type is already exist for given Decision Book UUID. Check occupant type and try again",
+# )
+# data_dict["occupant_type"] = occupant_type.id
+# data_dict["occupant_type_uu_id"] = str(occupant_type.uu_id)
diff --git a/api_events/events/decision_book/decision_book_decision_book_items_debits.py b/api_events/events/decision_book/decision_book_decision_book_items_debits.py
new file mode 100644
index 0000000..9678af6
--- /dev/null
+++ b/api_events/events/decision_book/decision_book_decision_book_items_debits.py
@@ -0,0 +1,105 @@
+import typing
+
+from databases import (
+ Build,
+ BuildParts,
+ BuildDecisionBook,
+ BuildDecisionBookItems,
+ BuildDecisionBookPerson,
+ BuildDecisionBookPayments,
+ BuildDecisionBookProjects,
+ BuildDecisionBookProjectPerson,
+ ApiEnumDropdown,
+ OccupantTypes,
+ Companies,
+ BuildLivingSpace,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from api_library.date_time_actions.date_functions import system_arrow, client_arrow
+
+
+class DecisionBookDecisionBookItemsDebitsListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": "decision_book_decision_book_items_debits_list",
+ }
+ __event_validation__ = {"a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": None}
+
+ @classmethod
+ def decision_book_decision_book_items_debits_list(
+ cls,
+ decision_book_id: str,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ BuildDecisionBookItems.pre_query = BuildDecisionBookItems.filter_all(
+ BuildDecisionBookItems.decision_book_id == decision_book_id,
+ ).query
+ BuildDecisionBookItems.filter_attr = None
+ records = BuildDecisionBookItems.filter_all(
+ BuildDecisionBookItems.decision_book_id == decision_book_id,
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Decision Book Items Debits are listed",
+ result=records,
+ )
+
+
+class DecisionBookDecisionBookItemsDebitsCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": "decision_book_decision_book_items_debits_create",
+ }
+ __event_validation__ = {"a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": None}
+
+ @classmethod
+ def decision_book_decision_book_items_debits_create(
+ cls,
+ decision_book_id: str,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ decision_book_items_debits: dict,
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+
+ raise HTTPException(
+ status_code=status.HTTP_406_NOT_ACCEPTABLE,
+ detail="No employee can reach this event. An notification is send to admin about event registration",
+ )
+
+ decision_book_items_debits["decision_book_id"] = decision_book_id
+ decision_book_items_debits["created_at"] = system_arrow().datetime
+ decision_book_items_debits["created_by"] = token_dict.employee_id
+ decision_book_items_debits["updated_at"] = system_arrow().datetime
+ decision_book_items_debits["updated_by"] = token_dict.employee_id
+ decision_book_items_debits["is_active"] = True
+ decision_book_items_debits["is_confirmed"] = False
+ decision_book_items_debits["is_deleted"] = False
+ decision_book_items_debits["confirmed_at"] = None
+ decision_book_items_debits["confirmed_by"] = None
+ decision_book_items_debits["deleted_at"] = None
+ decision_book_items_debits["deleted_by"] = None
+ decision_book_items_debits["confirmed_at"] = None
+ decision_book_items_debits["confirmed_by"] = None
+ decision_book_items_debits["deleted_at"] = None
+ decision_book_items_debits["deleted_by"] = None
+ decision_book_items_debits["confirmed_at"] = None
+ decision_book_items_debits["confirmed_by"] = None
+ decision_book_items_debits["deleted_at"] = None
+ decision_book_items_debits["deleted_by"] = None
+ BuildDecisionBookItems.pre_query = BuildDecisionBookItems.filter_all(
+ BuildDecisionBookItems.decision_book_id == decision_book_id,
+ ).query
+ BuildDecisionBookItems.filter_attr = None
+ records = BuildDecisionBookItems.filter_all(
+ BuildDecisionBookItems.decision_book_id == decision_book_id,
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Decision Book Items Debits are listed",
+ result=records,
+ )
diff --git a/api_events/events/decision_book/decision_book_decision_book_person.py b/api_events/events/decision_book/decision_book_decision_book_person.py
new file mode 100644
index 0000000..3755a87
--- /dev/null
+++ b/api_events/events/decision_book/decision_book_decision_book_person.py
@@ -0,0 +1,456 @@
+import typing
+
+from fastapi import status, HTTPException
+from fastapi.responses import JSONResponse
+
+from databases import (
+ BuildDecisionBook,
+ BuildDecisionBookPerson,
+ BuildDecisionBookInvitations,
+ Users,
+ BuildLivingSpace,
+ BuildParts,
+ BuildDecisionBookPersonOccupants,
+ People,
+ OccupantTypes,
+)
+
+from api_validations.validations_request import (
+ ListOptions,
+ RemoveDecisionBookPerson,
+ DecisionBookDecisionBookInvitationsAttend,
+ DecisionBookDecisionBookInvitationsUpdate,
+ DecisionBookDecisionBookInvitationsAssign,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class DecisionBookPersonListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "ea324dc0-3b08-4896-9040-7fa0401a176f": "building_decision_book_person_list",
+ }
+ __event_validation__ = {"ea324dc0-3b08-4896-9040-7fa0401a176f": None}
+
+ @classmethod
+ def building_decision_book_person_list(
+ cls,
+ data: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+
+class DecisionBookPersonAddEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "e346f720-880b-4b07-93d6-9ac76fbbaa33": "building_decision_book_person_add",
+ }
+ __event_validation__ = {
+ "e346f720-880b-4b07-93d6-9ac76fbbaa33": DecisionBookDecisionBookInvitationsUpdate
+ }
+
+ @classmethod
+ def building_decision_book_person_add(
+ cls,
+ data: DecisionBookDecisionBookInvitationsUpdate,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Employee cannot create decision book invitations",
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ decision_book = BuildDecisionBook.filter_one(
+ BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
+ ).data
+ if not decision_book:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"No Decision Book is match with given UUID {data.build_decision_book_uu_id}",
+ )
+ manager_occupant_type = OccupantTypes.filter_by_one(
+ system=True, occupant_code="BU-MNG", occupant_category_type="BU"
+ ).data
+ if (
+ not manager_occupant_type.uu_id
+ == token_dict.selected_occupant.occupant_type_uu_id
+ ):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Only Build Manager can update the invitation",
+ )
+
+ assign_occupant_type = OccupantTypes.filter_by_one(
+ system=True,
+ uu_id=data.occupant_type_uu_id,
+ occupant_category_type="MT",
+ ).data
+ if not assign_occupant_type:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
+ )
+
+ manger_book_person = BuildDecisionBookPerson.filter_one(
+ BuildDecisionBookPerson.token == data.token,
+ BuildDecisionBookPerson.build_decision_book_uu_id
+ == data.build_decision_book_uu_id,
+ ).data
+ if not manger_book_person:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Manager person not found. Please check token",
+ )
+ book_invite = BuildDecisionBookInvitations.filter_one(
+ BuildDecisionBookInvitations.id == manger_book_person.invite_id,
+ BuildDecisionBookInvitations.build_id
+ == token_dict.selected_occupant.build_id,
+ ).data
+ if not book_invite:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Invitation not found. Please check token",
+ )
+ selected_book_person = BuildDecisionBookPerson.filter_one(
+ BuildDecisionBookPerson.invite_id == book_invite.id,
+ BuildDecisionBookPerson.person_uu_id == data.person_uu_id,
+ ).data
+ if not selected_book_person:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Selected person is not in the invitation list. Please check {data.person_uu_id}",
+ )
+ selected_book_person.update(
+ occupant_type=assign_occupant_type.id,
+ occupant_type_uu_id=str(assign_occupant_type.uu_id),
+ )
+ BuildDecisionBookPerson.save()
+ return JSONResponse(
+ status_code=status.HTTP_200_OK,
+ content={
+ "completed": True,
+ "message": "Invitation is updated",
+ "data": selected_book_person.get_dict(),
+ },
+ )
+
+
+class DecisionBookPersonRemoveEventMethods(MethodToEvent):
+
+ event_type = "DELETE"
+ __event_keys__ = {
+ "30588869-04cd-48ea-ad00-0e4f8dd7f735": "building_decision_book_people_remove",
+ }
+ __event_validation__ = {
+ "30588869-04cd-48ea-ad00-0e4f8dd7f735": RemoveDecisionBookPerson
+ }
+
+ @classmethod
+ def building_decision_book_people_remove(
+ cls, data: RemoveDecisionBookPerson, token_dict: EmployeeTokenObject
+ ):
+ return
+
+
+class DecisionBookPersonAttendEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "bdcba521-0116-441c-ace1-84c5b68c86c7": "decision_book_invitations_attend",
+ }
+ __event_validation__ = {
+ "bdcba521-0116-441c-ace1-84c5b68c86c7": DecisionBookDecisionBookInvitationsAttend
+ }
+
+ @classmethod
+ def decision_book_invitations_attend(
+ cls,
+ data: DecisionBookDecisionBookInvitationsAttend,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Employee cannot create decision book invitations",
+ )
+
+ token_user = Users.filter_one(Users.id == token_dict.user_id).data
+ invitation_person = BuildDecisionBookPerson.filter_one(
+ BuildDecisionBookPerson.token == data.token,
+ ).data
+ if not invitation_person:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Invitation for the this specific user is not found. Please check token",
+ )
+
+ # is_token_valid = token_dict.person_id == invitation_person.person_id
+ # if not invitation_person.vicarious_person_id:
+ # if not invitation_person or not is_token_valid:
+ # raise HTTPException(
+ # status_code=status.HTTP_404_NOT_FOUND,
+ # detail=f"Invitation for the user {token_user.email} is not valid. Please check token",
+ # )
+ # todo check if vicarious person is valid
+ invitation = BuildDecisionBookInvitations.filter_one(
+ BuildDecisionBookInvitations.id == invitation_person.invite_id,
+ BuildDecisionBookInvitations.build_id
+ == token_dict.selected_occupant.build_id,
+ ).data
+ if not invitation:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Invitation not found. Please check invitation uuid : {invitation.uu_id}",
+ )
+ invitation_person.update(
+ is_attending=bool(data.is_attend), vicarious_person_id=None
+ )
+ BuildDecisionBookInvitations.save()
+ return JSONResponse(
+ status_code=status.HTTP_200_OK,
+ content={
+ "completed": True,
+ "message": "Attendance is updated. Thank you for your response",
+ "data": {
+ "is_attending": bool(data.is_attend),
+ "user_uuid": str(token_user.uu_id),
+ "invitation_uuid": str(invitation.uu_id),
+ },
+ },
+ )
+
+
+class DecisionBookPersonAssignOccupantEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "c0b65098-9c79-4212-b1d0-c7e7836cf141": "decision_book_invitations_assign_occupant",
+ }
+ __event_validation__ = {
+ "c0b65098-9c79-4212-b1d0-c7e7836cf141": DecisionBookDecisionBookInvitationsAssign
+ }
+
+ @classmethod
+ def decision_book_invitations_assign_occupant(
+ cls,
+ data: DecisionBookDecisionBookInvitationsAssign,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Employee cannot create decision book invitations",
+ )
+
+ book_person_manager = BuildDecisionBookPerson.filter_one(
+ BuildDecisionBookPerson.token == data.token,
+ BuildDecisionBookPerson.build_living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ ).data
+ manager_occupant_type = OccupantTypes.filter_by_one(
+ system=True, occupant_code="BU-MNG", occupant_category_type="BU"
+ ).data
+ book_person_manager.check_occupant_type(manager_occupant_type)
+
+ # supervisor_occupant_type = OccupantTypes.find_or_abort(occupant_code="BU-SPV", occupant_category_type="BU")
+ # book_person_supervisor.check_occupant_type(supervisor_occupant_type)
+
+ invitation = BuildDecisionBookInvitations.filter_one(
+ BuildDecisionBookInvitations.id == book_person_manager.invite_id,
+ BuildDecisionBookInvitations.build_id
+ == token_dict.selected_occupant.build_id,
+ ).data
+ if not invitation:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Invitation not found. Please check token",
+ )
+
+ assign_occupant_type = OccupantTypes.filter_by_one(
+ system=True,
+ uu_id=data.occupant_type_uu_id,
+ ).data
+ if not assign_occupant_type:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
+ )
+
+ build_parts_of_token = BuildParts.filter_all(
+ BuildParts.build_id == token_dict.selected_occupant.build_id,
+ ).data
+ selected_living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.uu_id == data.build_living_space_uu_id,
+ BuildLivingSpace.build_parts_id.in_(
+ [build.id for build in build_parts_of_token]
+ ),
+ ).data
+ if not selected_living_space:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Person not found. Please check person uuid",
+ )
+
+ book_person_to_assign: BuildDecisionBookPerson = (
+ BuildDecisionBookPerson.filter_one(
+ BuildDecisionBookPerson.build_living_space_id
+ == selected_living_space.id,
+ BuildDecisionBookPerson.invite_id == invitation.id,
+ ).data
+ )
+ if not book_person_to_assign:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Person not found in the invitation list. Please check person uuid: {data.build_living_space_uu_id}",
+ )
+ if not book_person_to_assign.is_attending:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=f"Person is declined the invitation. This person is not attending the meeting. "
+ f"Please check person uuid: {data.build_living_space_uu_id}. Invite UUID: {invitation.uu_id}",
+ )
+
+ if assign_occupant_type.occupant_code in ("MT-PRS", "MT-WRT"):
+ occupant_type_unique = OccupantTypes.filter_by_one(
+ system=True,
+ occupant_code=assign_occupant_type.occupant_code,
+ occupant_category_type="MT",
+ ).data
+ if assigned_book_person_occupant := BuildDecisionBookPersonOccupants.filter_one(
+ BuildDecisionBookPersonOccupants.invite_id == invitation.id,
+ BuildDecisionBookPersonOccupants.occupant_type_id
+ == occupant_type_unique.id,
+ ).data:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=f"Only one person can be assigned to {assign_occupant_type.occupant_code} type"
+ f" {assigned_book_person_occupant.uu_id} is already assigned",
+ )
+
+ if assign_occupant_type.occupant_code == "BU-MNG":
+ person_occupant_manager = BuildDecisionBookPersonOccupants.filter_one(
+ BuildDecisionBookPersonOccupants.invite_id == invitation.id,
+ BuildDecisionBookPersonOccupants.occupant_type_id
+ == manager_occupant_type.id,
+ )
+ person_occupant_manager.query.delete()
+
+ book_person_to_assign.add_occupant_type(
+ occupant_type=assign_occupant_type,
+ build_living_space_id=selected_living_space.id,
+ )
+ BuildDecisionBookPersonOccupants.save()
+ return JSONResponse(
+ status_code=status.HTTP_200_OK,
+ content={
+ "completed": True,
+ "message": "Invitation is updated",
+ "data": book_person_to_assign.get_dict(),
+ },
+ )
+
+
+DecisionBookPersonListEventMethod = DecisionBookPersonListEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/people/list")
+)
+DecisionBookPersonAddEventMethod = DecisionBookPersonAddEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/people/add")
+)
+DecisionBookPersonRemoveEventMethod = DecisionBookPersonRemoveEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/people/remove")
+)
+DecisionBookPersonAttendEventMethod = DecisionBookPersonAttendEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/invitations/attend")
+)
+DecisionBookPersonAssignOccupantEventMethod = (
+ DecisionBookPersonAssignOccupantEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/invitations/assign")
+ )
+)
+
+# Build.pre_query = Build.select_action(
+# employee_id=token_dict.selected_company.employee_id,
+# filter_expr=[
+# Build.id == decision_book.build_id,
+# ],
+# )
+# reachable_building = Build.filter_all()
+# if not reachable_building.data:
+# raise HTTPException(
+# status_code=status.HTTP_404_NOT_FOUND,
+# detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
+# )
+#
+# Companies.pre_query = Companies.select_action(
+# duty_id_list=[
+# token_dict.selected_company.duty_id,
+# token_dict.selected_company.bulk_duties_id,
+# ],
+# filter_expr=[Companies.id == decision_book.resp_company_id],
+# )
+# reachable_companies = Companies.filter_all()
+# if not reachable_companies.data:
+# raise HTTPException(
+# status_code=status.HTTP_404_NOT_FOUND,
+# detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
+# )
+# person_to_add = People.find_one(uu_id=data.person_uu_id)
+# if not person_to_add:
+# raise HTTPException(
+# status_code=status.HTTP_404_NOT_FOUND,
+# detail=f"No person is match with given UUID {data.person_uu_id}",
+# )
+# management_typecode = ApiEnumDropdown.filter_all(
+# ApiEnumDropdown.uu_id == data.management_typecode_uu_id,
+# ApiEnumDropdown.enum_class.in_("BuildManagementType", "BuildDuesTypes"),
+# )
+# if not management_typecode.data:
+# raise HTTPException(
+# status_code=status.HTTP_404_NOT_FOUND,
+# detail=f"No management type is match with given UUID {data.management_typecode_uu_id}",
+# )
+# condition_to_met = (
+# data.management_typecode_uu_id
+# in ApiEnumDropdown.get_management_type_codes_list()
+# )
+# any_type_already = BuildDecisionBookPerson.find_one(
+# build_decision_book_id=decision_book.id,
+# management_typecode=data.management_typecode_uu_id,
+# )
+# if condition_to_met and any_type_already:
+# raise HTTPException(
+# status_code=status.HTTP_400_BAD_REQUEST,
+# detail=f"Management type is already exist in given Decision Book UUID {data.build_decision_book_uu_id}.",
+# )
+#
+# data_dict.pop("build_decision_book_uu_id", None)
+# data_dict.pop("person_uu_id", None)
+# data_dict["management_typecode"] = data_dict.pop(
+# "management_typecode_uu_id", None
+# )
+# data_dict["build_decision_book_id"] = decision_book.id
+# data_dict["person_id"] = person_to_add.id
+#
+# created = BuildDecisionBookPerson.find_or_create(**data_dict)
+# if created.is_found:
+# raise HTTPException(
+# status_code=status.HTTP_400_BAD_REQUEST,
+# detail=f"Decision Book Person is already exist in given Decision Book UUID {data.build_decision_book_uu_id}.",
+# )
+# return JSONResponse(
+# status_code=status.HTTP_200_OK,
+# content=dict(
+# message=f"Decision Book Person has added for given Decision Book UUID {data.build_decision_book_uu_id}",
+# completed=True,
+# data=created.get_dict(),
+# ),
+# )
diff --git a/api_events/events/decision_book/decision_book_invitations.py b/api_events/events/decision_book/decision_book_invitations.py
new file mode 100644
index 0000000..b782e81
--- /dev/null
+++ b/api_events/events/decision_book/decision_book_invitations.py
@@ -0,0 +1,282 @@
+import typing
+
+from fastapi import status, HTTPException
+from fastapi.responses import JSONResponse
+
+from databases import (
+ Build,
+ BuildLivingSpace,
+ BuildParts,
+ BuildDecisionBookInvitations,
+ BuildDecisionBookPerson,
+ BuildDecisionBook,
+ BuildDecisionBookPersonOccupants,
+ OccupantTypes,
+ Users,
+ ApiEnumDropdown,
+)
+
+from api_validations.validations_request import (
+ DecisionBookDecisionBookInvitationsUpdate,
+ DecisionBookDecisionBookInvitations,
+)
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from api_library.date_time_actions.date_functions import system_arrow
+
+
+class BuildDecisionBookInvitationsListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "e2277528-8c9c-4c0c-ae64-3ce80cae664b": "decision_book_invitations_list",
+ }
+ __event_validation__ = {"e2277528-8c9c-4c0c-ae64-3ce80cae664b": None}
+
+ @classmethod
+ def decision_book_invitations_list(
+ cls,
+ data,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+
+class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "d0bfa20c-841d-421c-98e6-d308f938d16a": "decision_book_invitations_create",
+ }
+ __event_validation__ = {
+ "d0bfa20c-841d-421c-98e6-d308f938d16a": DecisionBookDecisionBookInvitations
+ }
+
+ @classmethod
+ def decision_book_invitations_create(
+ cls,
+ data: DecisionBookDecisionBookInvitations,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Employee cannot create decision book invitations",
+ )
+ # Check token posses the occupant type of Build Manager
+ occupant_manager = OccupantTypes.filter_by_one(
+ system=True, occupant_category_type="BU", occupant_code="BU-MNG"
+ ).data
+ if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail="Only Build Manager can create decision book",
+ )
+
+ # Check decision book is valid for this token and building
+ decision_book = BuildDecisionBook.filter_one(
+ BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
+ BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
+ ).data
+ if not decision_book:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Decision book not found. Please create decision book first",
+ )
+ occupant_building = Build.filter_one(
+ Build.id == token_dict.selected_occupant.build_id
+ ).data
+
+ # Check planned decision book date is valid
+ if (
+ not system_arrow.get(data.planned_date).date()
+ >= system_arrow.now().shift(days=1).date()
+ ):
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Planned date must be greater than today",
+ )
+
+ # Create an invitation for specific invitation type to start invite sending process
+ planned_date_expires = str(
+ system_arrow.get(data.planned_date).shift(days=15).date()
+ )
+ book_invitation = BuildDecisionBookInvitations.find_or_create(
+ build_id=token_dict.selected_occupant.build_id,
+ build_uu_id=token_dict.selected_occupant.build_uuid,
+ decision_book_id=decision_book.id,
+ decision_book_uu_id=str(decision_book.uu_id),
+ invitation_type=str(decision_book.decision_type),
+ living_part_count=occupant_building.livable_part_count,
+ living_part_percentage=0.51,
+ message=data.message,
+ planned_date=str(system_arrow.get(data.planned_date)),
+ planned_date_expires=planned_date_expires,
+ expiry_ends=str(system_arrow.get(data.planned_date).shift(days=15).date()),
+ )
+ book_invitation.save_and_confirm()
+
+ # Get all the parts of the building that is occupant in token
+ build_parts = BuildParts.filter_all(
+ BuildParts.build_id == occupant_building.id,
+ )
+
+ # Get all build living spaces that is found in building with distinct person id
+ occupants = OccupantTypes.filter_all(system=True)
+ BuildLivingSpace.filter_attr = None
+ build_living_spaces_people = (
+ BuildLivingSpace.filter_all(
+ BuildLivingSpace.build_parts_id.in_(
+ [build_part.id for build_part in build_parts.data]
+ ),
+ BuildLivingSpace.occupant_type.in_(
+ [occupant.id for occupant in occupants.data]
+ ),
+ )
+ .query.distinct(BuildLivingSpace.person_id)
+ .all()
+ )
+ if not build_living_spaces_people:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="No living spaces found for the building",
+ )
+ print(
+ f"Tnvite UUID : {book_invitation.uu_id} Message : {data.message} Planned date : {data.planned_date}"
+ )
+
+ # Send invitation to all the users as attend and update the manager as build manager
+ attendance_occupant_type = OccupantTypes.filter_by_one(
+ system=True, occupant_code="MT-ATT", occupant_category_type="MT"
+ ).data
+ manager_occupant_type = OccupantTypes.filter_by_one(
+ system=True, occupant_code="BU-MNG", occupant_category_type="BU"
+ ).data
+
+ build_decision_book_person_dict = dict(
+ build_decision_book_id=decision_book.id,
+ build_decision_book_uu_id=str(decision_book.uu_id),
+ invite_id=book_invitation.id,
+ invite_uu_id=str(book_invitation.uu_id),
+ send_date=str(system_arrow.now().date()),
+ expiry_starts=decision_book.expiry_starts,
+ expiry_ends=decision_book.expiry_ends,
+ )
+ # Check if the invitation is already created at database
+ for build_living_spaces_user in build_living_spaces_people:
+ if invite := BuildDecisionBookPerson.filter_one(
+ BuildDecisionBookPerson.invite_id == book_invitation.id,
+ BuildDecisionBookPerson.build_living_space_id
+ == build_living_spaces_user.id,
+ ).data:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=f"Invitation already send to {build_living_spaces_user.email} "
+ f"for invite {invite.uu_id} date : {str(book_invitation.planned_date)}",
+ )
+
+ invitations_person = BuildDecisionBookPerson.find_or_create(
+ **build_decision_book_person_dict,
+ build_living_space_id=build_living_spaces_user.id,
+ build_living_space_uu_id=str(build_living_spaces_user.uu_id),
+ person_id=build_living_spaces_user.person_id,
+ token=Users.generate_token(40),
+ )
+ invitations_person.save_and_confirm()
+
+ invitations_person.add_occupant_type(occupant_type=attendance_occupant_type)
+ if invitations_person:
+ print(f'"{invitations_person.token}",')
+ spaces_user = Users.filter_one(
+ Users.person_id == build_living_spaces_user.person_id,
+ ).data
+ # print(
+ # f"Invitation is send : {spaces_user.email} "
+ # f"Token : {invitations_person.token} "
+ # f"Send Date : {str(invitations_person.send_date.date())}"
+ # )
+
+ manager_living_spaces = BuildLivingSpace.filter_all(
+ BuildLivingSpace.person_id == token_dict.person_id,
+ )
+ manager_people = BuildDecisionBookPerson.filter_all(
+ BuildDecisionBookPerson.invite_id == book_invitation.id,
+ BuildDecisionBookPerson.build_living_space_id.in_(
+ [
+ manager_living_space.id
+ for manager_living_space in manager_living_spaces.data
+ ]
+ ),
+ system=True,
+ )
+ manager_people_occupants = BuildDecisionBookPersonOccupants.filter_all(
+ BuildDecisionBookPersonOccupants.build_decision_book_person_id
+ == manager_people.get(1).id,
+ system=True,
+ )
+ if manager_people_occupants.count:
+ manager_people_occupants.query.delete()
+ BuildDecisionBookPersonOccupants.save()
+ if manager_people.count:
+ manager_people.query.delete()
+ BuildDecisionBookPerson.save()
+
+ if book_person_manager := BuildDecisionBookPerson.find_or_create(
+ **build_decision_book_person_dict,
+ build_living_space_id=token_dict.selected_occupant.living_space_id,
+ build_living_space_uu_id=str(
+ token_dict.selected_occupant.living_space_uu_id
+ ),
+ person_id=token_dict.person_id,
+ token=Users.generate_token(40),
+ ):
+ book_person_manager.save_and_confirm()
+ book_person_manager.add_occupant_type(occupant_type=manager_occupant_type)
+ print(f"Manager Token : {book_person_manager.token}")
+ BuildDecisionBookPerson.save()
+ return JSONResponse(
+ status_code=status.HTTP_200_OK,
+ content={
+ "completed": True,
+ "message": "Invitation are send to people related with building",
+ "data": book_invitation.get_dict(),
+ },
+ )
+
+
+class BuildDecisionBookInvitationsUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "92413636-53a8-4a05-842c-1485a64e00d1": "decision_book_invitations_attend",
+ }
+ __event_validation__ = {
+ "92413636-53a8-4a05-842c-1485a64e00d1": DecisionBookDecisionBookInvitationsUpdate
+ }
+
+ @classmethod
+ def decision_book_invitations_attend(
+ cls,
+ data: DecisionBookDecisionBookInvitationsUpdate,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+
+BuildDecisionBookInvitationsListEventMethod = (
+ BuildDecisionBookInvitationsListEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/invite/list")
+ )
+)
+BuildDecisionBookInvitationsCreateEventMethod = (
+ BuildDecisionBookInvitationsCreateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/invite/create")
+ )
+)
+BuildDecisionBookInvitationsUpdateEventMethod = (
+ BuildDecisionBookInvitationsUpdateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/invite/update")
+ )
+)
diff --git a/api_events/events/decision_book/decision_book_payment.py b/api_events/events/decision_book/decision_book_payment.py
new file mode 100644
index 0000000..79b503f
--- /dev/null
+++ b/api_events/events/decision_book/decision_book_payment.py
@@ -0,0 +1,169 @@
+from typing import Union
+
+from fastapi.responses import JSONResponse
+from fastapi import status
+
+from api_validations.validations_response.parts import BuildPartsListResponse
+from databases import (
+ Build,
+ BuildParts,
+)
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+from api_validations.validations_request import (
+ InsertBuildParts,
+ UpdateBuildParts,
+ ListOptions,
+)
+from databases.sql_models.building.decision_book import BuildDecisionBookPayments
+
+
+class DecisionBookPaymentListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "49bb8ab8-520d-4676-a159-aaf84f37f372": "decision_book_payment_list"
+ }
+ __event_validation__ = {"49bb8ab8-520d-4676-a159-aaf84f37f372": None}
+
+ @classmethod
+ def decision_book_payment_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ """
+ SELECT payment_plan_time_periods, process_date, payment_amount, currency, payment_types_id,
+ payment_types_uu_id, period_time, process_date_y, process_date_m, build_decision_book_item_id,
+ build_decision_book_item_uu_id, decision_book_project_id, decision_book_project_uu_id, build_parts_id,
+ build_parts_uu_id, id, uu_id, ref_id, created_at, updated_at, cryp_uu_id, created_by, created_by_id,
+ updated_by, updated_by_id, confirmed_by, confirmed_by_id, is_confirmed, replication_id, deleted,
+ active, is_notification_send, is_email_send, expiry_starts, expiry_ends, account_records_id,
+ account_records_uu_id FROM public.build_decision_book_payments;
+ """
+ from sqlalchemy import func, select, union_all, extract, Integer
+
+ build_parts_id, build_decision_book_id = 7, ""
+ payment_types_id_recv, payment_types_id_deb = 46, 45
+
+ BuildDecisionBookPayments.filter_attr = list_options
+ # Define the subqueries
+ debit_subquery = (
+ select(
+ BuildDecisionBookPayments.payment_plan_time_periods,
+ func.sum(BuildDecisionBookPayments.payment_amount).label("debit"),
+ func.cast(0, Integer).label("recv"),
+ func.max(BuildDecisionBookPayments.process_date).label("ls"),
+ )
+ .where(
+ BuildDecisionBookPayments.build_parts_id == build_parts_id,
+ BuildDecisionBookPayments.payment_types_id == payment_types_id_deb,
+ BuildDecisionBookPayments.build_decision_book_id
+ == build_decision_book_id,
+ extract("year", func.current_date())
+ == extract("year", BuildDecisionBookPayments.process_date),
+ extract("month", func.current_date())
+ == extract("month", BuildDecisionBookPayments.process_date),
+ )
+ .group_by(BuildDecisionBookPayments.payment_plan_time_periods)
+ )
+
+ recv_subquery = (
+ select(
+ BuildDecisionBookPayments.payment_plan_time_periods,
+ func.cast(0, Integer).label("debit"),
+ func.sum(BuildDecisionBookPayments.payment_amount).label("recv"),
+ func.max(BuildDecisionBookPayments.process_date).label("ls"),
+ )
+ .where(
+ BuildDecisionBookPayments.build_parts_id == build_parts_id,
+ BuildDecisionBookPayments.payment_types_id == payment_types_id_recv,
+ BuildDecisionBookPayments.build_decision_book_id
+ == build_decision_book_id,
+ extract("year", func.current_date())
+ == extract("year", BuildDecisionBookPayments.process_date),
+ extract("month", func.current_date())
+ == extract("month", BuildDecisionBookPayments.process_date),
+ )
+ .group_by(BuildDecisionBookPayments.payment_plan_time_periods)
+ )
+
+ # Combine the subqueries using union_all
+ combined_subquery = union_all(debit_subquery, recv_subquery).alias("AA")
+
+ # Final query
+ final_query = select(
+ combined_subquery.c.payment_plan_time_periods,
+ func.sum(combined_subquery.c.debit).label("debit"),
+ func.sum(combined_subquery.c.recv).label("recv"),
+ combined_subquery.c.ls.label("Last Seen"),
+ ).group_by(
+ combined_subquery.c.payment_plan_time_periods, combined_subquery.c.ls
+ )
+
+ # Execute the query
+ book_payments_month = BuildDecisionBookPayments.session.execute(
+ final_query
+ ).fetchall()
+ print("book_payments_month", book_payments_month)
+
+ debit_subquery = (
+ select(
+ BuildDecisionBookPayments.payment_plan_time_periods,
+ func.sum(BuildDecisionBookPayments.payment_amount).label("debit"),
+ func.cast(0, Integer).label("recv"),
+ func.max(BuildDecisionBookPayments.process_date).label("ls"),
+ )
+ .where(
+ BuildDecisionBookPayments.build_parts_id == build_parts_id,
+ BuildDecisionBookPayments.payment_types_id == payment_types_id_deb,
+ BuildDecisionBookPayments.build_decision_book_id
+ == build_decision_book_id,
+ )
+ .group_by(BuildDecisionBookPayments.payment_plan_time_periods)
+ )
+
+ recv_subquery = (
+ select(
+ BuildDecisionBookPayments.payment_plan_time_periods,
+ func.cast(0, Integer).label("debit"),
+ func.sum(BuildDecisionBookPayments.payment_amount).label("recv"),
+ func.max(BuildDecisionBookPayments.process_date).label("ls"),
+ )
+ .where(
+ BuildDecisionBookPayments.build_parts_id == build_parts_id,
+ BuildDecisionBookPayments.payment_types_id == payment_types_id_recv,
+ BuildDecisionBookPayments.build_decision_book_id
+ == build_decision_book_id,
+ )
+ .group_by(BuildDecisionBookPayments.payment_plan_time_periods)
+ )
+
+ # Combine the subqueries using union_all
+ combined_subquery = union_all(debit_subquery, recv_subquery).alias("AA")
+
+ # Final query
+ final_query = select(
+ combined_subquery.c.payment_plan_time_periods,
+ func.sum(combined_subquery.c.debit).label("debit"),
+ func.sum(combined_subquery.c.recv).label("recv"),
+ combined_subquery.c.ls.label("Last Seen"),
+ ).group_by(
+ combined_subquery.c.payment_plan_time_periods, combined_subquery.c.ls
+ )
+
+ # Execute the query
+ book_payments = BuildDecisionBookPayments.session.execute(
+ final_query
+ ).fetchall()
+ print("book_payments", book_payments)
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Building Parts Records are listed",
+ result=[book_payments, book_payments_month],
+ cls_object=BuildParts,
+ response_model=BuildPartsListResponse,
+ filter_attributes=list_options,
+ )
diff --git a/api_events/events/decision_book/project_decision_book.py b/api_events/events/decision_book/project_decision_book.py
new file mode 100644
index 0000000..e22f90a
--- /dev/null
+++ b/api_events/events/decision_book/project_decision_book.py
@@ -0,0 +1,372 @@
+from typing import Union
+
+from api_library.date_time_actions.date_functions import system_arrow, client_arrow
+from databases import (
+ BuildDecisionBookProjects,
+ BuildDecisionBookProjectPerson,
+ BuildDecisionBookPayments,
+ OccupantTypes,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.validations_request import (
+ InsertBuildDecisionBookProjects,
+ UpdateBuildDecisionBookProjects,
+ ApprovalsBuildDecisionBookProjects,
+ ListOptions,
+)
+from api_validations.core_response import AlchemyJsonResponse
+from databases import Build, BuildLivingSpace, BuildParts, ApiEnumDropdown
+from databases.sql_models.building.decision_book import (
+ BuildDecisionBookProjectItems,
+ BuildDecisionBookItems,
+ BuildDecisionBook,
+)
+
+
+class ProjectDecisionBookListEventMethods(MethodToEvent):
+
+ event_type = "LIST"
+
+ __event_keys__ = {
+ "96459b36-37f2-4d5b-8370-c459058d5bce": "project_decision_book_list",
+ }
+ __event_validation__ = {"96459b36-37f2-4d5b-8370-c459058d5bce": None}
+
+ @classmethod
+ def project_decision_book_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ build_decision_book = BuildDecisionBook.filter_one(
+ BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
+ ).data
+ if not build_decision_book:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message="Build decision book not found",
+ data={},
+ )
+ BuildDecisionBookProjects.filter_attr = list_options
+ decision_book_projects = BuildDecisionBookProjects.filter_all(
+ BuildDecisionBookProjects.build_decision_book_id
+ == build_decision_book.id,
+ )
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision book created successfully",
+ result=decision_book_projects,
+ )
+
+
+class ProjectDecisionBookCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+
+ __event_keys__ = {
+ "b8e44bb2-f157-4dd5-8a24-0e02db4877c9": "project_decision_book_create",
+ }
+ __event_validation__ = {
+ "b8e44bb2-f157-4dd5-8a24-0e02db4877c9": InsertBuildDecisionBookProjects
+ }
+
+ @classmethod
+ def project_decision_book_create(
+ cls,
+ data: InsertBuildDecisionBookProjects,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.id == token_dict.selected_occupant.living_space_id,
+ ).data
+ if not living_space:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message="Living space not found",
+ data={},
+ )
+
+ occupant_type = OccupantTypes.filter_by_one(
+ occupant_category_type="PRJ",
+ occupant_code="PRJ-LDR",
+ id=living_space.occupant_type,
+ ).data
+ if not occupant_type:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message=f"{token_dict.selected_occupant.occupant_type_uu_id} occupant type is not allowed, only PRJ-LDR occupant type is allowed",
+ data={},
+ )
+ decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
+ BuildDecisionBookProjectPerson.living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ )
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision book created successfully",
+ result=decision_book_project_person,
+ )
+
+
+class ProjectDecisionBookUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+
+ __event_keys__ = {
+ "bfe3ef13-030f-495f-b692-94bcb746d700": "project_decision_book_update",
+ }
+ __event_validation__ = {
+ "bfe3ef13-030f-495f-b692-94bcb746d700": UpdateBuildDecisionBookProjects
+ }
+
+ @classmethod
+ def project_decision_book_update(
+ cls,
+ data: UpdateBuildDecisionBookProjects,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.id == token_dict.selected_occupant.living_space_id,
+ ).data
+ if not living_space:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message="Living space not found",
+ data={},
+ )
+ occupant_type = OccupantTypes.filter_by_one(
+ occupant_category_type="PRJ",
+ occupant_code="PRJ-LDR",
+ id=living_space.occupant_type,
+ ).data
+ if not occupant_type:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message=f"{token_dict.selected_occupant.occupant_type_uu_id} occupant type is not allowed, only PRJ-LDR occupant type is allowed",
+ data={},
+ )
+ decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
+ BuildDecisionBookProjectPerson.build_decision_book_project_uu_id
+ == data.build_decision_book_project_uu_id,
+ BuildDecisionBookProjectPerson.living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ ).data
+ if not decision_book_project_person:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message="This project is not allowed for this occupant",
+ data={},
+ )
+ decision_book_project = BuildDecisionBookProjects.filter_one(
+ BuildDecisionBookProjects.id
+ == decision_book_project_person.build_decision_book_project_id,
+ )
+ if decision_book_project.is_completed:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Project decision book is closed. No modification is allowed",
+ data={},
+ )
+ data_dict = data.excluded_dump()
+ decision_book_project.update(**data_dict)
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision book created successfully",
+ result=decision_book_project_person,
+ )
+
+
+class ProjectDecisionBookApprovalEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+
+ __event_keys__ = {
+ "a83a83fe-8446-4c60-9ae5-d1c06adbf626": "project_decision_book_approval",
+ }
+ __event_validation__ = {
+ "a83a83fe-8446-4c60-9ae5-d1c06adbf626": ApprovalsBuildDecisionBookProjects
+ }
+
+ @classmethod
+ def project_decision_book_approval(
+ cls,
+ data: ApprovalsBuildDecisionBookProjects,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ BuildDecisionBookPayments.client_arrow = client_arrow
+ BuildDecisionBookPayments.client_arrow.timezone = token_dict.timezone or "GMT+3"
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.id == token_dict.selected_occupant.living_space_id,
+ ).data
+ if not living_space:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message="Living space not found",
+ data={},
+ )
+ occupant_type = OccupantTypes.filter_by_one(
+ system=True,
+ occupant_category_type="PRJ",
+ occupant_code="PRJ-LDR",
+ id=living_space.occupant_type,
+ ).data
+ if not occupant_type:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message=f"{token_dict.selected_occupant.occupant_type_uu_id} occupant type is not allowed, only PRJ-LDR occupant type is allowed",
+ data={},
+ )
+ decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
+ BuildDecisionBookProjectPerson.build_decision_book_project_uu_id
+ == data.build_decision_book_project_uu_id,
+ BuildDecisionBookProjectPerson.living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ ).data
+ if not decision_book_project_person:
+ raise BuildDecisionBookProjectPerson.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message="This project is not allowed for this occupant",
+ data={},
+ )
+
+ decision_book_project = BuildDecisionBookProjects.filter_one(
+ BuildDecisionBookProjects.id
+ == decision_book_project_person.build_decision_book_project_id,
+ ).data
+ if decision_book_project.is_completed:
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Project decision book is closed. No modification is allowed",
+ data={},
+ )
+ data_dict = data.excluded_dump()
+ data_dict["is_completed"] = True
+
+ build_parts_list = BuildParts.filter_all(
+ BuildParts.human_livable == True,
+ BuildParts.build_id == token_dict.selected_occupant.build_id,
+ ).data
+
+ decision_book_project_item = BuildDecisionBookItems.filter_one(
+ BuildDecisionBookItems.id
+ == decision_book_project.build_decision_book_item_id
+ ).data
+
+ book_payment_dict = dict(
+ build_decision_book_item_id=decision_book_project_item.id,
+ build_decision_book_item_uu_id=str(decision_book_project_item.uu_id),
+ currency=decision_book_project.currency,
+ )
+ payment_type = ApiEnumDropdown.get_debit_search(search_debit="DT-D")
+ for final_price in data.final_price_list or []:
+ for build_part_single in build_parts_list:
+ local_date = BuildDecisionBookPayments.client_arrow.get(
+ str(final_price["date"])
+ )
+ local_date = system_arrow.get(local_date)
+ payment_amount = abs(float(final_price["price"])) * -1
+ created_book_payment = BuildDecisionBookPayments.find_or_create(
+ build_parts_id=build_part_single.id,
+ build_parts_uu_id=str(build_part_single.uu_id),
+ payment_amount=payment_amount,
+ payment_types_id=payment_type.id,
+ payment_types_uu_id=str(payment_type.uu_id),
+ process_date=str(local_date),
+ process_date_m=int(local_date.month),
+ process_date_y=int(local_date.year),
+ payment_plan_time_periods=str(
+ decision_book_project.project_type
+ ),
+ period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}",
+ decision_book_project_id=decision_book_project.id,
+ decision_book_project_uu_id=str(decision_book_project.uu_id),
+ **book_payment_dict,
+ )
+ created_book_payment.save_and_confirm()
+ updated_decision_book_project = decision_book_project.update(**data_dict)
+ updated_decision_book_project.save_and_confirm()
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision book created successfully",
+ result=updated_decision_book_project,
+ )
+
+
+class ProjectDecisionBookPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+
+ __event_keys__ = {
+ "444d67a0-b3a8-4ca2-9d8d-f1acc75011e0": "project_decision_book_patch",
+ }
+ __event_validation__ = {"444d67a0-b3a8-4ca2-9d8d-f1acc75011e0": None}
+
+ @classmethod
+ def project_decision_book_patch(
+ cls,
+ data,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+
+ProjectDecisionBookListEventMethod = ProjectDecisionBookListEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/list")
+)
+ProjectDecisionBookCreateEventMethod = ProjectDecisionBookCreateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/create")
+)
+ProjectDecisionBookUpdateEventMethod = ProjectDecisionBookUpdateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/update")
+)
+ProjectDecisionBookApprovalEventMethod = ProjectDecisionBookApprovalEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/approval")
+)
+ProjectDecisionBookPatchEventMethod = ProjectDecisionBookPatchEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/patch")
+)
diff --git a/api_events/events/decision_book/project_decision_book_items.py b/api_events/events/decision_book/project_decision_book_items.py
new file mode 100644
index 0000000..5c1d522
--- /dev/null
+++ b/api_events/events/decision_book/project_decision_book_items.py
@@ -0,0 +1,156 @@
+from typing import Union
+
+from databases import (
+ BuildDecisionBookProjectItems,
+ BuildDecisionBookProjectPerson,
+)
+
+from api_validations.validations_request import (
+ InsertBuildDecisionBookProjectItems,
+ UpdateBuildDecisionBookProjectItems,
+ ListOptions,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from databases.sql_models.building.decision_book import BuildDecisionBookProjects
+
+
+class BuildDecisionBookProjectItemsListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "ce3630e4-2bf9-4433-bdab-1ee72117e54b": "build_decision_book_project_items_list",
+ }
+ __event_validation__ = {"ce3630e4-2bf9-4433-bdab-1ee72117e54b": None}
+
+ @staticmethod
+ def build_decision_book_project_items_list(
+ requester: Union[EmployeeTokenObject, OccupantTokenObject],
+ list_options: ListOptions,
+ ):
+ response = BuildDecisionBookProjectItems.list_items(
+ requester=requester,
+ list_options=list_options,
+ )
+ return AlchemyJsonResponse(
+ message="Build Decision Book Project Items List",
+ result=response,
+ )
+
+
+class BuildDecisionBookProjectItemsCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "b27e4fd0-6e3e-441b-9b33-806ac7082444": "build_decision_book_project_items_create",
+ }
+ __event_validation__ = {
+ "b27e4fd0-6e3e-441b-9b33-806ac7082444": InsertBuildDecisionBookProjectItems,
+ }
+
+ @staticmethod
+ def build_decision_book_project_items_create(
+ data: InsertBuildDecisionBookProjectItems,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjectItems.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"No permission to create decision book project items",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ book_project = BuildDecisionBookProjects.filter_one(
+ BuildDecisionBookProjects.uu_id
+ == data.build_decision_book_project_uu_id,
+ BuildDecisionBookProjects.project_response_living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ ).data
+ if not book_project:
+ raise BuildDecisionBookProjectItems.raise_http_exception(
+ status_code="HTTP_404_NOT_FOUND",
+ error_case="NOT_FOUND",
+ message=f"This user can not create project item for this project uu_id : {data.build_decision_book_project_uu_id}",
+ data={},
+ )
+ data_dict = data.excluded_dump()
+ data_dict["build_decision_book_project_id"] = book_project.id
+ created_project_item = BuildDecisionBookProjectItems.find_or_create(
+ **data_dict
+ )
+ created_project_item.save_and_confirm()
+ return AlchemyJsonResponse(
+ message="Build Decision Book Project Items Create",
+ result=created_project_item.get_dict(),
+ )
+
+
+class BuildDecisionBookProjectItemsUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "b2b7cdce-9a0c-4722-90ff-8bef36b4ec6b": "build_decision_book_project_items_update",
+ }
+ __event_validation__ = {
+ "b2b7cdce-9a0c-4722-90ff-8bef36b4ec6b": UpdateBuildDecisionBookProjectItems
+ }
+
+ @staticmethod
+ def build_decision_book_project_items_update(
+ requester: Union[EmployeeTokenObject, OccupantTokenObject],
+ decision_book_project_items: UpdateBuildDecisionBookProjectItems,
+ ):
+ raise BuildDecisionBookProjectItems.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="UNAUTHORIZED",
+ message=f"No permission to update decision book project items",
+ data={},
+ )
+
+
+class BuildDecisionBookProjectItemsPatchEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "e59d50df-dd22-4823-aeae-b9490332885c": "build_decision_book_project_items_patch",
+ }
+ __event_validation__ = {"e59d50df-dd22-4823-aeae-b9490332885c": None}
+
+ @staticmethod
+ def build_decision_book_project_items_patch(
+ requester: Union[EmployeeTokenObject, OccupantTokenObject],
+ decision_book_project_items: UpdateBuildDecisionBookProjectItems,
+ ):
+ response = BuildDecisionBookProjectItems.delete_item(
+ requester=requester,
+ decision_book_project_items=decision_book_project_items,
+ )
+ return AlchemyJsonResponse(
+ message="Build Decision Book Project Items Patch",
+ result=response,
+ )
+
+
+BuildDecisionBookProjectItemsListEventMethod = (
+ BuildDecisionBookProjectItemsListEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/items/list")
+ )
+)
+BuildDecisionBookProjectItemsCreateEventMethod = (
+ BuildDecisionBookProjectItemsCreateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/items/create")
+ )
+)
+BuildDecisionBookProjectItemsUpdateEventMethod = (
+ BuildDecisionBookProjectItemsUpdateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/items/update")
+ )
+)
+BuildDecisionBookProjectItemsPatchEventMethod = (
+ BuildDecisionBookProjectItemsPatchEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/items/patch")
+ )
+)
diff --git a/api_events/events/decision_book/project_decision_book_person.py b/api_events/events/decision_book/project_decision_book_person.py
new file mode 100644
index 0000000..0dba3e2
--- /dev/null
+++ b/api_events/events/decision_book/project_decision_book_person.py
@@ -0,0 +1,189 @@
+from typing import Union
+
+from databases import (
+ BuildDecisionBookProjects,
+ BuildDecisionBookProjectPerson,
+)
+
+from api_validations.validations_request import (
+ InsertBuildDecisionBookProjectPerson,
+ UpdateBuildDecisionBookProjectPerson,
+ ListOptions,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class ProjectDecisionBookPersonListEventMethods(MethodToEvent):
+
+ event_type = "LIST"
+
+ __event_keys__ = {
+ "7101b5ca-8bef-40f9-8b4d-646d9994e18f": "project_decision_book_person_list",
+ }
+ __event_validation__ = {"7101b5ca-8bef-40f9-8b4d-646d9994e18f": None}
+
+ @classmethod
+ def project_decision_book_person_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ project_person = BuildDecisionBookProjectPerson.filter_all(
+ BuildDecisionBookProjects.living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ )
+ decision_book_ids = [
+ _.build_decision_book_project_id for _ in project_person.data
+ ]
+ decision_book_projects = BuildDecisionBookProjects.filter_all(
+ BuildDecisionBookProjects.build_decision_book_project_id.in_(
+ decision_book_ids
+ ),
+ )
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision person book listed successfully",
+ result=decision_book_projects,
+ )
+
+
+class ProjectDecisionBookPersonCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+
+ __event_keys__ = {
+ "9c88e314-84e8-435e-8c1e-6a5aae80b2e6": "project_decision_book_person_create",
+ }
+ __event_validation__ = {
+ "9c88e314-84e8-435e-8c1e-6a5aae80b2e6": InsertBuildDecisionBookProjectPerson
+ }
+
+ @classmethod
+ def project_decision_book_create(
+ cls,
+ data: InsertBuildDecisionBookProjectPerson,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ decision_book = BuildDecisionBookProjects.filter_one(
+ BuildDecisionBookProjects.build_decision_book_uu_id
+ == data.get("build_decision_book_uu_id"),
+ BuildDecisionBookProjects.project_response_living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ )
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision book created successfully",
+ result=decision_book,
+ )
+
+
+class ProjectDecisionBookPersonUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+
+ __event_keys__ = {
+ "7fbd18a0-c099-4494-ada1-bb23e39bb141": "project_decision_book_update_person",
+ }
+ __event_validation__ = {
+ "7fbd18a0-c099-4494-ada1-bb23e39bb141": UpdateBuildDecisionBookProjectPerson
+ }
+
+ @classmethod
+ def project_decision_book_update(
+ cls,
+ data: UpdateBuildDecisionBookProjectPerson,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
+ BuildDecisionBookProjects.build_decision_book_project_uu_id
+ == data.get("build_decision_book_uu_id"),
+ BuildDecisionBookProjects.living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ )
+
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision book created successfully",
+ result=decision_book_project_person,
+ )
+
+
+class ProjectDecisionBookPersonPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+
+ __event_keys__ = {
+ "a122e84a-5556-4bf7-b680-1f47c438d4f7": "project_decision_book_person_patch",
+ }
+ __event_validation__ = {"a122e84a-5556-4bf7-b680-1f47c438d4f7": None}
+
+ @classmethod
+ def project_decision_book_patch(
+ cls,
+ data,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise BuildDecisionBookProjects.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ error_case="NOT_ALLOWED",
+ message="Employee cannot create project project decision book",
+ data={},
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
+ BuildDecisionBookProjects.build_decision_book_project_uu_id
+ == data.get("build_decision_book_uu_id"),
+ BuildDecisionBookProjects.living_space_id
+ == token_dict.selected_occupant.living_space_id,
+ )
+ return AlchemyJsonResponse(
+ status_code="HTTP_200_OK",
+ message="Project decision book created successfully",
+ result=decision_book_project_person,
+ )
+
+
+ProjectDecisionBookPersonListEventMethod = ProjectDecisionBookPersonListEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/people/list")
+)
+ProjectDecisionBookPersonCreateEventMethod = (
+ ProjectDecisionBookPersonCreateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/people/create")
+ )
+)
+ProjectDecisionBookPersonUpdateEventMethod = (
+ ProjectDecisionBookPersonUpdateEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/people/update")
+ )
+)
+ProjectDecisionBookPersonPatchEventMethod = ProjectDecisionBookPersonPatchEventMethods(
+ action=ActionsSchema(endpoint="/build/decision_book/project/people/patch")
+)
diff --git a/api_events/events/events/__init__.py b/api_events/events/events/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/events/events_bind_modules.py b/api_events/events/events/events_bind_modules.py
new file mode 100644
index 0000000..6daf315
--- /dev/null
+++ b/api_events/events/events/events_bind_modules.py
@@ -0,0 +1,157 @@
+import typing
+
+from databases import (
+ Modules,
+ BuildLivingSpace,
+)
+from api_validations.validations_request import (
+ RegisterModules2Occupant,
+ RegisterModules2Employee,
+)
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_events.events.events.events_bind_services import (
+ ServiceBindOccupantEventMethods,
+)
+from api_library.date_time_actions.date_functions import system_arrow
+from api_validations.core_response import AlchemyJsonResponse
+from databases.sql_models.company.employee import Employees
+from databases.sql_models.event.event import Event2Occupant, Event2Employee
+
+
+class ModulesBindOccupantEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "91003e90-8ead-4705-98a3-f8731c6ecb38": "modules_bind_occupant",
+ }
+ __event_validation__ = {
+ "91003e90-8ead-4705-98a3-f8731c6ecb38": None,
+ }
+
+ @classmethod
+ def bind_default_module_for_first_init_occupant(
+ cls, build_living_space_id: int, expires_at: str = None
+ ):
+
+ living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.id == build_living_space_id, system=True
+ ).data
+ modules = Modules.filter_all(Modules.is_default_module == True).data
+ print("living_space", living_space, "modules", modules)
+ if not living_space or not modules:
+ print(f"Giving living Space or Modules: Default not found")
+ return
+ service_build_dict = dict(build_living_space_id=living_space.id)
+ if expires_at:
+ service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
+ else:
+ expiry_ends = str(system_arrow.get(living_space.expiry_ends))
+ service_build_dict["expires_at"] = expiry_ends
+
+ for module in modules:
+ for service in module.retrieve_services():
+ event_occupant = Event2Occupant.find_or_create(
+ event_service_id=service.id,
+ event_service_uu_id=str(service.uu_id),
+ build_living_space_id=living_space.id,
+ build_living_space_uu_id=str(living_space.uu_id),
+ )
+ event_occupant.save_and_confirm()
+ return True
+
+ # @classmethod
+ # def modules_bind_occupant_system(
+ # cls, build_living_space_id: int, modules_id: int, expires_at: str = None
+ # ):
+ #
+ # living_space = BuildLivingSpace.filter_one(
+ # BuildLivingSpace.id == build_living_space_id,
+ # ).data
+ # modules = Modules.filter_one(Modules.id == modules_id).data
+ #
+ # if not living_space or not modules:
+ # print(f"Giving living Space or Modules: {modules.module_name} not found")
+ # return
+ # service_build_dict = dict(build_living_space_id=living_space.id)
+ # if expires_at:
+ # service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
+ # else:
+ # service_build_dict["expires_at"] = str(
+ # system_arrow.get(living_space.expiry_ends)
+ # )
+ #
+ # for service in modules.retrieve_services():
+ # ServiceBindOccupantEventMethods.bind_services_occupant_system(
+ # **service_build_dict,
+ # service_id=service.id,
+ # )
+ # BuildLivingSpace.save()
+ # return True
+
+ @classmethod
+ def modules_bind_occupant(
+ cls,
+ data: RegisterModules2Occupant,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+
+ return
+
+
+class ModulesBindEmployeeEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "d4ed23db-62e9-4015-b7c0-698a7917aa0c": "modules_bind_employee",
+ }
+ __event_validation__ = {
+ "d4ed23db-62e9-4015-b7c0-698a7917aa0c": None,
+ }
+
+ @classmethod
+ def bind_default_module_for_first_init_occupant(
+ cls, employee_id: int, expires_at: str = None
+ ):
+
+ employee = Employees.filter_one(
+ Employees.id == employee_id,
+ ).data
+ modules = Modules.filter_all(Modules.is_default_module == True).data
+ print("living_space", employee, "modules", modules)
+ if not employee or not modules:
+ print(f"Giving living Space or Modules: Default not found")
+ return
+ service_build_dict = dict(build_living_space_id=employee.id)
+ if expires_at:
+ service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
+ else:
+ expiry_ends = str(system_arrow.get(employee.expiry_ends))
+ service_build_dict["expires_at"] = expiry_ends
+
+ for module in modules:
+ for service in module.retrieve_services():
+ event_employee = Event2Employee.find_or_create(
+ event_service_id=service.id,
+ event_service_uu_id=str(service.uu_id),
+ employee_id=employee.id,
+ employee_uu_id=str(employee.uu_id),
+ )
+ event_employee.save_and_confirm()
+ return True
+
+ @classmethod
+ def modules_bind_employee(
+ cls,
+ data: RegisterModules2Employee,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+
+ModulesBindOccupantEventMethod = ModulesBindOccupantEventMethods(
+ action=ActionsSchema(endpoint="/bind/modules/occupant")
+)
+ModulesBindEmployeeEventMethod = ModulesBindEmployeeEventMethods(
+ action=ActionsSchema(endpoint="/bind/modules/employee")
+)
diff --git a/api_events/events/events/events_bind_services.py b/api_events/events/events/events_bind_services.py
new file mode 100644
index 0000000..e5997e2
--- /dev/null
+++ b/api_events/events/events/events_bind_services.py
@@ -0,0 +1,321 @@
+import typing
+
+from fastapi import status
+from fastapi.responses import JSONResponse
+from fastapi.exceptions import HTTPException
+
+from api_library.date_time_actions.date_functions import system_arrow
+from databases import (
+ Modules,
+ Employees,
+ BuildParts,
+ BuildLivingSpace,
+ Services,
+ OccupantTypes,
+ Event2Employee,
+ Event2Occupant,
+)
+from api_validations.validations_request import (
+ RegisterServices2Occupant,
+ RegisterServices2Employee,
+)
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class ServiceBindOccupantEventMethods(MethodToEvent):
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "0d2bc5c9-d4b1-4951-8305-69da4a687fdc": "bind_services_occupant",
+ }
+ __event_validation__ = {
+ "0d2bc5c9-d4b1-4951-8305-69da4a687fdc": RegisterServices2Occupant
+ }
+
+ @classmethod
+ def bind_services_occupant_system(
+ cls, build_living_space_id: int, service_id: int, expires_at: str = None
+ ):
+ living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.id == build_living_space_id,
+ ).data
+ service = Services.filter_one(Services.id == service_id).data
+ if not service:
+ print("Service is not valid. Service can not be binded")
+ return
+
+ if not living_space:
+ print("Living Space is not valid. Service is not binded")
+ return
+
+ if expires_at:
+ expires_at = str(system_arrow.get(expires_at))
+ else:
+ expires_at = str(system_arrow.get(living_space.expiry_ends))
+
+ occupants_event = Event2Occupant.find_or_create(
+ event_service_id=service.id,
+ event_service_uu_id=str(service.uu_id),
+ build_living_space_id=living_space.id,
+ build_living_space_uu_id=str(living_space.uu_id),
+ expiry_ends=expires_at,
+ )
+ occupants_event.save_and_confirm()
+ print(f"{service.service_name} is added to occupant {str(living_space.uu_id)}")
+
+ @classmethod
+ def bind_services_occupant(
+ cls,
+ data: RegisterServices2Occupant,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ from sqlalchemy.dialects.postgresql import insert
+
+ if isinstance(token_dict, EmployeeTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Employee is not authorized to add service to any occupant",
+ )
+
+ occupants_build_part = BuildParts.filter_one(
+ BuildParts.uu_id == data.build_part_uu_id,
+ BuildParts.build_id == token_dict.selected_occupant.build_id,
+ ).data
+ if not occupants_build_part:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "User is not authorized to add service to this occupant or flat",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ occupant_occupant_type = OccupantTypes.filter_by_one(
+ uu_id=data.occupant_uu_id
+ ).data
+ if not occupant_occupant_type:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Occupant Types is not found",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ service = Services.filter_one(Services.uu_id == data.service_uu_id).data
+ if not service:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Service is not found",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ # service_events = Service2Events.filter_all(
+ # Service2Events.service_id == service.id,
+ # ).data
+ # if not service_events:
+ # raise HTTPException(
+ # status_code=status.HTTP_404_NOT_FOUND,
+ # detail="Service has no events registered. Please contact with your manager",
+ # )
+
+ living_space = BuildLivingSpace.filter_one(
+ BuildLivingSpace.build_parts_id == occupants_build_part.id,
+ BuildLivingSpace.occupant_types_id == occupant_occupant_type.id,
+ BuildLivingSpace.person_id == token_dict.person_id,
+ ).data
+ if not living_space:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Living Space is not found with given data. Please check flat and occupant type",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ # event_ids_list = [
+ # {
+ # "build_living_space_id": living_space.id,
+ # "build_living_space_uu_id": str(living_space.uu_id),
+ # "event_id": service_event.event_id,
+ # "event_uu_id": str(service_event.event_uu_id),
+ # "is_confirmed": True,
+ # }
+ # for service_event in service_events
+ # ]
+ #
+ # session_execute = Services.session.execute(
+ # insert(Event2Occupant)
+ # .values(event_ids_list)
+ # .on_conflict_do_nothing(
+ # index_elements=["employee_id", "event_id"],
+ # )
+ # )
+ # count_row = session_execute.rowcount
+ # print(f"{count_row} events are added to employee {str(living_space.uu_id)}")
+ # Services.save()
+
+
+class ServiceBindEmployeeEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "50f84023-d8ec-4257-bfce-08ddf077c101": "bind_services_employee_super_user",
+ }
+ __event_validation__ = {"50f84023-d8ec-4257-bfce-08ddf077c101": None}
+
+ @classmethod
+ def bind_services_employee(cls, service_id: int, employee_id: int):
+ employee = Employees.filter_by_one(
+ id=employee_id, **Employees.valid_record_dict
+ ).data
+ service = Services.filter_by_one(
+ id=service_id, **Services.valid_record_dict
+ ).data
+ if not service:
+ print("Service is not valid. Service can not be binded")
+ return
+
+ if not employee:
+ print("Employee is not valid. Service is not binded")
+ return
+
+ # service_events = Service2Events.filter_all(
+ # Service2Events.service_id == service.id,
+ # ).data
+ # if not service_events:
+ # raise Exception(
+ # "Service has no events registered. Please contact with your manager"
+ # )
+
+ # event_ids_list = [
+ # {
+ # "employee_id": employee_id,
+ # "employee_uu_id": str(employee.uu_id),
+ # "event_id": service_event.event_id,
+ # "event_uu_id": str(service_event.event_uu_id),
+ # "is_confirmed": True,
+ # }
+ # for service_event in service_events
+ # ]
+ #
+ # session_execute = Services.session.execute(
+ # insert(Event2Employee)
+ # .values(event_ids_list)
+ # .on_conflict_do_nothing(
+ # index_elements=["employee_id", "event_id"],
+ # )
+ # )
+ # count_row = session_execute.rowcount
+ # print(f"{count_row} events are added to employee {employee.uu_id}")
+ # for service_event in service_events:
+ # service_event.save_and_confirm()
+
+ @classmethod
+ def bind_services_employee_super_user(
+ cls,
+ data: RegisterServices2Employee,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Occupant is not authorized to add service to any employee",
+ )
+
+ employee = Employees.filter_by_one(
+ uu_id=data.employee_uu_id, **Employees.valid_record_dict
+ ).data
+ if not employee:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "This employee is not authorized to add event to this employee",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ service = Services.filter_by_one(
+ uu_id=data.service_uu_id, **Services.valid_record_dict
+ ).data
+ if not service:
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Service is not found",
+ "data": {},
+ },
+ status_code=status.HTTP_404_NOT_FOUND,
+ )
+
+ event_of_employee = Event2Employee.find_or_create(
+ event_service_id=service.id,
+ event_service_uu_id=str(service.uu_id),
+ employee_id=employee.id,
+ employee_uu_id=str(employee.uu_id),
+ )
+ event_of_employee.save_and_confirm()
+ print(f"{service.service_name} is added to employee {str(employee.uu_id)}")
+
+ # service_events = Service2Events.filter_all(
+ # Service2Events.service_id == service.id,
+ # ).data
+ # if not service_events:
+ # raise HTTPException(
+ # status_code=status.HTTP_404_NOT_FOUND,
+ # detail="Service has no events registered. Please contact with your manager",
+ # )
+ #
+ # event_ids_list = [
+ # {
+ # "employee_id": employee.id,
+ # "employee_uu_id": employee.uu_id,
+ # "event_id": service_event.event_id,
+ # "event_uu_id": service_event.event_uu_id,
+ # "is_confirmed": True,
+ # }
+ # for service_event in service_events
+ # ]
+ #
+ # session_execute = Services.session.execute(
+ # insert(Event2Employee)
+ # .values(event_ids_list)
+ # .on_conflict_do_nothing(
+ # index_elements=["employee_id", "event_id"],
+ # )
+ # )
+ # count_row = session_execute.rowcount
+ # if not count_row:
+ # Services.save()
+ # return JSONResponse(
+ # content={
+ # "completed": False,
+ # "message": "No events are added to employee",
+ # "data": {},
+ # },
+ # status_code=status.HTTP_200_OK,
+ # )
+ # return JSONResponse(
+ # content={
+ # "completed": True,
+ # "message": f"{count_row} events are added to employee",
+ # "data": {},
+ # },
+ # status_code=status.HTTP_200_OK,
+ # )
+
+
+ServiceBindOccupantEventMethod = ServiceBindOccupantEventMethods(
+ action=ActionsSchema(endpoint="/bind/services/occupant")
+)
+ServiceBindEmployeeEventMethod = ServiceBindEmployeeEventMethods(
+ action=ActionsSchema(endpoint="/bind/services/employee")
+)
diff --git a/api_events/events/events/events_events.py b/api_events/events/events/events_events.py
new file mode 100644
index 0000000..5560e5f
--- /dev/null
+++ b/api_events/events/events/events_events.py
@@ -0,0 +1,270 @@
+from typing import Union
+
+from fastapi.exceptions import HTTPException
+
+from api_events.events.events.events_services import ServicesEvents
+from databases import (
+ Events,
+ Employees,
+ Staff,
+ Duties,
+ Event2Occupant,
+ Event2Employee,
+ BuildLivingSpace,
+)
+from api_validations.validations_request import (
+ RegisterEvents2Employee,
+ RegisterEvents2Occupant,
+ ListOptions,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class EventsListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": "events_list",
+ }
+ __event_validation__ = {"9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": None}
+
+ @classmethod
+ def events_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ list_options.page = 1
+ list_options.size = 10000
+ Events.filter_attr = list_options
+ if isinstance(token_dict, OccupantTokenObject):
+ occupant_events = Event2Occupant.filter_all(
+ Event2Occupant.build_living_space_id
+ == token_dict.selected_occupant.living_space_id
+ ).data
+ records = Events.filter_all(
+ Events.id.in_([event.event_id for event in occupant_events])
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Events are listed successfully",
+ result=records,
+ )
+ elif isinstance(token_dict, EmployeeTokenObject):
+ employee_events = Event2Employee.filter_all(
+ Event2Employee.employee_id == token_dict.selected_company.employee_id
+ ).data
+ records = Events.filter_all(
+ Events.id.in_([event.event_id for event in employee_events])
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Events are listed successfully",
+ result=records,
+ )
+ return AlchemyJsonResponse(
+ completed=False,
+ message="Events are NOT listed successfully",
+ result=[],
+ )
+
+
+class EventsBindEventToOccupantMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "d9aa58aa-37f7-4c27-861d-3105f76f5cdc": "bind_events_employee",
+ }
+ __event_validation__ = {
+ "d9aa58aa-37f7-4c27-861d-3105f76f5cdc": RegisterEvents2Employee
+ }
+
+ @classmethod
+ def bind_events_employee(cls, data: RegisterEvents2Employee, token_dict):
+ events = Events.filter_all(
+ Events.uu_id.in_(data.event_id),
+ ).data
+ if not events:
+ raise HTTPException(
+ status_code=401,
+ detail="No event found. Please contact your super user.",
+ )
+ employee_is_not_valid = False
+ employee = Employees.filter_one(
+ Employees.employee_uu_id == data.employee_uu_id,
+ ).data
+ if employee:
+ staff = Staff.filter_one(
+ Staff.id == employee.staff_id,
+ ).data
+ duties = Duties.filter_one(
+ Duties.id == staff.duties_id,
+ ).data
+ if duties.company_id not in token_dict.companies_id_list:
+ employee_is_not_valid = True
+
+ if employee_is_not_valid:
+ raise HTTPException(
+ status_code=401,
+ detail="This employee can not be reached by this user. Please contact your super user.",
+ )
+
+ for event in events:
+ employee = Event2Employee.find_or_create(
+ **token_dict.user_creds, employee_id=employee.id, event_id=event.id
+ )
+ Events.save()
+ return {
+ "status": "success",
+ "message": "Events registered successfully.",
+ "events": [event.uu_id for event in events.data],
+ }
+
+
+class EventsBindEventToEmployeeMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "8bb4f4fc-b474-427e-90b3-d8681f308bb5": "bind_events_occupant",
+ }
+ __event_validation__ = {
+ "8bb4f4fc-b474-427e-90b3-d8681f308bb5": RegisterEvents2Occupant
+ }
+
+ @classmethod
+ def bind_events_occupant(cls, data: RegisterEvents2Occupant, token_dict):
+ events = Events.filter_all(
+ Events.uu_id.in_(data.event_id),
+ ).data
+ if not events:
+ raise HTTPException(
+ status_code=401,
+ detail="No event found. Please contact your super user.",
+ )
+ occupant = BuildLivingSpace.filter_one(
+ BuildLivingSpace.uu_id == data.build_living_space_uu_id,
+ ).data
+ if not occupant:
+ raise HTTPException(
+ status_code=401,
+ detail="This occupant can not be reached by this user. Please contact your super user.",
+ )
+ for event in events:
+ occupant = Event2Occupant.find_or_create(
+ **token_dict.user_creds,
+ build_living_space_id=occupant.id,
+ event_id=event.id,
+ )
+ Events.save()
+ return {
+ "status": "success",
+ "message": "Events registered successfully.",
+ "events": [event.uu_id for event in events.data],
+ }
+
+
+EventsBindEventToOccupantMethod = EventsBindEventToOccupantMethods(
+ action=ActionsSchema(endpoint="/bind/events/occupant")
+)
+EventsBindEventToEmployeeMethod = EventsBindEventToEmployeeMethods(
+ action=ActionsSchema(endpoint="/bind/events/employee")
+)
+EventsListEventMethod = EventsListEventMethods(
+ action=ActionsSchema(endpoint="/event/list")
+)
+
+# EventsCreateEventMethod = EventsCreateEventMethods(
+# action=ActionsSchema(endpoint="/event/create")
+# )
+# EventsUpdateEventMethod = EventsUpdateEventMethods(
+# action=ActionsSchema(endpoint="/event/update")
+# )
+# EventsPatchEventMethod = EventsPatchEventMethods(
+# action=ActionsSchema(endpoint="/event/patch")
+# )
+#
+
+# class EventsCreateEventMethods(MethodToEvent):
+#
+# event_type = "CREATE"
+# __event_keys__ = {
+# "514a9f8f-e5e5-4e10-9d0b-2de8f461fc1b": "events_create",
+# }
+#
+# @classmethod
+# def events_create(cls, data: CreateEvents, token_dict):
+# event = Events.find_or_create(
+# **token_dict.user_creds,
+# event_name=data.event_name,
+# event_description=data.event_description,
+# event_date=data.event_date,
+# event_location=data.event_location,
+# active=True,
+# deleted=False,
+# )
+# Events.save()
+# return {
+# "status": "success",
+# "message": "Event created successfully.",
+# "event": event.uu_id,
+# }
+# class EventsUpdateEventMethods(MethodToEvent):
+#
+# event_type = "UPDATE"
+# __event_keys__ = {
+# "f94e7b79-2369-4840-bf2b-244934ca3136": "events_update",
+# }
+#
+# @classmethod
+# def events_update(cls, data: CreateEvents, token_dict):
+# event = Events.filter_by_one(uu_id=data.uu_id, **Events.valid_record_dict).data
+# if not event:
+# raise HTTPException(
+# status_code=404,
+# detail="No event found. Please contact your responsible company.",
+# )
+# event.update(
+# **token_dict.user_creds,
+# event_name=data.event_name,
+# event_description=data.event_description,
+# event_date=data.event_date,
+# event_location=data.event_location,
+# )
+# Events.save()
+# return {
+# "status": "success",
+# "message": "Event updated successfully.",
+# "event": event.uu_id,
+# }
+#
+#
+# class EventsPatchEventMethods(MethodToEvent):
+#
+# event_type = "PATCH"
+# __event_keys__ = {
+# "41944c63-22d3-4866-affd-34bcd49da58b": "events_patch",
+# }
+#
+# @classmethod
+# def events_patch(cls, data: CreateEvents, token_dict):
+# event = Events.filter_by_one(uu_id=data.uu_id, **Events.valid_record_dict).data
+# if not event:
+# raise HTTPException(
+# status_code=404,
+# detail="No event found. Please contact your responsible company.",
+# )
+# event.update(
+# **token_dict.user_creds,
+# event_name=data.event_name,
+# event_description=data.event_description,
+# event_date=data.event_date,
+# event_location=data.event_location,
+# )
+# return {
+# "status": "success",
+# "message": "Event patched successfully.",
+# "event": event.uu_id,
+# }
diff --git a/api_events/events/events/events_models.py b/api_events/events/events/events_models.py
new file mode 100644
index 0000000..595d9b1
--- /dev/null
+++ b/api_events/events/events/events_models.py
@@ -0,0 +1,28 @@
+from api_validations.validations_request import (
+ DepartmentsPydantic,
+ PatchRecord,
+ ListOptions,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class ModelEvents(MethodToEvent):
+
+ @classmethod
+ def model_list(cls, list_options: ListOptions, token_dict):
+ return
+
+ @classmethod
+ def model_create(cls, data: DepartmentsPydantic, token_dict):
+ return
+
+ @classmethod
+ def model_update(cls, company_uu_id: str, data: DepartmentsPydantic, token_dict):
+ return
+
+ @classmethod
+ def model_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
+ return
diff --git a/api_events/events/events/events_modules.py b/api_events/events/events/events_modules.py
new file mode 100644
index 0000000..62f3114
--- /dev/null
+++ b/api_events/events/events/events_modules.py
@@ -0,0 +1,24 @@
+from api_validations.validations_request import DepartmentsPydantic, PatchRecord
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class ModulesEvents(MethodToEvent):
+
+ @classmethod
+ def modules_list(cls, request, list_options):
+ return
+
+ @classmethod
+ def modules_create(cls, data: DepartmentsPydantic, token_dict):
+ return
+
+ @classmethod
+ def modules_update(cls, module_uu_id: str, data: DepartmentsPydantic, token_dict):
+ return
+
+ @classmethod
+ def modules_patch(cls, module_uu_id: str, data: PatchRecord, token_dict):
+ return
diff --git a/api_events/events/events/events_services.py b/api_events/events/events/events_services.py
new file mode 100644
index 0000000..dfd3174
--- /dev/null
+++ b/api_events/events/events/events_services.py
@@ -0,0 +1,64 @@
+from typing import Union
+
+from api_validations.validations_request import (
+ DepartmentsPydantic,
+ PatchRecord,
+ ListOptions,
+)
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class ServicesEvents(MethodToEvent):
+
+ @classmethod
+ def services_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+ @classmethod
+ def services_create(
+ cls,
+ data: DepartmentsPydantic,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+ @classmethod
+ def services_update(
+ cls,
+ service_uu_id: str,
+ data: DepartmentsPydantic,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+ @classmethod
+ def services_patch(
+ cls,
+ service_uu_id: str,
+ data: PatchRecord,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ return
+
+ @classmethod
+ def bind_service_to_action(
+ cls, data, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
+ ):
+ return
+
+ @classmethod
+ def bind_module_to_service(
+ cls, data, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
+ ):
+ return
+
+ @classmethod
+ def bind_events_patch(cls, company_uu_id: str, data: PatchRecord):
+ return
diff --git a/api_events/events/identity/__init__.py b/api_events/events/identity/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/events/identity/people.py b/api_events/events/identity/people.py
new file mode 100644
index 0000000..cb2c2f3
--- /dev/null
+++ b/api_events/events/identity/people.py
@@ -0,0 +1,219 @@
+from typing import Union
+
+from fastapi import status
+from fastapi.responses import JSONResponse
+
+from api_validations.validations_response.people import PeopleListResponse
+from databases import (
+ Build,
+ People,
+ Users,
+ Companies,
+)
+
+from api_validations.validations_request import InsertPerson, UpdateUsers
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+
+
+class PeopleListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "0a05f03c-6ed8-4230-a4ff-6e7cf886909b": "super_users_people_list",
+ "b5612538-0445-4a4a-ab13-d2a06037f7a5": "sales_users_people_list",
+ "25cbbaf8-117a-470f-a844-2cfc70f71dde": "human_resources_users_people_list",
+ "cdf62f06-ec50-40de-b19e-adb3dd34bb95": "people_list_only_occupant_tenant_or_owner",
+ }
+ __event_validation__ = {
+ "0a05f03c-6ed8-4230-a4ff-6e7cf886909b": PeopleListResponse,
+ "b5612538-0445-4a4a-ab13-d2a06037f7a5": None,
+ "25cbbaf8-117a-470f-a844-2cfc70f71dde": None,
+ "cdf62f06-ec50-40de-b19e-adb3dd34bb95": None,
+ }
+
+ @classmethod
+ def super_users_people_list(
+ cls, list_options, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
+ ):
+ records = []
+ if isinstance(token_dict, EmployeeTokenObject):
+ People.pre_query = People.select_action(
+ duty_id_list=[
+ token_dict.selected_company.duty_id,
+ token_dict.selected_company.bulk_duties_id,
+ ],
+ )
+ People.filter_attr = list_options
+ records = People.filter_all()
+ elif isinstance(token_dict, OccupantTokenObject):
+ related_users = Users.filter_all(
+ Users.related_company
+ == token_dict.selected_occupant.responsible_company_id,
+ ).data
+ People.pre_query = People.filter_all(
+ People.id.in_([user.person_id for user in related_users]),
+ ).query
+ People.filter_attr = list_options
+ records = People.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="People are listed successfully",
+ result=records,
+ cls_object=People,
+ filter_attributes=list_options,
+ response_model=PeopleListResponse,
+ )
+
+ @classmethod
+ def sales_users_people_list(
+ cls,
+ list_options,
+ token_dict: EmployeeTokenObject,
+ ):
+ People.filter_attr = list_options
+ records = People.filter_all().data
+ return AlchemyJsonResponse(
+ completed=True,
+ message="People are listed successfully",
+ result=records,
+ )
+
+ @classmethod
+ def human_resources_users_people_list(
+ cls,
+ list_options,
+ token_dict: EmployeeTokenObject,
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ People.filter_attr = list_options
+ records = People.filter_all().data
+ return AlchemyJsonResponse(
+ completed=True,
+ message="People are listed successfully",
+ result=records,
+ )
+
+
+class PeopleCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "2d1513f4-44ed-4fa3-84d1-dfbd0eadf9a1": "people_create",
+ }
+ __event_validation__ = {
+ "2d1513f4-44ed-4fa3-84d1-dfbd0eadf9a1": InsertPerson,
+ }
+
+ @classmethod
+ def people_create(
+ cls,
+ data: InsertPerson,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, EmployeeTokenObject):
+ created_user = People.create_action(data=data, token=token_dict)
+ People.save()
+ elif isinstance(token_dict, OccupantTokenObject):
+ created_user = People.create_action(data=data, token=token_dict)
+ People.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create User record",
+ "data": created_user.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class PeopleUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "e05cf22c-16c4-450b-86c8-417896a26afc": "people_update",
+ }
+ __event_validation__ = {"e05cf22c-16c4-450b-86c8-417896a26afc": UpdateUsers}
+
+ @classmethod
+ def people_update(
+ cls,
+ data: UpdateUsers,
+ user_uu_id: str,
+ token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ data_dict = data.excluded_dump()
+ if isinstance(token_dict, EmployeeTokenObject):
+ find_one_user = Users.filter_one(
+ Users.uu_id == user_uu_id,
+ ).data
+ access_authorized_company = Companies.select_action(
+ duty_id_list=[
+ token_dict.selected_company.duty_id,
+ token_dict.selected_company.bulk_duties_id,
+ ],
+ )
+ if access_authorized_company.count:
+ updated_user = find_one_user.update(**data_dict)
+ Users.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update User record",
+ "data": updated_user,
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ elif isinstance(token_dict, OccupantTokenObject):
+ find_one_user = People.filter_one(
+ People.uu_id == user_uu_id,
+ ).data
+ access_authorized_company = Companies.select_action(
+ duty_id_list=[getattr(token_dict, "duty_id")],
+ filter_expr=[Companies.id == find_one_user.id],
+ )
+ if access_authorized_company.count:
+ data_dict = data.excluded_dump()
+ updated_user = find_one_user.update(**data_dict)
+ People.save()
+ return JSONResponse(
+ content={"completed": True, "message": "Update User record", "data": {}},
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class PeoplePatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "3ae16d66-090b-4d27-b567-cce1b10a1c3b": "people_patch",
+ }
+ __event_validation__ = {"3ae16d66-090b-4d27-b567-cce1b10a1c3b": None}
+
+ @classmethod
+ def people_patch(cls):
+ return
+
+
+class PeopleDeleteEventMethods(MethodToEvent):
+
+ event_type = "DELETE"
+ __event_keys__ = {
+ "7f84c7a2-a120-4867-90d4-6767a41320db": "people_delete",
+ }
+ __event_validation__ = {"7f84c7a2-a120-4867-90d4-6767a41320db": None}
+
+
+PeopleListEventMethod = PeopleListEventMethods(
+ action=ActionsSchema(endpoint="/people/list")
+)
+PeopleCreateEventMethod = PeopleCreateEventMethods(
+ action=ActionsSchema(endpoint="/people/create")
+)
+PeopleUpdateEventMethod = PeopleUpdateEventMethods(
+ action=ActionsSchema(endpoint="/people/update")
+)
+PeoplePatchEventMethod = PeoplePatchEventMethods(
+ action=ActionsSchema(endpoint="/people/patch")
+)
diff --git a/api_events/events/identity/users.py b/api_events/events/identity/users.py
new file mode 100644
index 0000000..7f8c15b
--- /dev/null
+++ b/api_events/events/identity/users.py
@@ -0,0 +1,217 @@
+import typing
+
+from fastapi import status
+from fastapi.responses import JSONResponse
+
+from api_configs import ApiStatic
+from databases import MongoQueryIdentity, Users, Companies, People
+from databases.no_sql_models.validations import DomainViaUser
+
+from api_events.events.abstract_class import MethodToEvent, ActionsSchema
+from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
+from api_validations.core_response import AlchemyJsonResponse
+from api_services.email.service import send_email
+from api_services.templates.password_templates import change_your_password_template
+from api_validations.validations_request import (
+ InsertUsers,
+ UpdateUsers,
+ PatchRecord,
+ ListOptions,
+ RegisterServices2Occupant,
+)
+
+
+class UserListEventMethods(MethodToEvent):
+
+ event_type = "SELECT"
+ __event_keys__ = {
+ "1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": "user_list",
+ }
+ __event_validation__ = {"1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": None}
+
+ @classmethod
+ def user_list(
+ cls,
+ list_options: ListOptions,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ if isinstance(token_dict, OccupantTokenObject):
+ raise Users.raise_http_exception(
+ status_code="HTTP_403_FORBIDDEN",
+ message="Occupant object can not list users",
+ error_case="NOTAUTHORIZED",
+ data={},
+ )
+ if "user_uu_id_list" in list_options.query:
+ people_ids = list_options.query.pop("user_uu_id_list")
+ people_id_list = (
+ user.person_id
+ for user in Users.filter_all(Users.uu_id.in_(people_ids)).data
+ )
+ Users.filter_attr = list_options
+ records = Users.filter_all(
+ Users.person_id.in_(people_id_list),
+ )
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Users are listed successfully",
+ result=records,
+ )
+ Users.filter_attr = list_options
+ records = Users.filter_all()
+ return AlchemyJsonResponse(
+ completed=True,
+ message="Users are listed successfully",
+ result=records,
+ )
+
+
+class UserCreateEventMethods(MethodToEvent):
+
+ event_type = "CREATE"
+ __event_keys__ = {
+ "8eb50c24-4bdc-4309-9836-f7048daee409": "user_create",
+ }
+ __event_validation__ = {"8eb50c24-4bdc-4309-9836-f7048daee409": InsertUsers}
+
+ @classmethod
+ def user_create(
+ cls,
+ data: InsertUsers,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ created_user = Users.create_action(create_user=data, token_dict=token_dict)
+ domain_via_user = DomainViaUser(
+ **{"user_uu_id": str(created_user.uu_id), "main_domain": "evyos.com.tr"}
+ )
+ created_user.save_and_confirm()
+ mongo_query_identity = MongoQueryIdentity(
+ company_uuid=created_user.related_company,
+ )
+ mongo_query_identity.create_domain_via_user(payload=domain_via_user)
+ reset_password_token = created_user.reset_password_token(
+ found_user=created_user
+ )
+ send_email_completed = send_email(
+ subject=f"Dear {created_user.user_tag}, your password has been changed.",
+ receivers=[str(created_user.email)],
+ html=change_your_password_template(
+ user_name=created_user.user_tag,
+ forgot_link=ApiStatic.forgot_link(forgot_key=reset_password_token),
+ ),
+ )
+ if not send_email_completed:
+ raise created_user.raise_http_exception(
+ status_code=400, message="Email can not be sent. Try again later"
+ )
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Create User record",
+ "data": created_user.get_dict(),
+ "password_token": {
+ "password_token": created_user.password_token,
+ "password_expires_day": str(created_user.password_expires_day),
+ "password_expiry_begins": str(created_user.password_expiry_begins),
+ "hash_password": created_user.hash_password,
+ "related_company": created_user.related_company,
+ },
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class UserUpdateEventMethods(MethodToEvent):
+
+ event_type = "UPDATE"
+ __event_keys__ = {
+ "d08a9470-1eb0-4890-a9e8-b6686239d7e9": "user_update",
+ }
+ __event_validation__ = {"d08a9470-1eb0-4890-a9e8-b6686239d7e9": UpdateUsers}
+
+ @classmethod
+ def user_update(
+ cls,
+ data: UpdateUsers,
+ user_uu_id: str,
+ token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
+ ):
+ find_one_user = Users.filter_one(
+ Users.uu_id == user_uu_id,
+ *Users.valid_record_args(Users),
+ ).data
+ access_authorized_company = Companies.select_action(
+ duty_id_list=[getattr(token_dict, "duty_id", 5)],
+ filter_expr=[Companies.id == token_dict.get("")],
+ )
+ if access_authorized_company.count:
+ data_dict = data.excluded_dump()
+ updated_user = find_one_user.update(**data_dict)
+ Users.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Update User record",
+ "data": updated_user,
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={"completed": True, "message": "Update User record", "data": {}},
+ status_code=status.HTTP_200_OK,
+ )
+
+
+class UserPatchEventMethods(MethodToEvent):
+
+ event_type = "PATCH"
+ __event_keys__ = {
+ "d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": "user_patch",
+ }
+ __event_validation__ = {"d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": None}
+
+ @classmethod
+ def user_patch(cls, data: PatchRecord, user_uu_id: str, token_dict):
+ find_one_user = Users.filter_one(
+ Users.uu_id == user_uu_id,
+ ).data
+ access_authorized_company = Companies.select_action(
+ duty_id_list=[getattr(token_dict, "duty_id", 5)],
+ filter_expr=[Companies.id == find_one_user.id],
+ )
+ if access_authorized_company.count:
+ action = data.excluded_dump()
+ find_one_user.active = bool(action.get("active", find_one_user.active))
+ find_one_user.is_confirmed = bool(
+ action.get("confirm", find_one_user.is_confirmed)
+ )
+ find_one_user.deleted = bool(action.get("delete", find_one_user.deleted))
+ find_one_user.save()
+ return JSONResponse(
+ content={
+ "completed": True,
+ "message": "Patch User record completed",
+ "data": find_one_user.get_dict(),
+ },
+ status_code=status.HTTP_200_OK,
+ )
+ return JSONResponse(
+ content={
+ "completed": False,
+ "message": "Patch User record failed",
+ "data": {},
+ },
+ status_code=status.HTTP_200_OK,
+ )
+
+
+UserListEventMethod = UserListEventMethods(action=ActionsSchema(endpoint="/user/list"))
+UserCreateEventMethod = UserCreateEventMethods(
+ action=ActionsSchema(endpoint="/user/create")
+)
+UserUpdateEventMethod = UserUpdateEventMethods(
+ action=ActionsSchema(endpoint="/user/update")
+)
+UserPatchEventMethod = UserPatchEventMethods(
+ action=ActionsSchema(endpoint="/user/patch")
+)
diff --git a/api_events/tasks2events/__init__.py b/api_events/tasks2events/__init__.py
new file mode 100644
index 0000000..c6f44bb
--- /dev/null
+++ b/api_events/tasks2events/__init__.py
@@ -0,0 +1,49 @@
+from api_events.tasks2events.common_tasks.default_user import AuthDefaultEventBlock
+from api_events.tasks2events.employee_tasks.super_user import SuperUserEventBlock
+
+from api_events.tasks2events.occupant_tasks.build_manager import BuildManager
+from api_events.tasks2events.occupant_tasks.build_owner import BuildOwner
+from api_events.tasks2events.occupant_tasks.build_resident import BuildResident
+from api_events.tasks2events.occupant_tasks.build_tenant import BuildTenant
+from api_events.tasks2events.occupant_tasks.build_represent import BuildRepresent
+from api_events.tasks2events.occupant_tasks.meeting_writer import BuildMeetingWriter
+from api_events.tasks2events.occupant_tasks.meeting_advisor import BuildMeetingAdvisor
+from api_events.tasks2events.occupant_tasks.meeting_attendance import (
+ BuildMeetingAttendance,
+)
+from api_events.tasks2events.occupant_tasks.meeting_president import (
+ BuildMeetingPresident,
+)
+from api_events.tasks2events.occupant_tasks.meeting_voted_president import (
+ BuildMeetingVotedPresident,
+)
+from api_events.tasks2events.occupant_tasks.project_leader import ProjectLeader
+from api_events.tasks2events.occupant_tasks.project_finance import (
+ ProjectFinanceResponsible,
+)
+from api_events.tasks2events.occupant_tasks.project_employee import ProjectEmployee
+from api_events.tasks2events.occupant_tasks.project_technical import ProjectTechnical
+from api_events.tasks2events.occupant_tasks.project_responsiable import (
+ ProjectResponsible,
+)
+
+
+__all__ = [
+ "AuthDefaultEventBlock",
+ "SuperUserEventBlock",
+ "BuildManager",
+ "BuildOwner",
+ "BuildResident",
+ "BuildTenant",
+ "BuildRepresent",
+ "BuildMeetingWriter",
+ "BuildMeetingPresident",
+ "BuildMeetingAdvisor",
+ "BuildMeetingAttendance",
+ "BuildMeetingVotedPresident",
+ "ProjectLeader",
+ "ProjectFinanceResponsible",
+ "ProjectEmployee",
+ "ProjectTechnical",
+ "ProjectResponsible",
+]
diff --git a/api_events/tasks2events/common_tasks/__init__.py b/api_events/tasks2events/common_tasks/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/tasks2events/common_tasks/default_user.py b/api_events/tasks2events/common_tasks/default_user.py
new file mode 100644
index 0000000..6a1c5eb
--- /dev/null
+++ b/api_events/tasks2events/common_tasks/default_user.py
@@ -0,0 +1,22 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class AuthDefaultEventBlock(AddEventFunctionality):
+ service_code = "AUTH"
+ related_code = "DF-USER"
+ events = [
+ {"function_code": "e672846d-cc45-4d97-85d5-6f96747fac67"},
+ {"function_code": "cee96b9b-8487-4e9f-aaed-2e8c79687bf9"},
+ {"function_code": "48379bb2-ba81-4d8e-a9dd-58837cfcbf67"},
+ {"function_code": "f09f7c1a-bee6-4e32-8444-962ec8f39091"},
+ {"function_code": "c519f9af-92e1-47b2-abf7-5a3316d075f7"},
+ {"function_code": "8b586848-2fb3-4161-abbe-642157eec7ce"},
+ {"function_code": "5cc22e4e-a0f7-4077-be41-1871feb3dfd1"},
+ {"function_code": "c90f3334-10c9-4181-b5ff-90d98a0287b2"},
+ {"function_code": "e3ca6e24-b9f8-4127-949c-3bfa364e3513"},
+ {"function_code": "c140cd5f-307f-4046-a93e-3ade032a57a7"},
+ {"function_code": "af9e121e-24bb-44ac-a616-471d5754360e"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/default_abstract.py b/api_events/tasks2events/default_abstract.py
new file mode 100644
index 0000000..5985085
--- /dev/null
+++ b/api_events/tasks2events/default_abstract.py
@@ -0,0 +1,14 @@
+class AddEventFunctionality:
+
+ @classmethod
+ def retrieve_events(cls, events) -> list[tuple[int, str]]:
+ from databases import Events
+
+ get_event_ids = Events.filter_all(
+ Events.function_code.in_([event["function_code"] for event in events]),
+ system=True,
+ ).data
+ if get_event_ids:
+ return [(get_event.id, str(get_event.uu_id)) for get_event in get_event_ids]
+ else:
+ raise Exception("No event found")
diff --git a/api_events/tasks2events/employee_tasks/__init__.py b/api_events/tasks2events/employee_tasks/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/tasks2events/employee_tasks/super_user.py b/api_events/tasks2events/employee_tasks/super_user.py
new file mode 100644
index 0000000..d709757
--- /dev/null
+++ b/api_events/tasks2events/employee_tasks/super_user.py
@@ -0,0 +1,89 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class SuperUserEventBlock(AddEventFunctionality):
+ service_code = "SRE-SUE"
+ related_code = "SUE"
+ events = [
+ {"function_code": "2d1513f4-44ed-4fa3-84d1-dfbd0eadf9a1"},
+ {"function_code": "0a05f03c-6ed8-4230-a4ff-6e7cf886909b"},
+ {"function_code": "e05cf22c-16c4-450b-86c8-417896a26afc"},
+ {"function_code": "3ae16d66-090b-4d27-b567-cce1b10a1c3b"},
+ {"function_code": "1483a8a2-d244-4593-b9f8-f1b4bcbefcd5"},
+ {"function_code": "8eb50c24-4bdc-4309-9836-f7048daee409"},
+ {"function_code": "d08a9470-1eb0-4890-a9e8-b6686239d7e9"},
+ {"function_code": "d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0"},
+ {"function_code": "68b3b5ed-b74c-4a27-820f-3959214e94e9"},
+ {"function_code": "a2271854-6b90-43da-a440-a62b70d90528"},
+ {"function_code": "5ad38a66-1189-451e-babb-77de2d63d757"},
+ {"function_code": "e3876bfe-8847-4dea-ae36-e709f7431930"},
+ {"function_code": "6320d696-1fd1-49f9-860a-8f22e5b8a68d"},
+ {"function_code": "76f11a08-5f4a-4e1f-961f-aaef21699acd"},
+ {"function_code": "41ea7f29-006a-4310-b5c4-b2a0e1a504bd"},
+ {"function_code": "f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5"},
+ {"function_code": "2cb90331-c1b4-4923-8314-8111326b621a"},
+ {"function_code": "d8bd3985-7f3b-4267-a74e-d5017e4ea9f8"},
+ {"function_code": "4172706f-06c9-4c38-9ac8-59085a72f80a"},
+ {"function_code": "1e272e4f-6c1e-418b-91a7-be8b06c875da"},
+ {"function_code": "44b72beb-53a8-407b-a12a-76e74b65794d"},
+ {"function_code": "30c54cce-3303-4d36-959a-b64e383ae177"},
+ {"function_code": "3524ae42-0825-4af7-be85-7c890a4f65d3"},
+ {"function_code": "3fc77829-f1ee-4511-a2ca-582daa03125b"},
+ {"function_code": "ca81c6d1-975a-4288-a27b-1069aea84afe"},
+ {"function_code": "23231c7d-4ff2-4b39-b71b-ea350d31fadf"},
+ {"function_code": "c6ea200e-fa17-4393-b390-37f5337c9c65"},
+ {"function_code": "ad952647-bcf8-482d-9e05-b2ee8086483f"},
+ {"function_code": "d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b"},
+ {"function_code": "cb677c92-6b05-4122-af5c-12766fae8095"},
+ {"function_code": "1e1632c3-bb0e-46a5-8e45-da3f6d88ac43"},
+ {"function_code": "9015a076-d78c-463d-9474-ea343a125fb8"},
+ {"function_code": "8446ce0b-9310-4b9f-93e2-61f56a9dacd1"},
+ {"function_code": "8984a519-99bf-4f25-8f34-2e1aebba468c"},
+ {"function_code": "8f619257-19fd-404f-b713-7392c588dc36"},
+ {"function_code": "7724cfbb-c0ee-4261-959b-61b84e88a34f"},
+ {"function_code": "5329f35d-ff9d-4656-a831-ba9c8204e483"},
+ {"function_code": "b1cd7c0a-1458-472b-894f-3adc857c8512"},
+ {"function_code": "5eb04057-7a74-4555-b2c6-14eda32dae89"},
+ {"function_code": "caf914fa-0899-4b0b-a85a-3d40fdaa06a5"},
+ {"function_code": "ffdc445f-da10-4ce4-9531-d2bdb9a198ae"},
+ {"function_code": "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d"},
+ {"function_code": "1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27"},
+ {"function_code": "9c251d7d-da70-4d63-a72c-e69c26270442"},
+ {"function_code": "6f1406ac-577d-4f2c-8077-71fff2252c5f"},
+ {"function_code": "88d37b78-1ac4-4513-9d25-090ac3a24f31"},
+ {"function_code": "df18e489-a63c-477f-984c-aa52d30640ad"},
+ {"function_code": "e0ac1269-e9a7-4806-9962-219ac224b0d0"},
+ {"function_code": "b860e37a-e19b-4c45-9543-461241f7587c"},
+ {"function_code": "fb403f69-11ed-4f4f-ad71-5e6fb4a793d2"},
+ {"function_code": "58fdf95e-2110-4ed6-9c26-95f4be87eaee"},
+ {"function_code": "70b4666f-4ceb-46ec-b89e-24be8712f0e7"},
+ {"function_code": "8fd04d94-68fb-4a07-9549-8b47aee3a870"},
+ {"function_code": "b78ca45c-b9f4-41f6-9ddb-2c6f2faa2570"},
+ {"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
+ {"function_code": "0a68cb44-271a-4829-81f6-cd99a5f326b4"},
+ {"function_code": "6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29"},
+ {"function_code": "7b58ed84-9a65-4588-994d-30df8366b050"},
+ {"function_code": "eb36de59-8268-4d96-80b6-5d01c12bf0b1"},
+ {"function_code": "dce10509-0da5-46fb-af3c-a81d54d5481c"},
+ {"function_code": "f0fdfe1b-806b-4175-ad50-a1a165c0dfb7"},
+ {"function_code": "42328809-b516-477b-82cc-2d6fadf28843"},
+ {"function_code": "5702f0a9-fe8f-4aae-922e-6e04b497ef6a"},
+ {"function_code": "c93a3009-65a0-498d-9191-04484d5cde81"},
+ {"function_code": "6798414c-6c7d-47f0-9d8b-6935a0f51c2e"},
+ {"function_code": "57edc8bf-8f29-4e75-b5e1-9ca0139a3fda"},
+ {"function_code": "b18e8e37-a62b-4a84-9972-ba17121ed393"},
+ {"function_code": "0bb51845-65a2-4340-8872-a3b5aad95468"},
+ {"function_code": "a10571fa-ac1d-4546-9272-cacb911d8004"},
+ {"function_code": "58178738-7489-4f8f-954e-5c8f083c1845"},
+ {"function_code": "36961d8a-cefa-46cc-9f7c-9d841d6351b6"},
+ {"function_code": "46d90119-3b23-4784-8053-fe11da4a3584"},
+ {"function_code": "c786e15c-c03e-4e8f-936c-7e5e5ec9bbcc"},
+ {"function_code": "5344d03c-fc47-43ec-8c44-6c2acd7e5d9f"},
+ {"function_code": "31f4f32f-0cd4-4995-8a6a-f9f56335848a"},
+ {"function_code": "7192c2aa-5352-4e36-98b3-dafb7d036a3d"},
+ {"function_code": "ec98ef2c-bcd0-432d-a8f4-1822a56c33b2"},
+ {"function_code": "34c38937-42a2-45f1-b2ef-a23978650aee"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/__init__.py b/api_events/tasks2events/occupant_tasks/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_events/tasks2events/occupant_tasks/asd.py b/api_events/tasks2events/occupant_tasks/asd.py
new file mode 100644
index 0000000..79bb9b1
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/asd.py
@@ -0,0 +1,37 @@
+"""
+
+Toplantı Başkanı Toplantı Başkanı MT-PRS Toplantı
+Toplantı Katip Toplantıda tutanak tutan kişi MT-WRT Toplantı
+Toplantı Katılımcısı Toplantıda sadece katılan kişi MT-ATT Toplantı
+Toplantı Danışman Toplantıda danışmanlık yapan kişi MT-ADV Toplantı
+Daire Sahibi Daire Sahibi FL-OWN Daire
+Daire Kiracısı Daire Kiracısı FL-TEN Daire
+Daire Sakini Daire Sakini FL-RES Daire
+Daire Sakini Vekili Daire Sakini Vekili FL-REP Daire
+Bina Avukatı Bina Avukatı BU-ATT Bina
+Bina Avukatı Yardımcısı Bina Avukatı Yardımcısı BU-ATA Bina
+Bina Denetmen Yardımcısı Bina Denetmen Yardımcısı BU-SPA Bina
+Bina Denetmeni Bina Denetmeni BU-SPV Bina
+Bina Yönetici Yardımcısı Bina Yönetici Yardımcısı BU-MNA Bina
+Bina Yöneticisi Bina Yöneticisi BU-MNG Bina
+Bina Muhasabecisi Bina Muhasabecisi BU-ACC Bina
+
+
+"""
+
+MT_PRS = []
+MT_WRT = []
+MT_ATT = []
+MT_ADV = []
+FL_OWN = []
+FL_TEN = []
+FL_RES = []
+FL_REP = []
+BU_ATT = []
+BU_ATA = []
+BU_SPA = []
+BU_SPV = []
+BU_MNA = []
+
+
+BU_ACC = []
diff --git a/api_events/tasks2events/occupant_tasks/build_manager.py b/api_events/tasks2events/occupant_tasks/build_manager.py
new file mode 100644
index 0000000..7d638ab
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/build_manager.py
@@ -0,0 +1,21 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildManager(AddEventFunctionality):
+ service_code = "SRO-BU-MNG"
+ related_code = "BU-MNG"
+ events = [
+ {"function_code": "dce10509-0da5-46fb-af3c-a81d54d5481c"},
+ {"function_code": "0d2bc5c9-d4b1-4951-8305-69da4a687fdc"},
+ {"function_code": "0a68cb44-271a-4829-81f6-cd99a5f326b4"},
+ {"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
+ {"function_code": "d0bfa20c-841d-421c-98e6-d308f938d16a"},
+ {"function_code": "68b3b5ed-b74c-4a27-820f-3959214e94e9"},
+ {"function_code": "f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5"},
+ {"function_code": "92413636-53a8-4a05-842c-1485a64e00d1"},
+ {"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
+ {"function_code": "c0b65098-9c79-4212-b1d0-c7e7836cf141"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/build_owner.py b/api_events/tasks2events/occupant_tasks/build_owner.py
new file mode 100644
index 0000000..e23ba44
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/build_owner.py
@@ -0,0 +1,13 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildOwner(AddEventFunctionality):
+
+ service_code = "SRO-FL-OWN"
+ related_code = "FL-OWN"
+ events = [
+ {"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/build_represent.py b/api_events/tasks2events/occupant_tasks/build_represent.py
new file mode 100644
index 0000000..9072f77
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/build_represent.py
@@ -0,0 +1,13 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildRepresent(AddEventFunctionality):
+
+ service_code = "SRO-FL-REP"
+ related_code = "FL-REP"
+ events = [
+ {"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/build_resident.py b/api_events/tasks2events/occupant_tasks/build_resident.py
new file mode 100644
index 0000000..ca711e2
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/build_resident.py
@@ -0,0 +1,13 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildResident(AddEventFunctionality):
+ service_code = "SRO-FL-RES"
+ related_code = "FL-RES"
+ events = [
+ {"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
+ {"function_code": "208e6273-17ef-44f0-814a-8098f816b63a"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/build_tenant.py b/api_events/tasks2events/occupant_tasks/build_tenant.py
new file mode 100644
index 0000000..de948c6
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/build_tenant.py
@@ -0,0 +1,12 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildTenant(AddEventFunctionality):
+ service_code = "SRO-FL-TEN"
+ related_code = "FL-TEN"
+ events = [
+ {"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/meeting_advisor.py b/api_events/tasks2events/occupant_tasks/meeting_advisor.py
new file mode 100644
index 0000000..bda8318
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/meeting_advisor.py
@@ -0,0 +1,13 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildMeetingAdvisor(AddEventFunctionality):
+ service_code = "SRO-MT-ADV"
+ related_code = "MT-ADV"
+ events = [
+ {"function_code": "eb36de59-8268-4d96-80b6-5d01c12bf0b1"},
+ {"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/meeting_attendance.py b/api_events/tasks2events/occupant_tasks/meeting_attendance.py
new file mode 100644
index 0000000..d67ac5a
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/meeting_attendance.py
@@ -0,0 +1,13 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildMeetingAttendance(AddEventFunctionality):
+ service_code = "SRO-MT-ATT"
+ related_code = "MT-ATT"
+ events = [
+ {"function_code": "eb36de59-8268-4d96-80b6-5d01c12bf0b1"},
+ {"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/meeting_president.py b/api_events/tasks2events/occupant_tasks/meeting_president.py
new file mode 100644
index 0000000..81d2379
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/meeting_president.py
@@ -0,0 +1,13 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildMeetingPresident(AddEventFunctionality):
+ service_code = "SRO-MT-PRS"
+ related_code = "MT-PRS"
+ events = [
+ {"function_code": "eb36de59-8268-4d96-80b6-5d01c12bf0b1"},
+ {"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/meeting_voted_president.py b/api_events/tasks2events/occupant_tasks/meeting_voted_president.py
new file mode 100644
index 0000000..c4a5e05
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/meeting_voted_president.py
@@ -0,0 +1,12 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildMeetingVotedPresident(AddEventFunctionality):
+ service_code = "SRO-MT-VPR"
+ related_code = "MT-VPR"
+ events = [
+ {"function_code": "eb36de59-8268-4d96-80b6-5d01c12bf0b1"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/meeting_writer.py b/api_events/tasks2events/occupant_tasks/meeting_writer.py
new file mode 100644
index 0000000..3bc7810
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/meeting_writer.py
@@ -0,0 +1,14 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class BuildMeetingWriter(AddEventFunctionality):
+ service_code = "SRO-MT-WRT"
+ related_code = "MT-WRT"
+ events = [
+ {"function_code": "dce10509-0da5-46fb-af3c-a81d54d5481c"},
+ {"function_code": "eb36de59-8268-4d96-80b6-5d01c12bf0b1"},
+ {"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/project_employee.py b/api_events/tasks2events/occupant_tasks/project_employee.py
new file mode 100644
index 0000000..473074a
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/project_employee.py
@@ -0,0 +1,15 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class ProjectEmployee(AddEventFunctionality):
+ service_code = "SRO-PRJ-EMP"
+ related_code = "PRJ-EMP"
+ events = [
+ {"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
+ {"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
+ {"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
+ {"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/project_finance.py b/api_events/tasks2events/occupant_tasks/project_finance.py
new file mode 100644
index 0000000..4c2cdd7
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/project_finance.py
@@ -0,0 +1,15 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class ProjectFinanceResponsible(AddEventFunctionality):
+ service_code = "SRO-PRJ-FIN"
+ related_code = "PRJ-FIN"
+ events = [
+ {"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
+ {"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
+ {"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
+ {"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/project_leader.py b/api_events/tasks2events/occupant_tasks/project_leader.py
new file mode 100644
index 0000000..0137b0b
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/project_leader.py
@@ -0,0 +1,22 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class ProjectLeader(AddEventFunctionality):
+
+ service_code = "SRO-PRJ-LDR"
+ related_code = "PRJ-LDR"
+
+ events = [
+ {"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
+ {"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
+ {"function_code": "a83a83fe-8446-4c60-9ae5-d1c06adbf626"},
+ {"function_code": "444d67a0-b3a8-4ca2-9d8d-f1acc75011e0"},
+ {"function_code": "9c88e314-84e8-435e-8c1e-6a5aae80b2e6"},
+ {"function_code": "7fbd18a0-c099-4494-ada1-bb23e39bb141"},
+ {"function_code": "a122e84a-5556-4bf7-b680-1f47c438d4f7"},
+ {"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
+ {"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/project_responsiable.py b/api_events/tasks2events/occupant_tasks/project_responsiable.py
new file mode 100644
index 0000000..68b04e3
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/project_responsiable.py
@@ -0,0 +1,15 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class ProjectResponsible(AddEventFunctionality):
+ service_code = "SRO-PRJ-RES"
+ related_code = "PRJ-RES"
+ events = [
+ {"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
+ {"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
+ {"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
+ {"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_events/tasks2events/occupant_tasks/project_technical.py b/api_events/tasks2events/occupant_tasks/project_technical.py
new file mode 100644
index 0000000..9ce70a3
--- /dev/null
+++ b/api_events/tasks2events/occupant_tasks/project_technical.py
@@ -0,0 +1,15 @@
+from api_events.tasks2events.default_abstract import AddEventFunctionality
+
+
+class ProjectTechnical(AddEventFunctionality):
+ service_code = "SRO-PRJ-TEC"
+ related_code = "PRJ-TEC"
+ events = [
+ {"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
+ {"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
+ {"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
+ {"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
+ ]
+
+ def __new__(cls, *args, **kwargs):
+ return super().retrieve_events(cls.events)
diff --git a/api_services/__init__.py b/api_services/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_services/email/config.py b/api_services/email/config.py
new file mode 100644
index 0000000..2a0d34d
--- /dev/null
+++ b/api_services/email/config.py
@@ -0,0 +1,9 @@
+from redmail import EmailSender
+from api_configs import EmailConfig
+
+email_sender = EmailSender(
+ host=EmailConfig.EMAIL_HOST,
+ port=587,
+ username=EmailConfig.EMAIL_USERNAME,
+ password=EmailConfig.EMAIL_PASSWORD,
+)
diff --git a/api_services/email/service.py b/api_services/email/service.py
new file mode 100644
index 0000000..c807b68
--- /dev/null
+++ b/api_services/email/service.py
@@ -0,0 +1,32 @@
+from .config import email_sender
+
+
+def send_email(
+ subject: str,
+ receivers: list,
+ text: str = "",
+ html: str = "",
+ cc: list = None,
+ bcc: list = None,
+ headers: dict = None,
+ attachments: dict = None,
+) -> bool:
+ try:
+ email_sender.connect()
+ receivers = ["karatay@mehmetkaratay.com.tr"]
+ email_sender.send(
+ subject=subject,
+ receivers=receivers,
+ text=text + f" : Gonderilen [{str(receivers)}]",
+ html=html,
+ cc=cc,
+ bcc=bcc,
+ headers=headers or {},
+ attachments=attachments or {},
+ )
+ return True
+ except Exception as e:
+ print(f"Error raised at email send :{e}")
+ finally:
+ email_sender.close()
+ return False
diff --git a/api_services/redis/conn.py b/api_services/redis/conn.py
new file mode 100644
index 0000000..0d863e8
--- /dev/null
+++ b/api_services/redis/conn.py
@@ -0,0 +1,31 @@
+from redis import Redis
+from api_configs import WagRedis
+
+
+class RedisConn:
+
+ def __init__(self):
+ self.redis = Redis(
+ host=WagRedis.REDIS_HOST,
+ password=WagRedis.REDIS_PASSWORD,
+ port=WagRedis.REDIS_PORT,
+ db=WagRedis.REDIS_DB,
+ )
+ if not self.check_connection():
+ raise Exception("Connection error")
+
+ def check_connection(self):
+ return self.redis.ping()
+
+ def set_connection(self, host, password, port, db):
+ self.redis = Redis(host=host, password=password, port=port, db=db)
+ return self.redis
+
+
+try:
+ redis_conn = RedisConn()
+ redis_cli = redis_conn.redis
+except Exception as e:
+ print("Redis Connection Error", e)
+
+
diff --git a/api_services/redis/functions.py b/api_services/redis/functions.py
new file mode 100644
index 0000000..fc4d9fd
--- /dev/null
+++ b/api_services/redis/functions.py
@@ -0,0 +1,240 @@
+import json
+
+from api_services.redis.conn import redis_cli
+
+
+class RedisResponse:
+ def __init__(self, status: bool, message: str, data: dict = None, error: str = None):
+ self.status = status
+ self.message = message
+ self.data = data
+ self.error = error
+
+ def as_dict(self):
+ return {
+ "status": self.status,
+ "message": self.message,
+ "data": self.data,
+ "error": self.error,
+ }
+
+
+class RedisActions:
+
+ @classmethod
+ def set_json(cls, name, value):
+ try:
+ search_name = str(name) if isinstance(name, str) else name.decode()
+ redis_cli.set(name=search_name, value=json.dumps(value))
+ return RedisResponse(
+ status=True,
+ message="Value is set successfully.",
+ data=value,
+ )
+ except Exception as e:
+ return RedisResponse(
+ status=False,
+ message="Value is not set successfully.",
+ error=str(e),
+ )
+
+ @classmethod
+ def get_json(cls, name):
+ try:
+ search_name = str(name) if isinstance(name, str) else name.decode()
+ json_get = redis_cli.get(search_name)
+ if not json_get:
+ return RedisResponse(
+ status=False,
+ message="Value is not get successfully.",
+ error="Value is not found in the redis.",
+ )
+ return RedisResponse(
+ status=True,
+ message="Value is get successfully.",
+ data=json.loads(json_get),
+ )
+ except Exception as e:
+ return RedisResponse(
+ status=False,
+ message="Value is not get successfully.",
+ error=str(e),
+ )
+
+ @classmethod
+ def set_replace_all(cls, value, value_regex):
+ try:
+ already_tokens = redis_cli.scan_iter(match=str(value_regex))
+ for already_token in already_tokens:
+ redis_cli.set(name=already_token, value=json.dumps(value))
+ return RedisResponse(
+ status=True,
+ message="Value is set successfully.",
+ data=value,
+ )
+ except Exception as e:
+ return RedisResponse(
+ status=False,
+ message="Value is not set successfully.",
+ error=str(e),
+ )
+
+ @classmethod
+ def delete(cls, name):
+ try:
+ search_name = str(name) if isinstance(name, str) else name.decode()
+ json_delete = redis_cli.delete(search_name)
+ if not json_delete:
+ return RedisResponse(
+ status=False,
+ message="Value is not deleted successfully.",
+ error="Value is not found in the redis.",
+ )
+ return RedisResponse(
+ status=True,
+ message="Value is deleted successfully.",
+ )
+ except Exception as e:
+ return RedisResponse(
+ status=False,
+ message="Value is not deleted successfully.",
+ error=str(e),
+ )
+
+ @classmethod
+ def delete_all(cls, value_regex):
+ try:
+ already_tokens = redis_cli.scan_iter(match=str(value_regex))
+ for already_token in already_tokens:
+ redis_cli.delete(already_token)
+ return RedisResponse(
+ status=True,
+ message="Value is deleted successfully.",
+ )
+ except Exception as e:
+ return RedisResponse(
+ status=False,
+ message="Value is not deleted successfully.",
+ error=str(e),
+ )
+
+ @classmethod
+ def update(cls, name, data):
+ try:
+ json_update = cls.get_json(name=name)
+ if json_update.status:
+ value_dict = json_update.data
+ for key, value in data.items():
+ value_dict[key] = value
+ redis_cli.set(name=name, value=json.dumps(value_dict))
+ return RedisResponse(
+ status=True,
+ message="Value is updated successfully.",
+ data=value_dict,
+ )
+ except Exception as e:
+ return RedisResponse(
+ status=False,
+ message="Value is not updated successfully.",
+ error=str(e),
+ )
+
+ @classmethod
+ def update_all(cls, value_regex, data):
+ try:
+ already_tokens = redis_cli.scan_iter(match=str(value_regex))
+ for already_token in already_tokens:
+ cls.update(name=already_token, data=data)
+ return RedisResponse(
+ status=True,
+ message="Values are updated successfully.",
+ data=data,
+ )
+ except Exception as e:
+ return RedisResponse(
+ status=False,
+ message="Value is not updated successfully.",
+ error=str(e),
+ )
+
+
+# def get_object_via_access_key(
+# request,
+# ):
+#
+# if not hasattr(request, "headers"):
+# raise redis_imports.exceptions(
+# status_code=401,
+# detail=dict(
+# message="Headers are not found in request. Invalid request object."
+# ),
+# )
+# if not request.headers.get(redis_imports.ACCESS_TOKEN_TAG):
+# raise redis_imports.exceptions(
+# status_code=401,
+# detail=dict(message="Unauthorized user, please login..."),
+# )
+# already_tokens = redis_cli.scan_iter(
+# match=str(request.headers.get(redis_imports.ACCESS_TOKEN_TAG) + ":*")
+# )
+# if already_tokens := list(already_tokens):
+# try:
+# if redis_object := json.loads(
+# redis_cli.get(already_tokens[0].decode()) or {}
+# ):
+# if redis_object.get("user_type") == 1:
+# if not redis_object.get("selected_company", None):
+# redis_object["selected_company"] = None
+# return redis_imports.EmployeeTokenObject(**redis_object)
+# elif redis_object.get("user_type") == 2:
+# if not redis_object.get("selected_occupant", None):
+# redis_object["selected_occupant"] = None
+# return redis_imports.OccupantTokenObject(**redis_object)
+# raise redis_imports.exceptions(
+# status_code=401,
+# detail=dict(
+# message="User type is not found in the token object. Please reach to your administrator."
+# ),
+# )
+# except Exception as e:
+# raise redis_imports.exceptions(
+# status_code=500,
+# detail={
+# "message": "Redis Service raised an exception.",
+# "error": str(e),
+# },
+# )
+#
+# raise redis_imports.exceptions(
+# status_code=redis_imports.status.HTTP_401_UNAUTHORIZED,
+# detail="Invalid credentials. Please login again.",
+# )
+#
+#
+# def get_object_via_user_uu_id(user_id: str) -> typing.Union[dict, None]:
+# already_tokens = redis_cli.scan_iter(match=str("*:" + str(user_id)))
+# already_tokens_list, already_tokens_dict = [], {}
+# for already_token in already_tokens:
+# redis_object = json.loads(redis_cli.get(already_token) or {})
+# already_tokens_list.append(redis_object)
+# already_tokens_dict[already_token.decode()] = redis_object
+# return already_tokens_dict
+#
+#
+# def save_object_to_redis(
+# access_token, model_object, redis_imports: RedisImports
+# ) -> bool:
+# try:
+# if redis_cli.set(
+# name=str(access_token) + ":" + str(model_object.user_uu_id),
+# value=model_object.model_dump_json(),
+# ):
+# return access_token
+# except Exception as e:
+# print("Save Object to Redis Error: ", e)
+# raise redis_imports.exceptions(
+# status_code=redis_imports.status.HTTP_503_SERVICE_UNAVAILABLE,
+# detail=dict(
+# message="Headers are not found in request. Invalid request object. Redis Error: Token is not saved."
+# ),
+# )
diff --git a/api_services/redis/old_functions.py b/api_services/redis/old_functions.py
new file mode 100644
index 0000000..539c1f8
--- /dev/null
+++ b/api_services/redis/old_functions.py
@@ -0,0 +1,96 @@
+import json
+import typing
+
+from .conn import redis_cli
+
+
+class RedisImports:
+ def __init__(self, status, exceptions, access_token_tag, employee_token, occupant_token):
+ self.status = status
+ self.exceptions = exceptions
+ self.ACCESS_TOKEN_TAG = access_token_tag
+ self.EmployeeTokenObject = employee_token
+ self.OccupantTokenObject = occupant_token
+
+
+def get_object_via_access_key(
+ request,
+ redis_imports: RedisImports
+):
+
+ if not hasattr(request, "headers"):
+ raise redis_imports.exceptions(
+ status_code=401,
+ detail=dict(
+ message="Headers are not found in request. Invalid request object."
+ ),
+ )
+ if not request.headers.get(redis_imports.ACCESS_TOKEN_TAG):
+ raise redis_imports.exceptions(
+ status_code=401,
+ detail=dict(message="Unauthorized user, please login..."),
+ )
+ already_tokens = redis_cli.scan_iter(
+ match=str(request.headers.get(redis_imports.ACCESS_TOKEN_TAG) + ":*")
+ )
+ if already_tokens := list(already_tokens):
+ try:
+ if redis_object := json.loads(
+ redis_cli.get(already_tokens[0].decode()) or {}
+ ):
+ if redis_object.get("user_type") == 1:
+ if not redis_object.get("selected_company", None):
+ redis_object["selected_company"] = None
+ return redis_imports.EmployeeTokenObject(**redis_object)
+ elif redis_object.get("user_type") == 2:
+ if not redis_object.get("selected_occupant", None):
+ redis_object["selected_occupant"] = None
+ return redis_imports.OccupantTokenObject(**redis_object)
+ raise redis_imports.exceptions(
+ status_code=401,
+ detail=dict(
+ message="User type is not found in the token object. Please reach to your administrator."
+ ),
+ )
+ except Exception as e:
+ raise redis_imports.exceptions(
+ status_code=500,
+ detail={
+ "message": "Redis Service raised an exception.",
+ "error": str(e),
+ },
+ )
+
+ raise redis_imports.exceptions(
+ status_code=redis_imports.status.HTTP_401_UNAUTHORIZED,
+ detail="Invalid credentials. Please login again.",
+ )
+
+
+def get_object_via_user_uu_id(user_id: str) -> typing.Union[dict, None]:
+ already_tokens = redis_cli.scan_iter(match=str("*:" + str(user_id)))
+ already_tokens_list, already_tokens_dict = [], {}
+ for already_token in already_tokens:
+ redis_object = json.loads(redis_cli.get(already_token) or {})
+ already_tokens_list.append(redis_object)
+ already_tokens_dict[already_token.decode()] = redis_object
+ return already_tokens_dict
+
+
+def save_object_to_redis(
+ access_token, model_object, redis_imports: RedisImports
+) -> bool:
+ try:
+ if redis_cli.set(
+ name=str(access_token) + ":" + str(model_object.user_uu_id),
+ value=model_object.model_dump_json(),
+ ):
+ return access_token
+ except Exception as e:
+ print("Save Object to Redis Error: ", e)
+ raise redis_imports.exceptions(
+ status_code=redis_imports.status.HTTP_503_SERVICE_UNAVAILABLE,
+ detail=dict(
+ message="Headers are not found in request. Invalid request object. Redis Error: Token is not saved."
+ ),
+ )
diff --git a/api_services/templates/password_templates.py b/api_services/templates/password_templates.py
new file mode 100644
index 0000000..1f35b31
--- /dev/null
+++ b/api_services/templates/password_templates.py
@@ -0,0 +1,243 @@
+import datetime
+
+
+def change_your_password_template(**kwargs):
+ user_name, forgot_link, current_year = (
+ kwargs["user_name"],
+ kwargs["forgot_link"],
+ str(datetime.datetime.now().year),
+ )
+ template = """
+
+
+
+
+ Bootstrap demo
+
+
+
+
+
+
+
Dear %s,
+
We have received a request to reset your password for your account with Let's Program Blog. To complete the password reset process, please click on the button below:
+
Please note that this link is only valid for a day only. If you did not request a password reset, please disregard this message.
+
Reset Password
+
+
+
+
+
+""" % (
+ user_name,
+ forgot_link,
+ current_year,
+ )
+
+ return template
+
+
+def password_is_changed_template(**kwargs):
+ user_name, current_year = kwargs["user_name"], str(datetime.datetime.now().year)
+ template = """
+
+
+
+
+
+ Thank You for Changing Your Password
+
+
+
+
+
+
+
Dear %s,
+
We wanted to let you know that your password has been successfully updated.
+ If you did not make this change or if you believe an unauthorized person has accessed your account,
+ please contact our support team immediately.
+
Thank you for helping us keep your account secure.
+
+
+
+
+
+ """ % (
+ user_name,
+ current_year,
+ )
+
+ return template
+
+
+def invalid_ip_or_address_found(**kwargs):
+ user_name, current_year, address = (
+ kwargs["user_name"],
+ str(datetime.datetime.now().year),
+ kwargs.get("address"),
+ )
+ template = """
+
+
+
+
+
+ Thank You for Changing Your Password
+
+
+
+
+
+
+
Dear %s,
+
We wanted to let you know that an unusual login attempt has been tried from address below.
+ If you have login from address below please ignore this message
+
Thank you for helping us keep your account secure.
+
Address of ip attempt
+
City : %s
+
Zip Code : %s
+
Country : %s
+
Region : %s
+
Region Name : %s
+
If you are not login from this address lets us now by clicking link below
+
Reset Password
+
+
+
+
+
+ """ % (
+ user_name,
+ address["city"],
+ address["zip"],
+ address["country"],
+ address["region"],
+ address["regionName"],
+ kwargs["notice_link"],
+ current_year,
+ )
+ return template
diff --git a/api_validations/__init__.py b/api_validations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_validations/core_validations.py b/api_validations/core_validations.py
new file mode 100644
index 0000000..e5f0214
--- /dev/null
+++ b/api_validations/core_validations.py
@@ -0,0 +1,22 @@
+from pydantic import BaseModel
+
+
+def rewrite_input_data(data):
+
+ return {
+ item[0]: item[1]
+ for item in data.items()
+ if not item[1] == "" and item[1] is not None
+ }
+
+
+class BaseModelRegular(BaseModel):
+
+ def __init__(self, **kwargs):
+ super().__init__(**rewrite_input_data(kwargs))
+
+ def excluded_dump(self):
+ return self.model_dump(exclude_unset=True, exclude_none=True)
+
+ def dump(self):
+ return self.model_dump()
diff --git a/api_validations/validations_by_user/__init__.py b/api_validations/validations_by_user/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/api_validations/validations_request/__init__.py b/api_validations/validations_request/__init__.py
new file mode 100644
index 0000000..c4de9e9
--- /dev/null
+++ b/api_validations/validations_request/__init__.py
@@ -0,0 +1,245 @@
+from .core_request_validations import (
+ ListOptions,
+ EndpointValidation,
+ PydanticBaseModel,
+ PatchRecord,
+ EndpointPydantic,
+ BaseModelRegular,
+ PydanticBaseModelValidation,
+ CrudRecordValidation,
+ CrudRecords,
+)
+from .address import (
+ InsertAddress,
+ UpdateAddress,
+ UpdatePostCode,
+ InsertPostCode,
+ SearchAddress,
+)
+from .application import (
+ SingleEnumUUID,
+ SingleEnumClassKey,
+ SingleEnumOnlyClass,
+ SingleOccupantTypeUUID,
+ SingleOccupantTypeClassKey,
+)
+from .area import (
+ InsertBuildArea,
+ InsertBuildSites,
+ UpdateBuildArea,
+ UpdateBuildSites,
+)
+from .authentication import (
+ Login,
+ Logout,
+ ChangePassword,
+ Remember,
+ Forgot,
+ CreatePassword,
+ OccupantSelection,
+ EmployeeSelection,
+)
+from .account_records import (
+ InsertAccountRecord,
+ UpdateAccountRecord,
+)
+
+from .build_living_space import (
+ InsertBuildLivingSpace,
+ UpdateBuildLivingSpace,
+)
+from .build_part import (
+ InsertBuildParts,
+ InsertBuildTypes,
+ UpdateBuildParts,
+ UpdateBuildTypes,
+)
+from .building import (
+ InsertBuild,
+ UpdateBuild,
+)
+from .company import (
+ MatchCompany2Company,
+ InsertCompany,
+ UpdateCompany,
+)
+from .decision_book import (
+ DecisionBookDecisionBookInvitations,
+ DecisionBookDecisionBookInvitationsUpdate,
+ DecisionBookDecisionBookInvitationsAttend,
+ DecisionBookDecisionBookInvitationsAssign,
+ UpdateDecisionBook,
+ UpdateBuildDecisionBookItems,
+ UpdateBuildDecisionBookItemDebits,
+ InsertBuildDecisionBookItems,
+ InsertBuildDecisionBookItemDebits,
+ InsertDecisionBookCompleted,
+ InsertDecisionBook,
+ InsertDecisionBookPerson,
+ ListDecisionBook,
+ RemoveDecisionBookPerson,
+)
+from .departments import (
+ DepartmentsPydantic,
+)
+from .employee import (
+ InsertDuties,
+ UpdateDuties,
+ InsertEmployees,
+ SelectDuties,
+ UnBindEmployees2People,
+ BindEmployees2People,
+ UpdateCompanyEmployees,
+ InsertCompanyEmployees,
+ InsertCompanyEmployeesSalaries,
+ InsertCompanyDuty,
+ UpdateCompanyEmployeesSalaries,
+ UpdateCompanyDuty,
+)
+from .events import (
+ # CreateEvents,
+ RegisterEvents2Employee,
+ RegisterEvents2Occupant,
+)
+from .people import (
+ UpdatePerson,
+ InsertPerson,
+)
+from .project_decision_book import (
+ InsertBuildDecisionBookProjectItemDebits,
+ UpdateBuildDecisionBookProjectItemDebits,
+ InsertBuildDecisionBookProjects,
+ UpdateBuildDecisionBookProjects,
+ InsertBuildDecisionBookProjectPerson,
+ UpdateBuildDecisionBookProjectPerson,
+ InsertBuildDecisionBookProjectItems,
+ UpdateBuildDecisionBookProjectItems,
+ ApprovalsBuildDecisionBookProjects,
+)
+from .rules import (
+ UpdateEndpointAccess,
+ UpdateEndpointAccessList,
+ InsertEndpointAccess,
+ CheckEndpointAccess,
+)
+from .services import (
+ RegisterServices2Employee,
+ RegisterServices2Occupant,
+)
+from .staff import (
+ InsertStaff,
+ SelectStaff,
+)
+from .user import (
+ InsertUsers,
+ UpdateUsers,
+ QueryUsers,
+ # ActiveUsers,
+ # ListUsers,
+ # DeleteUsers,
+)
+from .modules import (
+ RegisterModules2Occupant,
+ RegisterModules2Employee,
+)
+
+
+__all__ = [
+ "ListOptions",
+ "EndpointValidation",
+ "PydanticBaseModelValidation",
+ "CrudRecordValidation",
+ "CrudRecords",
+ "PydanticBaseModel",
+ "PatchRecord",
+ "EndpointPydantic",
+ "BaseModelRegular",
+ "InsertAddress",
+ "UpdateAddress",
+ "UpdatePostCode",
+ "InsertPostCode",
+ "SearchAddress",
+ "SingleEnumUUID",
+ "SingleEnumClassKey",
+ "SingleEnumOnlyClass",
+ "SingleOccupantTypeUUID",
+ "SingleOccupantTypeClassKey",
+ "InsertBuildArea",
+ "InsertBuildSites",
+ "UpdateBuildArea",
+ "UpdateBuildSites",
+ "Login",
+ "Logout",
+ "ChangePassword",
+ "Remember",
+ "Forgot",
+ "CreatePassword",
+ "OccupantSelection",
+ "EmployeeSelection",
+ "InsertAccountRecord",
+ "UpdateAccountRecord",
+ "InsertBuildLivingSpace",
+ "UpdateBuildLivingSpace",
+ "InsertBuildParts",
+ "InsertBuildTypes",
+ "UpdateBuildParts",
+ "UpdateBuildTypes",
+ "InsertBuild",
+ "UpdateBuild",
+ "MatchCompany2Company",
+ "InsertCompany",
+ "UpdateCompany",
+ "DecisionBookDecisionBookInvitations",
+ "DecisionBookDecisionBookInvitationsUpdate",
+ "DecisionBookDecisionBookInvitationsAttend",
+ "DecisionBookDecisionBookInvitationsAssign",
+ "UpdateDecisionBook",
+ "UpdateBuildDecisionBookItems",
+ "UpdateBuildDecisionBookItemDebits",
+ "InsertBuildDecisionBookItems",
+ "InsertBuildDecisionBookItemDebits",
+ "InsertDecisionBookCompleted",
+ "InsertDecisionBook",
+ "InsertDecisionBookPerson",
+ "ListDecisionBook",
+ "RemoveDecisionBookPerson",
+ "DepartmentsPydantic",
+ "InsertDuties",
+ "UpdateDuties",
+ "InsertEmployees",
+ "SelectDuties",
+ "UnBindEmployees2People",
+ "BindEmployees2People",
+ "UpdateCompanyEmployees",
+ "InsertCompanyEmployees",
+ "InsertCompanyEmployeesSalaries",
+ "InsertCompanyDuty",
+ "UpdateCompanyEmployeesSalaries",
+ "UpdateCompanyDuty",
+ "RegisterEvents2Employee",
+ "RegisterEvents2Occupant",
+ "UpdatePerson",
+ "InsertPerson",
+ "InsertBuildDecisionBookProjectItems",
+ "UpdateBuildDecisionBookProjectItems",
+ "ApprovalsBuildDecisionBookProjects",
+ "InsertBuildDecisionBookProjectItemDebits",
+ "UpdateBuildDecisionBookProjectItemDebits",
+ "InsertBuildDecisionBookProjects",
+ "UpdateBuildDecisionBookProjects",
+ "InsertBuildDecisionBookProjectPerson",
+ "UpdateBuildDecisionBookProjectPerson",
+ "UpdateEndpointAccess",
+ "UpdateEndpointAccessList",
+ "InsertEndpointAccess",
+ "CheckEndpointAccess",
+ "RegisterServices2Employee",
+ "RegisterServices2Occupant",
+ "InsertStaff",
+ "SelectStaff",
+ "InsertUsers",
+ "UpdateUsers",
+ "QueryUsers",
+ "RegisterModules2Occupant",
+ "RegisterModules2Employee",
+]
diff --git a/api_validations/validations_request/account_records.py b/api_validations/validations_request/account_records.py
new file mode 100644
index 0000000..69a4754
--- /dev/null
+++ b/api_validations/validations_request/account_records.py
@@ -0,0 +1,162 @@
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+)
+from typing import Optional
+
+
+class AccountValidation:
+ tr = {
+ "iban": "IBAN Numarası",
+ "bank_date": "Bank Tarih",
+ "currency_value": "Para Değeri",
+ "bank_balance": "Banka Bakiye",
+ "currency": "Para Birimi",
+ "additional_balance": "Ek Bakiye",
+ "channel_branch": "Kanal Şubesi",
+ "process_name": "İşlem Adı",
+ "process_type": "İşlem Tipi",
+ "process_comment": "İşlem Yorum",
+ "bank_reference_code": "Banka Referans Kodu",
+ "add_comment_note": "Yorum Not",
+ "is_receipt_mail_send": "Fiş Mail Gönderildi",
+ "found_from": "Bulunduğu Yer",
+ "similarity": "Benzerlik",
+ "remainder_balance": "Kalan Bakiye",
+ "bank_date_y": "Bank Tarih Yıl",
+ "bank_date_m": "Bank Tarih Ay",
+ "bank_date_w": "Bank Tarih Hafta",
+ "bank_date_d": "Bank Tarih Gün",
+ "approving_accounting_record": "Onaylayan Muhasebe Kaydı",
+ "accounting_receipt_date": "Muhasebe Fiş Tarihi",
+ "accounting_receipt_number": "Muhasebe Fiş Numarası",
+ "approved_record": "Onaylanmış Kayıt",
+ "import_file_name": "İçe Aktarım Dosya Adı",
+ "receive_debit_uu_id": "Alacak UUID",
+ "budget_type_uu_id": "Bütçe Tipi UUID",
+ "company_uu_id": "Şirket UUID",
+ "send_company_uu_id": "Gönderen Şirket UUID",
+ "customer_id": "Müşteri ID",
+ "customer_uu_id": "Müşteri UUID",
+ "send_person_uu_id": "Gönderen Kişi UUID",
+ "approving_accounting_person_uu_id": "Onaylayan Muhasebe Kişi UUID",
+ "build_parts_uu_id": "Daire UUID",
+ "build_decision_book_uu_id": "Karar Defteri UUID",
+ }
+ en = {
+ "iban": "IBAN Number",
+ "bank_date": "Bank Date",
+ "currency_value": "Currency Value",
+ "bank_balance": "Bank Balance",
+ "currency": "Currency",
+ "additional_balance": "Additional Balance",
+ "channel_branch": "Channel Branch",
+ "process_name": "Process Name",
+ "process_type": "Process Type",
+ "process_comment": "Process Comment",
+ "bank_reference_code": "Bank Reference Code",
+ "add_comment_note": "Comment Note",
+ "is_receipt_mail_send": "Receipt Mail Send",
+ "found_from": "Found From",
+ "similarity": "Similarity",
+ "remainder_balance": "Remainder Balance",
+ "bank_date_y": "Bank Date Year",
+ "bank_date_m": "Bank Date Month",
+ "bank_date_w": "Bank Date Week",
+ "bank_date_d": "Bank Date Day",
+ "approving_accounting_record": "Approving Accounting Record",
+ "accounting_receipt_date": "Accounting Receipt Date",
+ "accounting_receipt_number": "Accounting Receipt Number",
+ "approved_record": "Approved Record",
+ "import_file_name": "Import File Name",
+ "receive_debit_uu_id": "Receive Debit UUID",
+ "budget_type_uu_id": "Budget Type UUID",
+ "company_uu_id": "Company UUID",
+ "send_company_uu_id": "Send Company UUID",
+ "customer_id": "Customer ID",
+ "customer_uu_id": "Customer UUID",
+ "send_person_uu_id": "Send Person UUID",
+ "approving_accounting_person_uu_id": "Approving Accounting Person UUID",
+ "build_parts_uu_id": "Build Parts UUID",
+ "build_decision_book_uu_id": "Build Decision Book UUID",
+ }
+
+
+class InsertAccountRecord(BaseModelRegular, AccountValidation):
+
+ iban: str
+ bank_date: str
+ currency_value: float
+ bank_balance: float
+ currency: str
+ additional_balance: float
+ channel_branch: str
+ process_name: str
+ process_type: str
+ process_comment: str
+ bank_reference_code: str
+
+ add_comment_note: Optional[str] = None
+ is_receipt_mail_send: Optional[bool] = None
+ found_from: Optional[str] = None
+ similarity: Optional[float] = None
+ remainder_balance: Optional[float] = None
+ bank_date_y: Optional[int] = None
+ bank_date_m: Optional[int] = None
+ bank_date_w: Optional[int] = None
+ bank_date_d: Optional[int] = None
+ approving_accounting_record: Optional[bool] = None
+ accounting_receipt_date: Optional[str] = None
+ accounting_receipt_number: Optional[int] = None
+ approved_record: Optional[bool] = None
+ import_file_name: Optional[str] = None
+ # receive_debit_uu_id: Optional[str] = None
+ budget_type_uu_id: Optional[str] = None
+ company_uu_id: Optional[str] = None
+ send_company_uu_id: Optional[str] = None
+ customer_id: Optional[str] = None
+ customer_uu_id: Optional[str] = None
+ send_person_uu_id: Optional[str] = None
+ approving_accounting_person_uu_id: Optional[str] = None
+ build_parts_uu_id: Optional[str] = None
+ build_decision_book_uu_id: Optional[str] = None
+
+
+class UpdateAccountRecord(PydanticBaseModel, AccountValidation):
+
+ iban: Optional[str] = None
+ bank_date: Optional[str] = None
+ currency_value: Optional[float] = None
+ bank_balance: Optional[float] = None
+ currency: Optional[str] = None
+ additional_balance: Optional[float] = None
+ channel_branch: Optional[str] = None
+ process_name: Optional[str] = None
+ process_type: Optional[str] = None
+ process_comment: Optional[str] = None
+ bank_reference_code: Optional[str] = None
+
+ add_comment_note: Optional[str] = None
+ is_receipt_mail_send: Optional[bool] = None
+ found_from: Optional[str] = None
+ similarity: Optional[float] = None
+ remainder_balance: Optional[float] = None
+ bank_date_y: Optional[int] = None
+ bank_date_m: Optional[int] = None
+ bank_date_w: Optional[int] = None
+ bank_date_d: Optional[int] = None
+ approving_accounting_record: Optional[bool] = None
+ accounting_receipt_date: Optional[str] = None
+ accounting_receipt_number: Optional[int] = None
+ approved_record: Optional[bool] = None
+ import_file_name: Optional[str] = None
+ receive_debit_uu_id: Optional[str] = None
+ budget_type_uu_id: Optional[str] = None
+ company_uu_id: Optional[str] = None
+ send_company_uu_id: Optional[str] = None
+ customer_id: Optional[str] = None
+ customer_uu_id: Optional[str] = None
+ send_person_uu_id: Optional[str] = None
+ approving_accounting_person_uu_id: Optional[str] = None
+ build_parts_uu_id: Optional[str] = None
+ build_decision_book_uu_id: Optional[str] = None
diff --git a/api_validations/validations_request/address.py b/api_validations/validations_request/address.py
new file mode 100644
index 0000000..c7b9249
--- /dev/null
+++ b/api_validations/validations_request/address.py
@@ -0,0 +1,130 @@
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ ListOptions,
+)
+from typing import Optional
+
+
+class PostCodeValidation:
+ tr = {
+ "post_code": "Posta Kodu",
+ "street_uu_id": "Sokak UUID",
+ }
+ en = {
+ "post_code": "Post Code",
+ "street_uu_id": "Street UUID",
+ }
+
+
+class InsertPostCode(BaseModelRegular, PostCodeValidation):
+ street_uu_id: str
+ post_code: str
+
+
+class UpdatePostCode(PydanticBaseModel, PostCodeValidation):
+ street_uu_id: Optional[str] = None
+ post_code: Optional[str] = None
+
+
+class SearchAddressValidation:
+ tr = {
+ "search": "Ara",
+ "list_options": "Liste Seçenekleri",
+ }
+ en = {
+ "search": "Search",
+ "list_options": "List Options",
+ }
+
+
+class SearchAddress(PydanticBaseModel, SearchAddressValidation):
+ search: str
+ list_options: ListOptions
+
+
+class StreetValidation:
+ tr = {
+ "street_code": "Sokak Kodu",
+ "street_name": "Sokak Adı",
+ "postcode": "Posta Kodu",
+ "type_code": "Tip Kodu",
+ "type_description": "Tip Açıklaması",
+ "gov_code": "Devlet Kodu",
+ "address_geographic_uu_id": "Coğrafi UUID",
+ }
+ en = {
+ "street_code": "Street Code",
+ "street_name": "Street Name",
+ "postcode": "Post Code",
+ "type_code": "Type Code",
+ "type_description": "Type Description",
+ "gov_code": "Government Code",
+ "address_geographic_uu_id": "Address Geographic UUID",
+ }
+
+
+class InsertStreet(PydanticBaseModel, StreetValidation):
+ street_code: str
+ street_name: str
+ postcode: str
+
+ type_code: Optional[str] = None
+ type_description: Optional[str] = None
+ gov_code: Optional[str] = None
+ address_geographic_uu_id: Optional[str] = None
+
+
+class AddressValidation:
+ tr = {
+ "post_code_uu_id": "Posta Kodu UUID",
+ "comment_address": "Adres Yorumu",
+ "letter_address": "Mektup Adresi",
+ "build_number": "Bina Numarası",
+ "door_number": "Kapı Numarası",
+ "floor_number": "Kat Numarası",
+ "short_letter_address": "Kısa Mektup Adresi",
+ "latitude": "Enlem",
+ "longitude": "Boylam",
+ }
+ en = {
+ "post_code_uu_id": "Post Code UUID",
+ "comment_address": "Address Comment",
+ "letter_address": "Letter Address",
+ "build_number": "Build Number",
+ "door_number": "Door Number",
+ "floor_number": "Floor Number",
+ "short_letter_address": "Short Letter Address",
+ "latitude": "Latitude",
+ "longitude": "Longitude",
+ }
+
+
+class InsertAddress(BaseModelRegular, AddressValidation):
+ post_code_uu_id: str
+
+ comment_address: Optional[str] = None
+ letter_address: Optional[str] = None
+
+ build_number: str
+ door_number: Optional[str] = None
+ floor_number: Optional[str] = None
+
+ short_letter_address: Optional[str] = None
+ latitude: Optional[float] = None
+ longitude: Optional[float] = None
+
+
+class UpdateAddress(PydanticBaseModel, AddressValidation):
+ post_code_uu_id: Optional[str] = None
+
+ comment_address: Optional[str] = None
+ letter_address: Optional[str] = None
+
+ build_number: Optional[str] = None
+ door_number: Optional[str] = None
+ floor_number: Optional[str] = None
+
+ short_letter_address: Optional[str] = None
+ latitude: Optional[float] = None
+ longitude: Optional[float] = None
diff --git a/api_validations/validations_request/application.py b/api_validations/validations_request/application.py
new file mode 100644
index 0000000..f9fa22b
--- /dev/null
+++ b/api_validations/validations_request/application.py
@@ -0,0 +1,69 @@
+from api_validations.core_validations import BaseModelRegular
+
+
+class SingleEnumClassKeyValidation:
+ tr = {
+ "class_name": "Sınıf Adı",
+ "key_name": "Anahtar Adı",
+ }
+ en = {
+ "class_name": "Class Name",
+ "key_name": "Key Name",
+ }
+
+
+class SingleEnumClassKey(BaseModelRegular):
+ class_name: str
+ key_name: str
+
+
+class SingleEnumUUIDValidation:
+ tr = {
+ "uu_id": "UUID",
+ }
+ en = {
+ "uu_id": "UUID",
+ }
+
+
+class SingleEnumUUID(BaseModelRegular):
+ uu_id: str
+
+
+class SingleEnumOnlyClassValidation:
+ tr = {
+ "class_name": "Sınıf Adı",
+ }
+ en = {
+ "class_name": "Class Name",
+ }
+
+
+class SingleEnumOnlyClass(BaseModelRegular):
+ class_name: str
+
+
+class SingleOccupantTypeClassKeyValidation:
+ tr = {
+ "type_code": "Tip Kodu",
+ }
+ en = {
+ "type_code": "Type Code",
+ }
+
+
+class SingleOccupantTypeClassKey(BaseModelRegular):
+ type_code: str
+
+
+class SingleOccupantTypeUUIDValidation:
+ tr = {
+ "uu_id": "Görev UUID",
+ }
+ en = {
+ "uu_id": "Occupant UUID",
+ }
+
+
+class SingleOccupantTypeUUID(BaseModelRegular):
+ uu_id: str
diff --git a/api_validations/validations_request/area.py b/api_validations/validations_request/area.py
new file mode 100644
index 0000000..cfdf675
--- /dev/null
+++ b/api_validations/validations_request/area.py
@@ -0,0 +1,76 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+)
+
+
+class BuildAreaValidation:
+
+ tr = {
+ "area_name": "Alan Adı",
+ "area_code": "Alan Kodu",
+ "area_type": "Alan Tipi",
+ "area_direction": "Alan Yönü",
+ "area_gross_size": "Brüt Alan",
+ "area_net_size": "Net Alan",
+ "width": "Genişlik",
+ "size": "En",
+ }
+ en = {
+ "area_name": "Area Name",
+ "area_code": "Area Code",
+ "area_type": "Area Type",
+ "area_direction": "Area Direction",
+ "area_gross_size": "Gross Size",
+ "area_net_size": "Net Size",
+ "width": "Width",
+ "size": "Size",
+ }
+
+
+class InsertBuildArea(BaseModelRegular, BuildAreaValidation):
+
+ build_uu_id: str
+ area_name: str
+ area_code: str
+ area_type: str
+ area_direction: Optional[str] = None
+ area_gross_size: Optional[float] = None
+ area_net_size: Optional[float] = None
+ width: Optional[int] = None
+ size: Optional[int] = None
+
+
+class UpdateBuildArea(PydanticBaseModel, BuildAreaValidation):
+
+ area_name: Optional[str] = None
+ area_code: Optional[str] = None
+ area_type: Optional[str] = None
+ area_direction: Optional[str] = None
+ area_gross_size: Optional[float] = None
+ area_net_size: Optional[float] = None
+ width: Optional[int] = None
+ size: Optional[int] = None
+
+
+class BuildSites:
+ tr = {"address_uu_id": "Adres UU ID", "site_name": "Site Adı", "site_no": "Site No"}
+ en = {
+ "address_uu_id": "Address UU ID",
+ "site_name": "Site Name",
+ "site_no": "Site No",
+ }
+
+
+class InsertBuildSites(BaseModelRegular, BuildSites):
+
+ address_uu_id: str
+ site_name: str
+ site_no: str
+
+
+class UpdateBuildSites(PydanticBaseModel, BuildSites):
+
+ site_name: Optional[str] = None
+ site_no: Optional[str] = None
diff --git a/api_validations/validations_request/authentication.py b/api_validations/validations_request/authentication.py
new file mode 100644
index 0000000..d1205ce
--- /dev/null
+++ b/api_validations/validations_request/authentication.py
@@ -0,0 +1,104 @@
+from api_validations.core_validations import BaseModelRegular
+from typing import Optional
+from pydantic import BaseModel
+
+
+class ChangePasswordValidation:
+ tr = {"old_password": "Eski Şifre", "new_password": "Yeni Şifre"}
+ en = {"old_password": "Old Password", "new_password": "New Password"}
+
+
+class ChangePassword(BaseModelRegular, ChangePasswordValidation):
+ old_password: str
+ new_password: str
+
+
+class CreatePasswordValidation:
+ tr = {
+ "password_token": "Şifre Token",
+ "password": "Şifre",
+ "re_password": "Şifre Tekrar",
+ }
+ en = {
+ "password_token": "Password Token",
+ "password": "Password",
+ "re_password": "Re-Password",
+ }
+
+
+class CreatePassword(BaseModelRegular, CreatePasswordValidation):
+ password_token: str
+ password: str
+ re_password: str
+
+
+class OccupantSelectionValidation:
+
+ tr = {"occupant_uu_id": "Kiracı UU ID", "build_part_uu_id": "Bölüm UU ID"}
+ en = {"occupant_uu_id": "Occupant UU ID", "build_part_uu_id": "Build Part UU ID"}
+
+
+class OccupantSelection(BaseModel, OccupantSelectionValidation):
+ occupant_uu_id: str
+ build_part_uu_id: str
+
+
+class EmployeeSelectionValidation:
+
+ tr = {"company_uu_id": "Şirket UU ID"}
+ en = {"company_uu_id": "Company UU ID"}
+
+
+class EmployeeSelection(BaseModel, EmployeeSelectionValidation):
+ company_uu_id: str
+
+
+class LoginValidation:
+ tr = {
+ "domain": "Domain",
+ "access_key": "Erişim Anahtarı",
+ "password": "Şifre",
+ "remember_me": "Beni Hatırla",
+ }
+ en = {
+ "domain": "Domain",
+ "access_key": "Access Key",
+ "password": "Password",
+ "remember_me": "Remember Me",
+ }
+
+
+class Login(BaseModelRegular, LoginValidation):
+ domain: str
+ access_key: str
+ password: str
+ remember_me: Optional[bool] = False
+
+
+class LogoutValidation:
+ tr = {"domain": "Domain"}
+ en = {"domain": "Domain"}
+
+
+class Logout(BaseModelRegular, LogoutValidation):
+ domain: str
+
+
+class RememberValidation:
+ tr = {"domain": "Domain", "refresh_token": "Yenileme Anahtarı"}
+ en = {"domain": "Domain", "refresh_token": "Refresh Token"}
+
+
+class Remember(BaseModelRegular, RememberValidation):
+ domain: str
+ refresh_token: str
+
+
+class ForgotValidation:
+ tr = {"domain": "Domain", "access_key": "Erişim Anahtarı"}
+ en = {"domain": "Domain", "access_key": "Access Key"}
+
+
+class Forgot(BaseModelRegular, ForgotValidation):
+ domain: str
+ access_key: str
diff --git a/api_validations/validations_request/build_living_space.py b/api_validations/validations_request/build_living_space.py
new file mode 100644
index 0000000..abb1ae7
--- /dev/null
+++ b/api_validations/validations_request/build_living_space.py
@@ -0,0 +1,52 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+)
+
+
+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):
+ person_uu_id: str
+ build_parts_uu_id: str
+ occupant_type_uu_id: str
+ expiry_starts: str
+ expiry_ends: Optional[str] = None
+
+
+class UpdateBuildLivingSpace(PydanticBaseModel, BuildLivingSpaceValidation):
+ is_tenant_live: Optional[bool] = None
+ build_parts_uu_id: Optional[str] = None
+ person_uu_id: Optional[str] = None
diff --git a/api_validations/validations_request/build_part.py b/api_validations/validations_request/build_part.py
new file mode 100644
index 0000000..0386a3b
--- /dev/null
+++ b/api_validations/validations_request/build_part.py
@@ -0,0 +1,139 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+)
+
+
+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):
+ function_code: str
+ type_code: str
+ lang: str
+ type_name: str
+
+
+class UpdateBuildTypes(PydanticBaseModel, BuildTypesUpdateValidation): ...
+
+
+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):
+ build_uu_id: str
+ address_gov_code: str
+ part_no: int
+ part_level: int
+ build_part_type_uu_id: str
+
+ part_gross_size: Optional[int] = None
+ part_net_size: Optional[int] = None
+ default_accessory: Optional[str] = None
+ human_livable: Optional[bool] = False
+ part_direction_uu_id: Optional[str] = None
+ 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):
+ address_gov_code: Optional[str] = None
+ part_no: Optional[int] = None
+ part_level: Optional[int] = None
+ build_part_type_uu_id: Optional[str] = None
+
+ part_code: Optional[int] = None
+ part_gross_size: Optional[int] = None
+ part_net_size: Optional[int] = None
+ default_accessory: Optional[str] = None
+ human_livable: Optional[bool] = False
+ part_direction: Optional[str] = None
+ current_owner_person_uu_id: Optional[str] = None
+ current_tenant_person_uu_id: Optional[str] = None
diff --git a/api_validations/validations_request/building.py b/api_validations/validations_request/building.py
new file mode 100644
index 0000000..1efa2ac
--- /dev/null
+++ b/api_validations/validations_request/building.py
@@ -0,0 +1,102 @@
+from typing import Optional
+from datetime import datetime
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+ CrudRecordValidation,
+)
+
+
+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):
+
+ gov_address_code: str
+ build_name: str
+ build_types_uu_id: str
+ max_floor: int
+ underground_floor: int
+ address_uu_id: str
+ build_date: datetime
+ decision_period_date: datetime
+
+ tax_no: Optional[str] = None
+ lift_count: Optional[int] = None
+ heating_system: Optional[bool] = None
+ cooling_system: Optional[bool] = None
+ hot_water_system: Optional[bool] = None
+ block_service_man_count: Optional[int] = None
+ security_service_man_count: Optional[int] = None
+ garage_count: Optional[int] = None
+
+
+class BuildUpdateValidation:
+ tr = {
+ **BuildValidation.tr,
+ **PydanticBaseModelValidation.tr,
+ }
+ en = {
+ **BuildValidation.en,
+ **PydanticBaseModelValidation.en,
+ }
+
+
+class UpdateBuild(PydanticBaseModel, BuildUpdateValidation):
+ gov_address_code: Optional[str] = None
+ build_name: Optional[str] = None
+ build_no: Optional[str] = None
+ build_types_uu_id: Optional[str] = None
+ max_floor: Optional[int] = None
+ underground_floor: Optional[int] = None
+ build_date: Optional[datetime] = None
+ tax_no: Optional[str] = None
+ lift_count: Optional[int] = None
+ heating_system: Optional[bool] = None
+ cooling_system: Optional[bool] = None
+ hot_water_system: Optional[bool] = None
+ block_service_man_count: Optional[int] = None
+ security_service_man_count: Optional[int] = None
+ garage_count: Optional[int] = None
+ address_uu_id: Optional[str] = None
diff --git a/api_validations/validations_request/company.py b/api_validations/validations_request/company.py
new file mode 100644
index 0000000..22a3787
--- /dev/null
+++ b/api_validations/validations_request/company.py
@@ -0,0 +1,74 @@
+from typing import Optional, List
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+)
+
+
+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):
+ formal_name: str
+ company_type: str
+ commercial_type: str
+ tax_no: str
+ public_name: Optional[str] = None
+ company_tag: Optional[str] = None
+ default_lang_type: Optional[str] = None
+ default_money_type: Optional[str] = None
+ official_address_uu_id: Optional[str] = None
+ # parent_uu_id: Optional[int] = None
+
+
+class CompanyUpdateValidation:
+ tr = {
+ **CompanyValidation.tr,
+ **PydanticBaseModelValidation.tr,
+ }
+ en = {
+ **CompanyValidation.tr,
+ **PydanticBaseModelValidation.en,
+ }
+
+
+class UpdateCompany(PydanticBaseModel, CompanyUpdateValidation):
+ company_uu_id: str
+ public_name: Optional[str] = None
+ formal_name: Optional[str] = None
+ tax_no: Optional[str] = None
+ company_tag: Optional[str] = None
+ default_lang_type: Optional[str] = None
+ default_money_type: Optional[str] = None
+ 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):
+ match_company_uu_id: List[str]
+ duty_uu_id: str
+ show_only: Optional[bool] = None
diff --git a/api_validations/validations_request/core_request_validations.py b/api_validations/validations_request/core_request_validations.py
new file mode 100644
index 0000000..37081a4
--- /dev/null
+++ b/api_validations/validations_request/core_request_validations.py
@@ -0,0 +1,116 @@
+from typing import Optional
+
+from api_validations.core_validations import BaseModelRegular
+
+
+class ListOptionsValidation:
+ tr = {
+ "page": "Sayfa",
+ "size": "Boyut",
+ "order_field": "Sıralama Alanı",
+ "order_type": "Sıralama Türü",
+ "include_joins": "Alt İçerikleri",
+ "query": "Sorgu",
+ }
+ en = {
+ "page": "Page",
+ "size": "Size",
+ "order_field": "Order Field",
+ "order_type": "Order Type",
+ "include_joins": "Include Joins",
+ "query": "Query",
+ }
+
+
+class ListOptions(BaseModelRegular, ListOptionsValidation):
+ page: Optional[int] = 1
+ size: Optional[int] = 10
+ order_field: Optional[str] = "id"
+ order_type: Optional[str] = "asc"
+ include_joins: Optional[list] = None
+ query: Optional[dict] = None
+
+
+class CrudRecordValidation:
+ tr = {
+ "uu_id": "UUID",
+ "created_at": "Oluşturulma Tarihi",
+ "updated_at": "Güncellenme Tarihi",
+ "created_by": "Oluşturan",
+ "updated_by": "Güncelleyen",
+ "confirmed_by": "Onaylayan",
+ "is_confirmed": "Onay",
+ "expiry_starts": "Geçerlilik Başlangıç Tarihi",
+ "expiry_ends": "Geçerlilik Bitiş Tarihi",
+ "active": "Aktif",
+ "is_notification_send": "Bildirim Gönderildi",
+ "is_email_send": "E-posta Gönderildi",
+ }
+ en = {
+ "uu_id": "UUID",
+ "created_at": "Created At",
+ "updated_at": "Updated At",
+ "created_by": "Created By",
+ "updated_by": "Updated By",
+ "confirmed_by": "Confirmed By",
+ "is_confirmed": "Confirmed",
+ "expiry_starts": "Expiry Starts",
+ "expiry_ends": "Expiry Ends",
+ "active": "Active",
+ "is_notification_send": "Notification Send",
+ "is_email_send": "Email Send",
+ }
+
+
+class CrudRecords:
+ uu_id: Optional[str] = None
+ created_at: Optional[str] = None
+ updated_at: Optional[str] = None
+ created_by: Optional[str] = None
+ updated_by: Optional[str] = None
+ confirmed_by: Optional[str] = None
+ is_confirmed: Optional[bool] = None
+ active: Optional[bool] = None
+ is_notification_send: Optional[bool] = None
+ is_email_send: Optional[bool] = None
+
+
+class PydanticBaseModelValidation:
+ tr = {
+ "active": "Aktif",
+ "deleted": "Silinmiş",
+ "expiry_starts": "Geçerlilik Başlangıç Tarihi",
+ "expiry_ends": "Geçerlilik Bitiş Tarihi",
+ "is_confirmed": "Onay",
+ }
+ en = {
+ "active": "Active",
+ "deleted": "Deleted",
+ "expiry_starts": "Expiry Starts",
+ "expiry_ends": "Expiry Ends",
+ "is_confirmed": "Confirmed",
+ }
+
+
+class PydanticBaseModel(BaseModelRegular):
+
+ active: Optional[bool] = None
+ deleted: Optional[bool] = None
+ expiry_starts: Optional[str] = None
+ # expiry_ends: Optional[str] = None
+ is_confirmed: Optional[bool] = None
+
+
+class EndpointPydantic(BaseModelRegular):
+ data: Optional[dict] = None
+
+
+class EndpointValidation(BaseModelRegular):
+ endpoint: Optional[str] = None
+
+
+class PatchRecord(BaseModelRegular):
+
+ confirm: Optional[bool] = None
+ delete: Optional[bool] = None
+ active: Optional[bool] = None
diff --git a/api_validations/validations_request/create_model.py b/api_validations/validations_request/create_model.py
new file mode 100644
index 0000000..b16da10
--- /dev/null
+++ b/api_validations/validations_request/create_model.py
@@ -0,0 +1,73 @@
+import typing
+
+from datetime import datetime
+
+
+class ConvertField:
+
+ def __init__(self, match, default_val=None):
+ self.match = match
+ self.default_val = default_val
+
+ def typing_return(self):
+ typing_dict = {
+ "": float,
+ "": bool,
+ "": int,
+ "": str,
+ "": dict,
+ "": list,
+ "": datetime,
+ "typing.Optional[datetime.datetime]": typing.Optional[datetime],
+ "typing.Optional[bool]": typing.Optional[bool],
+ "typing.Optional[list]": typing.Optional[list],
+ "typing.Optional[str]": typing.Optional[str],
+ "typing.Optional[int]": typing.Optional[int],
+ "typing.Optional[float]": typing.Optional[float],
+ "typing.Optional[dict]": typing.Optional[dict],
+ }
+ matches_with = typing_dict.get(self.match, typing.Optional[str])
+ default_value = getattr(self.default_val, "field_default_value", None)
+ return matches_with, default_value
+
+
+#
+# def create_model_from_database(model_id: typing.Union[int, str]):
+# if isinstance(model_id, int):
+# selected_model = Models.find_one(id=model_id)
+# else:
+# selected_model = Models.find_one(uu_id=str(model_id))
+#
+# if not selected_model:
+# raise HTTPException(
+# status_code=202,
+# detail=f"Model {selected_model.model_name} not found in database. Please add model to api.",
+# )
+# pydantic_class = getattr(root_validates, selected_model.model_type, None)
+# if not pydantic_class:
+# raise HTTPException(
+# status_code=202,
+# detail=f"Pydantic class {selected_model.model_type} not found in database. Please add model to api.",
+# )
+#
+# model_entities_records = ModelEntities.filter_all(
+# ModelEntities.model_id == selected_model.id
+# ).data
+#
+# if not model_entities_records:
+# raise HTTPException(
+# status_code=202,
+# detail="Model has no entities registered. Please add entities to model.",
+# )
+#
+# fields = {}
+# for entity in model_entities_records:
+# fields[entity.field_name] = ConvertField(
+# entity.field_type, entity.field_default_value
+# ).typing_return()
+#
+# return create_model(
+# __model_name=selected_model.model_name, # pydantic_name(User)
+# __module__=pydantic_class.__module__, # field_name(uu_id)
+# **fields, # field_name = (field_type (Optional[str]), default_value(None))
+# )
diff --git a/api_validations/validations_request/decision_book.py b/api_validations/validations_request/decision_book.py
new file mode 100644
index 0000000..1c1f8f4
--- /dev/null
+++ b/api_validations/validations_request/decision_book.py
@@ -0,0 +1,356 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+ 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
+):
+ 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
+):
+ 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
+):
+ 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
+):
+ 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):
+ 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):
+ build_uu_id: str
+ decision_type: str
+ meeting_date: str
+ is_out_sourced: bool
+
+ resp_company_fix_wage: Optional[float] = None
+ 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
+):
+ 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):
+ person_uu_id: str
+ build_decision_book_uu_id: str
+ management_typecode_uu_id: str
+
+ dues_discount_approval_date: Optional[str] = None
+ dues_fix_discount: Optional[float] = None
+ 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):
+
+ 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):
+ 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):
+ decision_book_pdf_path: Optional[str] = None
+ is_out_sourced: Optional[bool] = None
+ contact_agreement_path: Optional[str] = None
+ contact_agreement_date: Optional[str] = None
+ meeting_date: Optional[str] = None
+ decision_type: Optional[str] = None
+
+ resp_company_fix_wage: Optional[float] = None
+ 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
+):
+ token: str
+ info_type_uu_id: str
+ item_comment: str
+
+ currency: Optional[str] = "TL"
+ unit_type: Optional[str] = "M2"
+ debit_start_date: Optional[str] = None
+ debit_end_date: Optional[str] = None
+ unit_price_is_fixed: Optional[bool] = False
+ unit_price: Optional[float] = 0.00
+
+ # build_decision_book_uu_id: str
+ # 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
+):
+ 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
+):
+ 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
+):
+ dues_types_uu_id: Optional[str] = None
+ dues_values: Optional[dict] = None
+ decision_taken: Optional[bool] = None
diff --git a/api_validations/validations_request/departments.py b/api_validations/validations_request/departments.py
new file mode 100644
index 0000000..03c61e1
--- /dev/null
+++ b/api_validations/validations_request/departments.py
@@ -0,0 +1,40 @@
+from typing import Optional
+from api_validations.validations_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):
+
+ department_code: Optional[str]
+ department_name: Optional[str]
+ department_description: Optional[str] = None
+ company_uu_id: Optional[str] = None
+ parent_department_uu_id: Optional[int] = None
+
+
+# class UpdateDepartments(PydanticBaseModel):
+#
+# department_code: Optional[str] = None
+# department_name: Optional[str] = None
+# department_description: Optional[str] = None
+# company_uu_id: Optional[str] = None
+# parent_department_uu_id: Optional[int] = None
diff --git a/api_validations/validations_request/employee.py b/api_validations/validations_request/employee.py
new file mode 100644
index 0000000..163928a
--- /dev/null
+++ b/api_validations/validations_request/employee.py
@@ -0,0 +1,251 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+)
+
+
+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):
+ 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):
+ 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):
+ 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):
+ 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):
+ 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):
+ 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
+ start_date: str
+ stop_date: Optional[str] = None
+ 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
+ start_date: Optional[str] = None
+ stop_date: Optional[str] = None
+ people_id: Optional[int] = None
+
+
+class InsertCompanyEmployeesValidation:
+ tr = {
+ "employee_description": "Çalışan Açıklaması",
+ "person_uu_id": "Kişi UUID",
+ "duty_uu_id": "Görev UUID",
+ "start_date": "Başlangıç Tarihi",
+ "stop_date": "Bitiş Tarihi",
+ }
+ en = {
+ "employee_description": "Employee Description",
+ "person_uu_id": "Person UUID",
+ "duty_uu_id": "Duty UUID",
+ "start_date": "Start Date",
+ "stop_date": "Stop Date",
+ }
+
+
+class InsertCompanyEmployees(BaseModelRegular, InsertCompanyEmployeesValidation):
+
+ employee_description: Optional[str] = None
+ person_uu_id: str
+ duty_uu_id: str
+
+ start_date: Optional[str] = None
+ stop_date: Optional[str] = None
+
+
+class UpdateCompanyEmployeesValidation:
+ tr = {
+ **PydanticBaseModelValidation.tr,
+ "stop_date": "Bitiş Tarihi",
+ "employee_description": "Çalışan Açıklaması",
+ }
+ en = {
+ **PydanticBaseModelValidation.en,
+ "stop_date": "Stop Date",
+ "employee_description": "Employee Description",
+ }
+
+
+class UpdateCompanyEmployees(PydanticBaseModel, UpdateCompanyEmployeesValidation):
+ stop_date: Optional[str] = None
+ employee_description: Optional[str] = None
diff --git a/api_validations/validations_request/events.py b/api_validations/validations_request/events.py
new file mode 100644
index 0000000..0cfe276
--- /dev/null
+++ b/api_validations/validations_request/events.py
@@ -0,0 +1,37 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+
+
+class RegisterEvents2EmployeeValidation:
+ tr = {
+ "event_uu_id_list": "Etkinlikler Listesi",
+ "employee_uu_id": "Çalışan UU ID",
+ }
+ en = {
+ "event_uu_id_list": "Event List",
+ "employee_uu_id": "Employee UU ID",
+ }
+
+
+class RegisterEvents2Employee(BaseModelRegular, RegisterEvents2EmployeeValidation):
+ event_uu_id_list: list[str] = None
+ employee_uu_id: Optional[str] = None
+
+
+class RegisterEvents2OccupantValidation:
+ tr = {
+ "event_uu_id_list": "Etkinlikler Listesi",
+ "build_part_uu_id": "Bina Parça UU ID",
+ "occupant_uu_id": "Apartman Sakini UU ID",
+ }
+ en = {
+ "event_uu_id_list": "Event List",
+ "build_part_uu_id": "Building Part UU ID",
+ "occupant_uu_id": "Occupant UU ID",
+ }
+
+
+class RegisterEvents2Occupant(BaseModelRegular, RegisterEvents2OccupantValidation):
+ event_uu_id_list: list[str] = None
+ build_part_uu_id: Optional[str] = None
+ occupant_uu_id: Optional[str] = None
diff --git a/api_validations/validations_request/modules.py b/api_validations/validations_request/modules.py
new file mode 100644
index 0000000..42076d3
--- /dev/null
+++ b/api_validations/validations_request/modules.py
@@ -0,0 +1,36 @@
+from api_validations.core_validations import BaseModelRegular
+
+
+class RegisterModules2OccupantValidation:
+ tr = {
+ "modules_uu_id": "Modül Listesi",
+ "occupant_uu_id": "Mülk Sahibi",
+ "build_part_uu_id": "Daire UUID",
+ }
+ en = {
+ "modules_uu_id": "Module List",
+ "occupant_uu_id": "Occupant",
+ "build_part_uu_id": "Flat UUID",
+ }
+
+
+class RegisterModules2Occupant(BaseModelRegular, RegisterModules2OccupantValidation):
+ modules_uu_id: str
+ occupant_uu_id: str
+ build_part_uu_id: str
+
+
+class RegisterModules2EmployeeValidation:
+ tr = {
+ "modules_uu_id": "Modül Listesi",
+ "employee_uu_id": "Çalışan",
+ }
+ en = {
+ "modules_uu_id": "Module List",
+ "employee_uu_id": "Employee",
+ }
+
+
+class RegisterModules2Employee(BaseModelRegular, RegisterModules2EmployeeValidation):
+ modules_uu_id: str
+ employee_uu_id: str
diff --git a/api_validations/validations_request/people.py b/api_validations/validations_request/people.py
new file mode 100644
index 0000000..36182ec
--- /dev/null
+++ b/api_validations/validations_request/people.py
@@ -0,0 +1,98 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+)
+
+
+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):
+ firstname: str
+ surname: str
+ sex_code: str
+ national_identity_id: str
+ middle_name: Optional[str] = None
+ father_name: Optional[str] = None
+ mother_name: Optional[str] = None
+ country_code: Optional[str] = "TR"
+ birth_place: Optional[str] = None
+ birth_date: Optional[str] = None
+ tax_no: Optional[str] = None
+ ref_id: Optional[str] = None
+
+
+class UpdatePersonValidation:
+ tr = {
+ **PydanticBaseModelValidation.tr,
+ **InsertPersonValidation.tr,
+ }
+ en = {
+ **PydanticBaseModelValidation.en,
+ **InsertPersonValidation.tr,
+ }
+
+
+class UpdatePerson(PydanticBaseModel, UpdatePersonValidation):
+ firstname: Optional[str] = None
+ surname: Optional[str] = None
+ middle_name: Optional[str]
+ father_name: Optional[str] = None
+ mother_name: Optional[str] = None
+ sex_code: Optional[str] = None
+ country_code: Optional[str] = None
+ national_identity_id: Optional[str] = None
+ birth_place: Optional[str] = None
+ birth_date: Optional[str] = None
+ tax_no: Optional[str] = None
+
+
+#
+# class QueryPeople(PydanticBaseModel):
+# uu_id: Optional[str] = None
+#
+#
+# class InsertPeople(PydanticBaseModel):
+# key_id: Optional[str] = None
+# query: Optional[dict] = None
+# data: Optional[_InsertPerson] = None
+#
+#
+# class UpdatePeople(PydanticBaseModel):
+# key_id: Optional[str] = None
+# query: Optional[QueryPeople] = None
+# data: Optional[_UpdatePerson] = None
+#
+#
+# class DeletePeople(PydanticBaseModel):
+# key_id: Optional[str] = None
+# query: Optional[List[QueryPeople]] = None
+# data: Optional[dict] = None
+#
+#
+# class ListPeople(PydanticBaseModel):
+# key_id: Optional[str] = None
+# query: Optional[QueryPeople] = None
+# data: Optional[ListOptions] = None
+#
+#
+# class ActivePeople(PydanticBaseModel):
+# key_id: Optional[str] = None
+# query: Optional[List[QueryPeople]] = None
+# data: Optional[dict] = None
diff --git a/api_validations/validations_request/project_decision_book.py b/api_validations/validations_request/project_decision_book.py
new file mode 100644
index 0000000..71fc1e4
--- /dev/null
+++ b/api_validations/validations_request/project_decision_book.py
@@ -0,0 +1,276 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+ PydanticBaseModelValidation,
+)
+
+
+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
+):
+ build_decision_book_project_uu_id: str
+ item_header: str
+ item_comment: str
+ attachment_pdf_path: Optional[str] = None
+ 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
+ attachment_pdf_path: Optional[str] = None
+ item_estimated_cost: Optional[float] = None
+ 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
+):
+ dues_percent_discount: Optional[int] = None
+ job_fix_wage: Optional[float] = None
+ bid_price: Optional[float] = None
+ decision_price: Optional[float] = None
+ build_decision_book_project_uu_id: str
+ living_space_uu_id: str
+ project_team_type_uu_id: str
+
+
+class UpdateBuildDecisionBookProjectPersonValidation:
+ tr = {
+ **InsertBuildDecisionBookProjectPersonValidation.tr,
+ **PydanticBaseModelValidation.tr,
+ }
+ en = {
+ **InsertBuildDecisionBookProjectPersonValidation.en,
+ **PydanticBaseModelValidation.en,
+ }
+
+
+class UpdateBuildDecisionBookProjectPerson(
+ PydanticBaseModel, UpdateBuildDecisionBookProjectPersonValidation
+):
+ dues_percent_discount: Optional[int] = None
+ job_fix_wage: Optional[float] = None
+ bid_price: Optional[float] = None
+ decision_price: Optional[float] = None
+ build_decision_book_project_uu_id: Optional[str] = None
+ living_space_uu_id: Optional[str] = None
+ project_team_type_uu_id: Optional[str] = None
+
+
+class InsertBuildDecisionBookProjectsValidation:
+ tr = {
+ "build_decision_book_item_uu_id": "Karar Defteri UUID",
+ "project_responsible_person_uu_id": "Proje Sorumlu Kişi UUID",
+ "project_name": "Proje Adı",
+ "project_start_date": "Proje Başlangıç Tarihi",
+ "project_stop_date": "Proje Bitiş Tarihi",
+ "project_type": "Proje Tipi",
+ "is_out_sourced": "Dış Kaynak Kullanımı",
+ "project_note": "Proje Notu",
+ "decision_book_pdf_path": "Karar Defteri PDF Yolu",
+ "resp_company_fix_wage": "Firma Sabit Ücreti",
+ "contact_agreement_path": "İletişim Anlaşması Yolu",
+ "contact_agreement_date": "İletişim Anlaşması Tarihi",
+ "meeting_date": "Toplantı Tarihi",
+ "currency": "Para Birimi",
+ "bid_price": "Teklif Fiyatı",
+ "resp_company_uu_id": "Firma UUID",
+ }
+ en = {
+ "build_decision_book_item_uu_id": "Decision Book UUID",
+ "project_responsible_person_uu_id": "Project Responsible Person UUID",
+ "project_name": "Project Name",
+ "project_start_date": "Project Start Date",
+ "project_stop_date": "Project Stop Date",
+ "project_type": "Project Type",
+ "is_out_sourced": "Out Sourced",
+ "project_note": "Project Note",
+ "decision_book_pdf_path": "Decision Book PDF Path",
+ "resp_company_fix_wage": "Company Fixed Wage",
+ "contact_agreement_path": "Contact Agreement Path",
+ "contact_agreement_date": "Contact Agreement Date",
+ "meeting_date": "Meeting Date",
+ "currency": "Currency",
+ "bid_price": "Bid Price",
+ "resp_company_uu_id": "Company UUID",
+ }
+
+
+class InsertBuildDecisionBookProjects(
+ BaseModelRegular, InsertBuildDecisionBookProjectsValidation
+):
+ build_decision_book_item_uu_id: str
+ project_responsible_person_uu_id: str
+ project_name: str
+ project_start_date: str
+ project_stop_date: str
+ project_type: str
+
+ is_out_sourced: Optional[bool] = False
+ project_note: Optional[str] = None
+ decision_book_pdf_path: Optional[str] = None
+ resp_company_fix_wage: Optional[float] = None
+ contact_agreement_path: Optional[str] = None
+ contact_agreement_date: Optional[str] = None
+ meeting_date: Optional[str] = None
+ currency: Optional[str] = None
+ bid_price: Optional[float] = None
+ resp_company_uu_id: Optional[str] = None
+
+
+class UpdateBuildDecisionBookProjectsValidation:
+ tr = {
+ **InsertBuildDecisionBookProjectsValidation.tr,
+ **PydanticBaseModelValidation.tr,
+ }
+ en = {
+ **InsertBuildDecisionBookProjectsValidation.en,
+ **PydanticBaseModelValidation.en,
+ }
+
+
+class UpdateBuildDecisionBookProjects(
+ PydanticBaseModel, UpdateBuildDecisionBookProjectsValidation
+):
+ build_decision_book_project_uu_id: str
+ is_out_sourced: Optional[bool] = False
+ project_note: Optional[str] = None
+ # decision_book_pdf_path: Optional[str] = None
+ status_id: Optional[int] = None
+ resp_company_fix_wage: Optional[float] = None
+ contact_agreement_path: Optional[str] = None
+ contact_agreement_date: Optional[str] = None
+ contact_uu_id: Optional[str] = None
+ resp_company_uu_id: Optional[str] = None
+ approved_price: Optional[float] = None
+
+
+class ApprovalsBuildDecisionBookProjectsValidation:
+ tr = {
+ "build_decision_book_project_uu_id": "Karar Defteri Proje UUID",
+ "project_stop_date": "Proje Bitiş Tarihi",
+ "status_code": "Durum Kodu",
+ "final_price_list": "Son Fiyat Listesi",
+ }
+ en = {
+ "build_decision_book_project_uu_id": "Decision Book Project UUID",
+ "project_stop_date": "Project Stop Date",
+ "status_code": "Status Code",
+ "final_price_list": "Final Price List",
+ }
+
+
+class ApprovalsBuildDecisionBookProjects(
+ PydanticBaseModel, ApprovalsBuildDecisionBookProjectsValidation
+):
+ build_decision_book_project_uu_id: str
+ project_stop_date: str
+ status_code: Optional[int] = None
+ final_price_list: Optional[list[dict]] = (
+ None # {"date": "2021-01-01", "price": 1000}
+ )
+
+
+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
+):
+ build_decision_book_project_item_uu_id: str
+ payment_date: str
+ dues_values: dict
+ is_official: Optional[bool] = False
+ discount_value: Optional[float] = None
+ discount_fix: Optional[float] = None
+ decision_taken: Optional[bool] = None
+
+
+class UpdateBuildDecisionBookProjectItemDebitsValidation:
+ tr = {
+ **InsertBuildDecisionBookProjectItemDebitsValidation.tr,
+ **PydanticBaseModelValidation.tr,
+ }
+ en = {
+ **InsertBuildDecisionBookProjectItemDebitsValidation.en,
+ **PydanticBaseModelValidation.en,
+ }
+
+
+class UpdateBuildDecisionBookProjectItemDebits(
+ PydanticBaseModel, UpdateBuildDecisionBookProjectItemDebitsValidation
+):
+ dues_values: Optional[str] = None
+ discount_value: Optional[float] = None
+ discount_fix: Optional[float] = None
+ decision_taken: Optional[bool] = None
+ is_official: Optional[bool] = None
diff --git a/api_validations/validations_request/rules.py b/api_validations/validations_request/rules.py
new file mode 100644
index 0000000..8350baa
--- /dev/null
+++ b/api_validations/validations_request/rules.py
@@ -0,0 +1,24 @@
+from typing import Optional, List
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+)
+
+
+class CheckEndpointAccess(BaseModelRegular):
+ endpoint: str
+
+class InsertEndpointAccess(PydanticBaseModel):
+ duty_uu_id: str
+ endpoint_restriction_list_uu_ids: list
+
+
+class UpdateEndpointAccess(PydanticBaseModel):
+ endpoint_restriction_uu_id: Optional[str] = None
+ deleted: Optional[bool] = None
+ active: Optional[bool] = None
+ is_confirmed: Optional[bool] = None
+
+
+class UpdateEndpointAccessList(PydanticBaseModel):
+ endpoint_restriction_list: List[UpdateEndpointAccess]
diff --git a/api_validations/validations_request/services.py b/api_validations/validations_request/services.py
new file mode 100644
index 0000000..6ce55b4
--- /dev/null
+++ b/api_validations/validations_request/services.py
@@ -0,0 +1,36 @@
+from api_validations.core_validations import BaseModelRegular
+
+
+class RegisterServices2OccupantValidation:
+ tr = {
+ "service_uu_id": "Hizmet UUID",
+ "occupant_uu_id": "Müşteri UUID",
+ "build_part_uu_id": "Bina Parça UUID",
+ }
+ en = {
+ "service_uu_id": "Service UUID",
+ "occupant_uu_id": "Occupant UUID",
+ "build_part_uu_id": "Building Part UUID",
+ }
+
+
+class RegisterServices2Occupant(BaseModelRegular, RegisterServices2OccupantValidation):
+ service_uu_id: str
+ occupant_uu_id: str
+ build_part_uu_id: str
+
+
+class RegisterServices2EmployeeValidation:
+ tr = {
+ "service_uu_id": "Hizmet UUID",
+ "employee_uu_id": "Personel UUID",
+ }
+ en = {
+ "service_uu_id": "Service UUID",
+ "employee_uu_id": "Employee UUID",
+ }
+
+
+class RegisterServices2Employee(BaseModelRegular, RegisterServices2EmployeeValidation):
+ service_uu_id: str
+ employee_uu_id: str
diff --git a/api_validations/validations_request/staff.py b/api_validations/validations_request/staff.py
new file mode 100644
index 0000000..6222b2d
--- /dev/null
+++ b/api_validations/validations_request/staff.py
@@ -0,0 +1,42 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ PydanticBaseModel,
+)
+
+
+class InsertStaffValidation:
+ tr = {
+ "staff_name": "Kadro Adı",
+ "staff_description": "Kadro Açıklaması",
+ "staff_code": "Kadro Kodu",
+ "duties_uu_id": "Görev UUID",
+ }
+ en = {
+ "staff_name": "Staff Name",
+ "staff_description": "Staff Description",
+ "staff_code": "Staff Code",
+ "duties_uu_id": "Duties UUID",
+ }
+
+
+class InsertStaff(BaseModelRegular, InsertStaffValidation):
+
+ staff_name: str
+ staff_description: Optional[str] = None
+ staff_code: Optional[str] = None
+ duties_uu_id: str
+
+
+class SelectStaffValidation:
+ tr = {
+ "duties_uu_id": "Görev UUID",
+ }
+ en = {
+ "duties_uu_id": "Duties UUID",
+ }
+
+
+class SelectStaff(PydanticBaseModel, SelectStaffValidation):
+
+ duties_uu_id: str
diff --git a/api_validations/validations_request/user.py b/api_validations/validations_request/user.py
new file mode 100644
index 0000000..99f89c8
--- /dev/null
+++ b/api_validations/validations_request/user.py
@@ -0,0 +1,70 @@
+from typing import Optional
+from api_validations.validations_request import (
+ PydanticBaseModel,
+)
+
+
+class InsertUsersValidation:
+ tr = {
+ "people_uu_id": "Kişi UUID",
+ "user_tag": "Kullanıcı Etiketi",
+ "email": "E-posta",
+ "phone_number": "Telefon Numarası",
+ "avatar": "Avatar",
+ }
+ en = {
+ "people_uu_id": "People UUID",
+ "user_tag": "User Tag",
+ "email": "Email",
+ "phone_number": "Phone Number",
+ "avatar": "Avatar",
+ }
+
+
+class InsertUsers(PydanticBaseModel, InsertUsersValidation):
+ people_uu_id: str
+ user_tag: str
+ email: Optional[str] = None
+ phone_number: Optional[str] = None
+ avatar: Optional[str] = None
+
+
+class UpdateUsersValidation:
+ tr = {
+ "people_uu_id": "Kişi UUID",
+ "nick_name": "Kullanıcı Etiketi",
+ "domain_name": "Domain Adı",
+ "email": "E-posta",
+ "phone_number": "Telefon Numarası",
+ "avatar": "Avatar",
+ }
+ en = {
+ "people_uu_id": "People UUID",
+ "nick_name": "User Tag",
+ "domain_name": "Domain Name",
+ "email": "Email",
+ "phone_number": "Phone Number",
+ "avatar": "Avatar",
+ }
+
+
+class UpdateUsers(PydanticBaseModel, UpdateUsersValidation):
+ people_uu_id: Optional[str] = None
+ nick_name: Optional[str] = None
+ domain_name: Optional[str] = None
+ email: Optional[str] = None
+ phone_number: Optional[str] = None
+ avatar: Optional[str] = None
+
+
+class QueryUsersValidation:
+ tr = {
+ "uu_id": "UUID",
+ }
+ en = {
+ "uu_id": "UUID",
+ }
+
+
+class QueryUsers(PydanticBaseModel):
+ uu_id: Optional[str] = None
diff --git a/api_validations/validations_response/__init__.py b/api_validations/validations_response/__init__.py
new file mode 100644
index 0000000..8e139ff
--- /dev/null
+++ b/api_validations/validations_response/__init__.py
@@ -0,0 +1,5 @@
+from .building import ListBuildingResponse
+
+__all__ = [
+ "ListBuildingResponse",
+]
diff --git a/api_validations/validations_response/account.py b/api_validations/validations_response/account.py
new file mode 100644
index 0000000..4a560e6
--- /dev/null
+++ b/api_validations/validations_response/account.py
@@ -0,0 +1,136 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ CrudRecordValidation,
+ CrudRecords,
+)
+
+
+class AccountListValidation:
+ tr = {
+ **CrudRecordValidation.tr,
+ "iban": "IBAN Numarası",
+ "bank_date": "Banka İşlem Tarihi",
+ "currency_value": "Para Birimi Değeri",
+ "bank_balance": "Banka Bakiyesi",
+ "currency": "Para Birimi Birimi",
+ "additional_balance": "Ek Bakiye",
+ "channel_branch": "Şube Banka",
+ "process_name": "Banka İşlem Türü Adı",
+ "process_type": "Banka İşlem Türü",
+ "process_comment": "İşlem Kayıt Yorumu",
+ "process_garbage": "İşlem Kayıt Çöpü",
+ "bank_reference_code": "Banka Referans Kodu",
+ "add_comment_note": "Yorum Not Ekle",
+ "is_receipt_mail_send": "Makbuz Posta Gönderildi",
+ "found_from": "Bulunduğu Yer",
+ "similarity": "Benzerlik",
+ "remainder_balance": "Kalan Bakiye",
+ "bank_date_y": "Banka İşlem Yılı",
+ "bank_date_m": "Banka İşlem Ayı",
+ "bank_date_w": "Banka İşlem Haftası",
+ "bank_date_d": "Banka İşlem Günü",
+ "approving_accounting_record": "Onaylayan Muhasebe Kaydı",
+ "accounting_receipt_date": "Muhasebe Makbuz Tarihi",
+ "accounting_receipt_number": "Muhasebe Makbuz Numarası",
+ "approved_record": "Onaylanmış Kayıt",
+ "import_file_name": "İçe Aktarım Dosya Adı",
+ "receive_debit": "Alacak Borç",
+ "receive_debit_uu_id": "Alacak Borç UU Kimliği",
+ "budget_type": "Bütçe Türü",
+ "budget_type_uu_id": "Bütçe Türü UU Kimliği",
+ "company_uu_id": "Şirket UU Kimliği",
+ "send_company_uu_id": "Şirket UU Kimliği Gönder",
+ "send_person_uu_id": "Kişi UU Kimliği Gönder",
+ "approving_accounting_person_uu_id": "Onaylayan Muhasebe Kişi UU Kimliği",
+ "living_space_uu_id": "Yaşam Alanı UU Kimliği",
+ "customer_uu_id": "Müşteri UU Kimliği",
+ "build_uu_id": "Yapı UU Kimliği",
+ "build_parts_uu_id": "Yapı Parça UU Kimliği",
+ "build_decision_book_uu_id": "Yapı Karar Defteri UU Kimliği",
+ }
+ en = {
+ **CrudRecordValidation.en,
+ "iban": "IBAN Number",
+ "bank_date": "Bank Transaction Date",
+ "currency_value": "Currency Value",
+ "bank_balance": "Bank Balance",
+ "currency": "Unit of Currency",
+ "additional_balance": "Additional Balance",
+ "channel_branch": "Branch Bank",
+ "process_name": "Bank Process Type Name",
+ "process_type": "Bank Process Type",
+ "process_comment": "Transaction Record Comment",
+ "process_garbage": "Transaction Record Garbage",
+ "bank_reference_code": "Bank Reference Code",
+ "add_comment_note": "Add Comment Note",
+ "is_receipt_mail_send": "Receipt Mail Send",
+ "found_from": "Found From",
+ "similarity": "Similarity",
+ "remainder_balance": "Remainder Balance",
+ "bank_date_y": "Bank Date Year",
+ "bank_date_m": "Bank Date Month",
+ "bank_date_w": "Bank Date Week",
+ "bank_date_d": "Bank Date Day",
+ "approving_accounting_record": "Approving Accounting Record",
+ "accounting_receipt_date": "Accounting Receipt Date",
+ "accounting_receipt_number": "Accounting Receipt Number",
+ "approved_record": "Approved Record",
+ "import_file_name": "Import File Name",
+ "receive_debit": "Receive Debit",
+ "receive_debit_uu_id": "Receive Debit UU ID",
+ "budget_type": "Budget Type",
+ "budget_type_uu_id": "Budget Type UU ID",
+ "company_uu_id": "Company UU ID",
+ "send_company_uu_id": "Send Company UU ID",
+ "send_person_uu_id": "Send Person UU ID",
+ "approving_accounting_person_uu_id": "Approving Accounting Person UU ID",
+ "living_space_uu_id": "Living Space UU ID",
+ "customer_uu_id": "Customer UU ID",
+ "build_uu_id": "Build UU ID",
+ "build_parts_uu_id": "Build Parts UU ID",
+ "build_decision_book_uu_id": "Build Decision Book UU ID",
+ }
+
+
+class AccountListResponse(BaseModelRegular, CrudRecords, AccountListValidation):
+
+ iban: Optional[str] = None
+ bank_date: Optional[str] = None
+ currency_value: Optional[str] = None
+ bank_balance: Optional[str] = None
+ currency: Optional[str] = None
+ additional_balance: Optional[str] = None
+ channel_branch: Optional[str] = None
+ process_name: Optional[str] = None
+ process_type: Optional[str] = None
+ process_comment: Optional[str] = None
+ process_garbage: Optional[str] = None
+ bank_reference_code: Optional[str] = None
+ add_comment_note: Optional[str] = None
+ is_receipt_mail_send: Optional[str] = None
+ found_from: Optional[str] = None
+ similarity: Optional[str] = None
+ remainder_balance: Optional[str] = None
+ bank_date_y: Optional[str] = None
+ bank_date_m: Optional[str] = None
+ bank_date_w: Optional[str] = None
+ bank_date_d: Optional[str] = None
+ approving_accounting_record: Optional[str] = None
+ accounting_receipt_date: Optional[str] = None
+ accounting_receipt_number: Optional[str] = None
+ approved_record: Optional[str] = None
+ import_file_name: Optional[str] = None
+ receive_debit: Optional[str] = None
+ receive_debit_uu_id: Optional[str] = None
+ budget_type: Optional[str] = None
+ budget_type_uu_id: Optional[str] = None
+ company_uu_id: Optional[str] = None
+ send_company_uu_id: Optional[str] = None
+ send_person_uu_id: Optional[str] = None
+ approving_accounting_person_uu_id: Optional[str] = None
+ living_space_uu_id: Optional[str] = None
+ customer_uu_id: Optional[str] = None
+ build_uu_id: Optional[str] = None
+ build_parts_uu_id: Optional[str] = None
+ build_decision_book_uu_id: Optional[str] = None
diff --git a/api_validations/validations_response/address.py b/api_validations/validations_response/address.py
new file mode 100644
index 0000000..19377f4
--- /dev/null
+++ b/api_validations/validations_response/address.py
@@ -0,0 +1,23 @@
+from typing import Optional
+
+
+class ListAddressResponse:
+ pass
+
+
+"""
+ street_id: Mapped[int] = mapped_column(ForeignKey("address_street.id"))
+ street_uu_id: Mapped[str] = mapped_column(
+ String, server_default="", comment="Street UUID"
+ )
+ postcode: Mapped[str] = mapped_column(
+ String(32), nullable=False, comment="Postcode"
+ )
+
+"""
+
+
+class AddressPostCodeResponse:
+ street_id: Optional[int] = None
+ street_uu_id: Optional[str] = None
+ postcode: Optional[str] = None
diff --git a/api_validations/validations_response/building.py b/api_validations/validations_response/building.py
new file mode 100644
index 0000000..391b5bf
--- /dev/null
+++ b/api_validations/validations_response/building.py
@@ -0,0 +1,123 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ CrudRecordValidation,
+ CrudRecords,
+)
+
+
+class BuildListValidation:
+ 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ı",
+ "site_uu_id": "Site UUID",
+ }
+ 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",
+ "site_uu_id": "Site UUID",
+ }
+
+
+class ListBuildingResponse(BaseModelRegular, CrudRecords, BuildListValidation):
+
+ gov_address_code: Optional[str] = None
+ build_name: Optional[str] = None
+ build_types_uu_id: Optional[str] = None
+ build_no: Optional[str] = None
+ max_floor: Optional[int] = None
+ underground_floor: Optional[int] = None
+ address_uu_id: Optional[str] = None
+ build_date: Optional[str] = None
+ decision_period_date: Optional[str] = None
+ tax_no: Optional[str] = None
+ lift_count: Optional[int] = None
+ heating_system: Optional[bool] = None
+ cooling_system: Optional[bool] = None
+ hot_water_system: Optional[bool] = None
+ block_service_man_count: Optional[int] = None
+ security_service_man_count: Optional[int] = None
+ garage_count: Optional[int] = None
+ site_uu_id: Optional[str] = None
+
+
+# class InsertBuild(BaseModelRegular, BuildValidation):
+# gov_address_code: str
+# build_name: str
+# build_types_uu_id: str
+# max_floor: int
+# underground_floor: int
+# address_uu_id: str
+# build_date: str
+# decision_period_date: str
+#
+# tax_no: Optional[str] = None
+# lift_count: Optional[int] = None
+# heating_system: Optional[bool] = None
+# cooling_system: Optional[bool] = None
+# hot_water_system: Optional[bool] = None
+# block_service_man_count: Optional[int] = None
+# security_service_man_count: Optional[int] = None
+# garage_count: Optional[int] = None
+#
+#
+# class BuildUpdateValidation:
+# tr = {
+# **BuildValidation.tr,
+# **PydanticBaseModelValidation.tr,
+# }
+# en = {
+# **BuildValidation.en,
+# **PydanticBaseModelValidation.en,
+# }
+#
+#
+# class UpdateBuild(PydanticBaseModel, BuildUpdateValidation):
+# gov_address_code: Optional[str] = None
+# build_name: Optional[str] = None
+# build_no: Optional[str] = None
+# build_types: Optional[str] = None
+# max_floor: Optional[int] = None
+# underground_floor: Optional[int] = None
+# build_date: Optional[str] = None
+# tax_no: Optional[str] = None
+# lift_count: Optional[int] = None
+# heating_system: Optional[bool] = None
+# cooling_system: Optional[bool] = None
+# hot_water_system: Optional[bool] = None
+# block_service_man_count: Optional[int] = None
+# security_service_man_count: Optional[int] = None
+# garage_count: Optional[int] = None
+# address_uu_id: Optional[str] = None
diff --git a/api_validations/validations_response/living_space.py b/api_validations/validations_response/living_space.py
new file mode 100644
index 0000000..4b4c902
--- /dev/null
+++ b/api_validations/validations_response/living_space.py
@@ -0,0 +1,52 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ CrudRecordValidation,
+ CrudRecords,
+)
+
+
+class LivingSpaceListValidation:
+ tr = {
+ **CrudRecordValidation.tr,
+ "fix_value": "Sabit Değer",
+ "fix_percent": "Sabit Yüzde",
+ "agreement_no": "Anlaşma No",
+ "marketing_process": "Pazarlama Süreci",
+ "marketing_layer": "Pazarlama Katmanı",
+ "build_parts_id": "Bölüm ID",
+ "build_parts_uu_id": "Bölüm UUID",
+ "person_id": "Sorumlu Kişi ID",
+ "person_uu_id": "Sorumlu Kişi UUID",
+ "occupant_type": "Kiracı Tipi",
+ "occupant_type_uu_id": "Kiracı Tipi UUID",
+ }
+ en = {
+ **CrudRecordValidation.en,
+ "fix_value": "Fixed Value",
+ "fix_percent": "Fixed Percent",
+ "agreement_no": "Agreement No",
+ "marketing_process": "Marketing Process",
+ "marketing_layer": "Marketing Layer",
+ "build_parts_id": "Part ID",
+ "build_parts_uu_id": "Part UUID",
+ "person_id": "Responsible Person ID",
+ "person_uu_id": "Responsible Person UUID",
+ "occupant_type": "Occupant Type",
+ "occupant_type_uu_id": "Occupant Type UUID",
+ }
+
+
+class LivingSpaceListResponse(BaseModelRegular, CrudRecords, LivingSpaceListValidation):
+
+ fix_value: Optional[float] = None
+ fix_percent: Optional[float] = None
+ agreement_no: Optional[str] = None
+ marketing_process: Optional[str] = None
+ marketing_layer: Optional[str] = None
+ build_parts_id: Optional[int] = None
+ build_parts_uu_id: Optional[str] = None
+ person_id: Optional[int] = None
+ person_uu_id: Optional[str] = None
+ occupant_type: Optional[str] = None
+ occupant_type_uu_id: Optional[str] = None
diff --git a/api_validations/validations_response/parts.py b/api_validations/validations_response/parts.py
new file mode 100644
index 0000000..bf518ea
--- /dev/null
+++ b/api_validations/validations_response/parts.py
@@ -0,0 +1,54 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ CrudRecordValidation,
+ CrudRecords,
+)
+
+
+class BuildPartsListValidation:
+ tr = {
+ **CrudRecordValidation.tr,
+ "address_gov_code": "Adres Kapı Kodu",
+ "part_no": "Bölüm No",
+ "part_level": "Bölüm Seviyesi",
+ "part_code": "Bölüm Kodu",
+ "part_gross": "Bölüm Brüt",
+ "part_net": "Bölüm Net",
+ "default_accessory": "Varsayılan Aksesuar",
+ "human_livable": "İnsan Yaşamı",
+ "due_part_key": "Sabit Ödeme Grubu",
+ "build_uu_id": "Bina UUID",
+ "part_direction_uu_id": "Bölüm Yönü UUID",
+ "part_type_uu_id": "Bölüm Tipi UUID",
+ }
+ en = {
+ **CrudRecordValidation.en,
+ "address_gov_code": "Address Government Code",
+ "part_no": "Part Number",
+ "part_level": "Part Level",
+ "part_code": "Part Code",
+ "part_gross": "Part Gross",
+ "part_net": "Part Net",
+ "default_accessory": "Default Accessory",
+ "human_livable": "Human Livable",
+ "due_part_key": "Constant Payment Group",
+ "build_uu_id": "Building UUID",
+ "part_direction_uu_id": "Part Direction UUID",
+ "part_type_uu_id": "Part Type UUID",
+ }
+
+
+class BuildPartsListResponse(BaseModelRegular, CrudRecords, BuildPartsListValidation):
+ address_gov_code: Optional[str] = None
+ part_no: Optional[int] = None
+ part_level: Optional[int] = None
+ part_code: Optional[str] = None
+ part_gross: Optional[int] = None
+ part_net: Optional[int] = None
+ default_accessory: Optional[str] = None
+ human_livable: Optional[bool] = None
+ due_part_key: Optional[str] = None
+ build_uu_id: Optional[str] = None
+ part_direction_uu_id: Optional[str] = None
+ part_type_uu_id: Optional[str] = None
diff --git a/api_validations/validations_response/people.py b/api_validations/validations_response/people.py
new file mode 100644
index 0000000..fcf6da4
--- /dev/null
+++ b/api_validations/validations_response/people.py
@@ -0,0 +1,57 @@
+from typing import Optional
+from api_validations.core_validations import BaseModelRegular
+from api_validations.validations_request import (
+ CrudRecordValidation,
+ CrudRecords,
+)
+
+
+class PeopleListValidation:
+ tr = {
+ **CrudRecordValidation.tr,
+ "firstname": "Ad",
+ "surname": "Soyad",
+ "middle_name": "Orta İsim",
+ "sex_code": "Cinsiyet Kodu",
+ "person_ref": "Kişi Referansı",
+ "person_tag": "Kişi Etiketi",
+ "father_name": "Baba Adı",
+ "mother_name": "Anne Adı",
+ "country_code": "Ülke Kodu",
+ "national_identity_id": "Kimlik Numarası",
+ "birth_place": "Doğum Yeri",
+ "birth_date": "Doğum Tarihi",
+ "tax_no": "Vergi Numarası",
+ }
+ en = {
+ **CrudRecordValidation.en,
+ "firstname": "First Name",
+ "surname": "Surname",
+ "middle_name": "Middle Name",
+ "sex_code": "Sex Code",
+ "person_ref": "Person Reference",
+ "person_tag": "Person Tag",
+ "father_name": "Father's Name",
+ "mother_name": "Mother's Name",
+ "country_code": "Country Code",
+ "national_identity_id": "National Identity ID",
+ "birth_place": "Birth Place",
+ "birth_date": "Birth Date",
+ "tax_no": "Tax Number",
+ }
+
+
+class PeopleListResponse(BaseModelRegular, CrudRecords, PeopleListValidation):
+ firstname: Optional[str] = None
+ surname: Optional[str] = None
+ middle_name: Optional[str] = None
+ sex_code: Optional[str] = None
+ person_ref: Optional[str] = None
+ person_tag: Optional[str] = None
+ father_name: Optional[str] = None
+ mother_name: Optional[str] = None
+ country_code: Optional[str] = None
+ national_identity_id: Optional[str] = None
+ birth_place: Optional[str] = None
+ birth_date: Optional[str] = None
+ tax_no: Optional[str] = None
diff --git a/databases/no_sql_models/__init__.py b/databases/no_sql_models/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/databases/no_sql_models/identity.py b/databases/no_sql_models/identity.py
new file mode 100644
index 0000000..de278be
--- /dev/null
+++ b/databases/no_sql_models/identity.py
@@ -0,0 +1,136 @@
+import datetime
+
+from databases.no_sql_models.validations import PasswordHistoryViaUser, DomainViaUser, AccessHistoryViaUser
+from databases.no_sql_models.mongo_database import MongoQuery
+
+
+class MongoQueryIdentity:
+ """
+ 4ex. mongo_collection_name = str(Company.uu_id()) + "*" + str('UserPasswordHistory')
+ """
+
+ def __init__(self, company_uuid, storage_reasoning: str = None):
+ self.company_uuid = company_uuid
+ self.mongo_collection_base = str(company_uuid)
+ if storage_reasoning:
+ self.mongo_collection_name = (
+ str(company_uuid) + "*" + str(storage_reasoning)
+ )
+ else:
+ self.mongo_collection_name = str(company_uuid) + "*" + str("Domain")
+ self.mongo_engine = MongoQuery(
+ table_name=self.mongo_collection_name, database_name="mongo_database"
+ )
+
+ def use_collection(self, storage_reasoning):
+ self.mongo_collection_name = (
+ str(self.company_uuid) + "*" + str(storage_reasoning)
+ )
+ self.mongo_engine = MongoQuery(
+ table_name=self.mongo_collection_name, database_name="mongo_database"
+ )
+
+ def create_domain_via_user(self, payload: DomainViaUser):
+ self.use_collection("Domain")
+ return self.mongo_engine.find_or_insert(
+ field="user_uu_id",
+ payload={
+ "user_uu_id": payload.user_uu_id,
+ "other_domains_list": [payload.main_domain],
+ "main_domain": payload.main_domain,
+ "modified_at": datetime.datetime.now().timestamp(),
+ }
+ )
+
+ def update_domain_via_user(self, payload: DomainViaUser):
+ self.use_collection("Domain")
+ return self.mongo_engine.update(
+ match=payload.user_uu_id,
+ payload={
+ "other_domains_list": payload.other_domains_list,
+ "modified_at": datetime.datetime.now().timestamp(),
+ },
+ field="user_uu_id",
+ )
+
+ def get_domain_via_user(self, user_uu_id):
+ self.use_collection("Domain")
+ return self.mongo_engine.get_one(match=str(user_uu_id), field="user_uu_id")
+
+ def refresh_password_history_via_user(self, payload: PasswordHistoryViaUser):
+ self.use_collection("PasswordHistory")
+ password_history_item = self.mongo_engine.get_one(
+ match=payload.user_uu_id, field="user_uu_id"
+ )
+ if not password_history_item:
+ self.mongo_engine.insert(
+ payload={
+ "user_uu_id": str(payload.user_uu_id),
+ "password_history": [],
+ }
+ )
+ password_history_item = self.mongo_engine.get_one(
+ match=payload.user_uu_id, field="user_uu_id"
+ )
+ password_history_list = password_history_item.get("password_history", [])
+ hashed_password = payload.password_add.get("password")
+ for password_in_history in password_history_list:
+ if str(password_in_history.get("password")) == str(hashed_password):
+ raise Exception(
+ dict(
+ status_code=400,
+ detail="Password already used. Please enter a new password that you have not used last 3 times."
+ )
+ )
+
+ if len(password_history_list) > 3:
+ password_history_list.pop(0)
+
+ password_history_list.append(payload.password_add)
+ return self.mongo_engine.update(
+ match=payload.user_uu_id,
+ payload={
+ "password_history": password_history_list,
+ "access_history_detail": payload.access_history_detail,
+ "modified_at": datetime.datetime.now().timestamp(),
+ },
+ field="user_uu_id",
+ )
+
+ def get_password_history_via_user(self, user_uu_id):
+ self.use_collection("PasswordHistory")
+ return self.mongo_engine.get_one(match=user_uu_id, field="user_uu_id")
+
+ def update_access_history_via_user(self, payload: AccessHistoryViaUser):
+ self.use_collection("AccessHistory")
+ if already_dict := self.get_access_history_via_user(
+ user_uu_id=payload.user_uu_id
+ ):
+ access_history = already_dict[0].get("access_history") or []
+ access_history.append(payload.access_history)
+ if len(access_history) > 60:
+ access_history.pop(0)
+ return self.mongo_engine.update(
+ match=payload.user_uu_id,
+ payload={
+ "user_uu_id": payload.user_uu_id,
+ "access_history": access_history,
+ "modified_at": datetime.datetime.now().timestamp(),
+ },
+ field="user_uu_id",
+ )
+ return self.mongo_engine.insert(
+ payload={
+ "user_uu_id": payload.user_uu_id,
+ "access_history": [payload.access_history],
+ "modified_at": datetime.datetime.now().timestamp(),
+ }
+ )
+
+ def get_access_history_via_user(self, user_uu_id):
+ self.use_collection("AccessHistory")
+ return self.mongo_engine.filter_by(
+ payload={"user_uu_id": user_uu_id},
+ sort_by="modified_at",
+ sort_direction="desc",
+ )
diff --git a/databases/no_sql_models/login_handlers.py b/databases/no_sql_models/login_handlers.py
new file mode 100644
index 0000000..0eb5af5
--- /dev/null
+++ b/databases/no_sql_models/login_handlers.py
@@ -0,0 +1,88 @@
+# from loggers.loggers import LoginLogger
+
+
+def get_menu_from_mongo(user_id, company_name):
+ from databases.no_sql_models.mongo_database import MongoQuery
+
+ mongo = MongoQuery(
+ table_name=company_name.replace(" ", ""), database_name="mongo_database"
+ )
+ mongo_dict = mongo.parse_json(mongo.get_one(match=user_id, field="user_id")) or {}
+ return mongo_dict.get("menu", [])
+
+
+def load_user_with_erp_details(found_user, access_dict: dict = None):
+ duties = []
+ employee = found_user.person.employee
+ duty_dict = {}
+ try:
+ duty_dict = employee.duty.get_dict(
+ include=["duty_name", "duty_code", "duty_description"]
+ )
+ duty_dict["buildings"] = []
+ duty_dict["response_buildings"] = []
+ duty_dict["department"] = employee.duty.department.get_dict(
+ include=["department_name", "department_code"]
+ )
+ duty_dict["company"] = employee.duty.department.company.get_dict(
+ include=["formal_name", "public_name", "tax_no", "default_lang_type"]
+ )
+ except Exception as e:
+ # LoginLogger.log_exception(
+ # {
+ # "exc": e,
+ # "user": found_user.uu_id,
+ # "function": "load_user_with_erp_details",
+ # }
+ # )
+ err = e
+ print("MongoQuery load_user_with_erp_details", err)
+
+ for building in list(set(employee.duty.department.company.response_buildings)):
+ build_parts = []
+ for part in building.parts:
+ build_parts.append(
+ part.get_dict(
+ include=["uu_id", "part_name", "part_code", "part_description"]
+ )
+ )
+ duty_dict["response_buildings"].append(
+ {
+ "build": building.get_dict(include=["build_name", "uu_id"]),
+ "parts": build_parts,
+ }
+ )
+ for building in list(set(employee.duty.department.company.buildings)):
+ build_parts = []
+ for part in building.parts:
+ build_parts.append(
+ part.get_dict(
+ include=[
+ "uu_id",
+ "part_name",
+ "part_code",
+ "part_description",
+ ]
+ )
+ )
+ duty_dict["buildings"].append(
+ {
+ "build": building.get_dict(include=["build_name", "uu_id"]),
+ "parts": build_parts,
+ }
+ )
+ duties.append(duty_dict)
+ return_dict = access_dict if access_dict else {}
+ return_dict.update(
+ {
+ "data": {
+ "profile": found_user.get_dict(),
+ "employee_info": duties,
+ "menu": get_menu_from_mongo(
+ found_user.id,
+ company_name=duty_dict.get("company", {}).get("public_name", ""),
+ ),
+ },
+ }
+ )
+ return return_dict
diff --git a/databases/no_sql_models/mongo_database.py b/databases/no_sql_models/mongo_database.py
new file mode 100644
index 0000000..9ced7b5
--- /dev/null
+++ b/databases/no_sql_models/mongo_database.py
@@ -0,0 +1,312 @@
+from itertools import count
+
+import pymongo
+
+from json import loads
+from bson import ObjectId, json_util
+from pydantic import BaseModel
+from api_configs import MongoConfig
+
+from pymongo import MongoClient
+from pymongo.collection import Collection
+from pymongo.results import InsertManyResult
+
+# from configs import TestMongo as MongoConfig
+
+
+class Paginate(BaseModel):
+ pageSize: int = 10
+ pageNumber: int = 1
+ sortField: str = "_id"
+ sortOrder: str = "desc"
+
+ def grab_paginates(self):
+ size_ = self.pageSize
+ return (
+ size_,
+ size_ * (self.pageNumber - 1),
+ self.sortField,
+ -1 if self.sortOrder == "desc" else 1,
+ )
+class MongoResponse:
+
+ def __init__(self, status: bool, message: str, message_code:str = None, data: dict = None, mongo=None, count: int = 1):
+ self.status = status
+ self.message = message
+ self.data = data
+ self.mongo = mongo
+ self.message_code = message_code
+ self.count = count
+
+ def as_dict(self):
+ return {
+ "status": self.status,
+ "count": self.count,
+ "message": self.message,
+ "message_code": self.message_code,
+ "data": self.data,
+ }
+
+class MongoQuery:
+
+ def __init__(self, table_name: str, database_name: str):
+ database = MongoClient(MongoConfig.url)[database_name]
+ self.table: Collection = database[table_name]
+
+ @staticmethod
+ def grab_paginates(paginate):
+ return (
+ paginate.size,
+ paginate.size * (paginate.page - 1),
+ paginate.order_field,
+ -1 if paginate.order_type == "desc" else 1,
+ )
+
+ @staticmethod
+ def parse_json(data):
+ return loads(json_util.dumps(data))
+
+ def insert(self, payload) -> MongoResponse:
+ insert = self.table.insert_one(document=payload)
+ if insert.acknowledged:
+ return MongoResponse(
+ status=True,
+ message="The document has been created",
+ message_code="CREATED",
+ data=payload,
+ mongo=insert,
+ )
+ return MongoResponse(
+ status=False,
+ message="The document has not been created",
+ message_code="NOT_CREATED",
+ data=None,
+ mongo=insert,
+ count=0
+ )
+
+ def insert_many(self, payload) -> MongoResponse:
+ insert_many = self.table.insert_many(documents=payload)
+ if insert_many.acknowledged:
+ return MongoResponse(
+ status=True,
+ message="The documents have been created",
+ message_code="CREATED",
+ data=payload,
+ mongo=insert_many,
+ count=len(payload)
+ )
+ return MongoResponse(
+ status=False,
+ message="The documents have not been created",
+ message_code="NOT_CREATED",
+ data=None,
+ mongo=insert_many,
+ count=0
+ )
+
+ def find_or_insert(self, payload, field: str = "id") -> MongoResponse:
+ if field == "id":
+ found_row = self.get_one(match=payload["_id"], field="_id")
+ if found_row.status:
+ return MongoResponse(
+ status=False,
+ message="The document already exists",
+ data=found_row.data,
+ mongo=found_row.mongo,
+ )
+ if mongo := self.table.insert_one(document=payload).acknowledged:
+ return MongoResponse(
+ status=True,
+ message="The document has been created",
+ data=payload,
+ mongo=mongo
+ )
+
+ found_row = self.get_one(match=payload[field], field=field)
+ if found_row.status:
+ return MongoResponse(
+ status=False,
+ message_code="ALREADY_EXISTS",
+ message="The document already exists",
+ data=found_row.data,
+ mongo=found_row.mongo
+ )
+ insert_row = self.table.insert_one(document=payload)
+ return MongoResponse(
+ status=True,
+ message="The document has been created",
+ message_code="CREATED",
+ data=payload,
+ mongo=insert_row
+ )
+
+ def update(self, match, payload, field: str = "id"):
+ if field == "id":
+ filter_ = {"_id": ObjectId(match)}
+ update_one = self.table.update_one(filter=filter_, update={"$set": payload})
+ return MongoResponse(
+ status=True,
+ message="The document has been updated",
+ message_code="UPDATED",
+ data=self.get_one(match=match, field=field).data,
+ mongo=update_one
+ )
+ update_one = self.table.update_one(filter={field: match}, update={"$set": payload})
+ return MongoResponse(
+ status=True,
+ message="The document has been updated",
+ message_code="UPDATED",
+ data=self.get_one(match=match, field=field).data,
+ mongo=update_one
+ )
+
+ def get_one(self, match, field: str = "id"):
+ if field == "id":
+ if get_one := self.table.find_one(filter={"_id": ObjectId(match)}):
+ return MongoResponse(
+ status=True,
+ message="The document has been found",
+ message_code="FOUND",
+ data=self.parse_json(data=get_one),
+ mongo=get_one
+ )
+ if get_one := self.table.find_one(filter={field: match}):
+ return MongoResponse(
+ status=True,
+ message="The document has been found",
+ message_code="FOUND",
+ data=self.parse_json(data=get_one),
+ mongo=get_one
+ )
+ return MongoResponse(
+ status=False,
+ message="The document has not been found",
+ message_code="NOT_FOUND",
+ data=None,
+ mongo=None
+ )
+
+ def filter_by(self, payload, sort_by: str = "_id", sort_direction: str = "asc"):
+ sort_direction = (
+ pymongo.ASCENDING
+ if str(sort_direction).lower() == "asc"
+ else pymongo.DESCENDING
+ )
+ return_ = self.table.find(payload).sort(sort_by, sort_direction)
+ data = self.parse_json(data=return_)
+ if len(data) == 0:
+ return MongoResponse(
+ status=False,
+ message="The documents have not been found",
+ message_code="NOT_FOUND",
+ data=None,
+ mongo=return_,
+ count=0
+ )
+ return MongoResponse(
+ status=True,
+ message="The documents have been found",
+ message_code="FOUND",
+ count=self.table.count_documents(payload),
+ data=data,
+ )
+
+ def delete_one(self, match, field: str = "id"):
+ if field == "id":
+ delete_one = self.table.delete_one(filter={"_id": ObjectId(match)})
+ if delete_one.deleted_count:
+ return MongoResponse(
+ status=True,
+ message="The document has been deleted",
+ message_code="DELETED",
+ data=None,
+ count=delete_one.deleted_count,
+ mongo=delete_one
+ )
+ delete_one = self.table.delete_one(filter={field: match})
+ if delete_one.deleted_count:
+ return MongoResponse(
+ status=True,
+ message="The document has been deleted",
+ message_code="DELETED",
+ data=None,
+ count=delete_one.deleted_count,
+ mongo=delete_one
+ )
+ return MongoResponse(
+ status=False,
+ message="The document has not been deleted",
+ message_code="NOT_DELETED",
+ data=None,
+ mongo=None,
+ count=0
+ )
+
+ def delete_all(self, match, field: str = "id"):
+ if field == "id":
+ delete_many = self.table.delete_many(filter={"_id": ObjectId(match)})
+ if delete_many.deleted_count:
+ return MongoResponse(
+ status=True,
+ message="The document has been deleted",
+ message_code="DELETED",
+ data=None,
+ count=delete_many.deleted_count,
+ mongo=delete_many
+ )
+ delete_many = self.table.delete_many(filter={field: match})
+ if delete_many.deleted_count:
+ return MongoResponse(
+ status=True,
+ message="The document has been deleted",
+ message_code="DELETED",
+ data=None,
+ count=delete_many.deleted_count,
+ mongo=delete_many
+ )
+ return MongoResponse(
+ status=False,
+ message="The document has not been deleted",
+ message_code="NOT_DELETED",
+ data=None,
+ mongo=None,
+ count=0
+ )
+
+ def list_all(self, paginate: Paginate):
+ size, skip, field, order = paginate.grab_paginates()
+ return_ = self.table.find().sort([(field, order)]).skip(skip).limit(size)
+ self.table.count_documents({}), self.parse_json(data=return_)
+ data = self.parse_json(data=return_)
+ if len(data) == 0:
+ return MongoResponse(
+ status=False,
+ message="The documents have not been found",
+ message_code="NOT_FOUND",
+ data=None,
+ mongo=return_,
+ count=0
+ )
+ return MongoResponse(
+ status=True,
+ message="The documents have been found",
+ message_code="FOUND",
+ count=self.table.count_documents({}),
+ data=data,
+ mongo=return_
+ )
+
+ def get_all(self):
+ return_ = self.table.find()
+ return MongoResponse(
+ status=True,
+ message="The documents have been found",
+ message_code="FOUND",
+ count=self.table.count_documents({}),
+ data=self.parse_json(data=return_),
+ mongo=return_
+ )
+
+
+# Mongo = MongoQuery(table_name="XcompanyConfig", database_name="mongo_database")
diff --git a/databases/no_sql_models/validations.py b/databases/no_sql_models/validations.py
new file mode 100644
index 0000000..fbbdab2
--- /dev/null
+++ b/databases/no_sql_models/validations.py
@@ -0,0 +1,19 @@
+from typing import Optional
+from pydantic import BaseModel
+
+
+class DomainViaUser(BaseModel):
+ user_uu_id: str
+ main_domain: str
+ other_domains_list: Optional[list] = None
+
+
+class PasswordHistoryViaUser(BaseModel):
+ user_uu_id: str
+ password_add: dict
+ access_history_detail: Optional[dict]
+
+
+class AccessHistoryViaUser(BaseModel):
+ user_uu_id: str
+ access_history: dict