database and services updated and tested

This commit is contained in:
berkay 2025-01-08 21:35:11 +03:00
parent 364a4df4b1
commit 08896e4c61
132 changed files with 13302 additions and 95 deletions

View File

@ -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

View File

@ -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))

View File

@ -0,0 +1 @@
__all__ = []

View File

@ -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

View File

@ -0,0 +1 @@
__all__ = []

View File

@ -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

View File

@ -0,0 +1 @@
__all__ = []

0
ApiServices/__init__.py Normal file
View File

View File

View File

@ -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,
),
)

View File

@ -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"

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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"

View File

@ -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",

View File

@ -1,3 +1,5 @@
storeHost = "10.10.2.36"

View File

@ -0,0 +1,6 @@
class EmailConfig:
EMAIL_HOST: str = "10.10.2.34"
EMAIL_USERNAME: str = "karatay@mehmetkaratay.com.tr"
EMAIL_PASSWORD: str = "system"

0
api_events/__init__.py Normal file
View File

View File

@ -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",
]

View File

@ -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",
)

View File

View File

@ -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")
)

View File

View File

@ -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")
)

View File

@ -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): ...

View File

@ -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): ...

View File

@ -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,
# )
# )
# )

View File

@ -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): ...

View File

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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)

View File

@ -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,
)

View File

@ -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(),
# ),
# )

View File

@ -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")
)
)

View File

@ -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,
)

View File

@ -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")
)

View File

@ -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")
)
)

View File

@ -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")
)

View File

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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,
# }

View File

@ -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

View File

@ -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

View File

@ -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

View File

View File

@ -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")
)

View File

@ -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")
)

View File

@ -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",
]

View File

@ -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)

View File

@ -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")

View File

@ -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)

View File

@ -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 = []

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

0
api_services/__init__.py Normal file
View File

View File

@ -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,
)

View File

@ -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

View File

@ -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)

View File

@ -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."
# ),
# )

View File

@ -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."
),
)

View File

@ -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 = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.header {
text-align: center;
padding-bottom: 20px;
border-bottom: 1px solid #dddddd;
}
.header img {
max-width: 100px;
}
.content {
padding: 20px 0;
}
.footer {
text-align: center;
padding: 10px;
font-size: 12px;
color: #777777;
}
.btn-success {
color: #fff;
background-color: #198754;
border-color: #198754;
text-align: center;
text-decoration: none;
vertical-align: middle;
width: 150px;
height: 40px;
border-radius: 5px;
font-weight: 400;
padding: .375rem .75rem;
}
</style>
</head>
<body>
<div class="email-container">
<div class="header">
<img src="" alt="Company Logo">
<h2>Reset Password</h2>
</div>
<div class="content">
<p>Dear %s,</p>
<p>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:</p>
<p>Please note that this link is only valid for a day only. If you did not request a password reset, please disregard this message.</p>
<a href="%s"><button type="button" class="btn-success">Reset Password</button></a>
</div>
<div class="footer">
<p>&copy; %s Evyos Ltd Şti. All rights reserved.</p>
</div>
</div>
</body>
</html>
""" % (
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 = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thank You for Changing Your Password</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.header {
text-align: center;
padding-bottom: 20px;
border-bottom: 1px solid #dddddd;
}
.header img {
max-width: 100px;
}
.content {
padding: 20px 0;
}
.footer {
text-align: center;
padding: 10px;
font-size: 12px;
color: #777777;
}
</style>
</head>
<body>
<div class="email-container">
<div class="header">
<img src="" alt="Company Logo">
<h2>Your Password has changed</h2>
</div>
<div class="content">
<p>Dear %s,</p>
<p>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.</p>
<p>Thank you for helping us keep your account secure.</p>
</div>
<div class="footer">
<p>&copy; %s Evyos Ltd Şti. All rights reserved.</p>
</div>
</div>
</body>
</html>
""" % (
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 = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thank You for Changing Your Password</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.header {
text-align: center;
padding-bottom: 20px;
border-bottom: 1px solid #dddddd;
}
.header img {
max-width: 100px;
}
.content {
padding: 20px 0;
}
.footer {
text-align: center;
padding: 10px;
font-size: 12px;
color: #777777;
}
</style>
</head>
<body>
<div class="email-container">
<div class="header">
<img src="" alt="Company Logo">
<h2>An Unknown login has been attempted</h2>
</div>
<div class="content">
<p>Dear %s,</p>
<p>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</p>
<p>Thank you for helping us keep your account secure.</p>
<h1>Address of ip attempt</h1>
<p>City : %s</p>
<p>Zip Code : %s</p>
<p>Country : %s</p>
<p>Region : %s</p>
<p>Region Name : %s</p>
<p>If you are not login from this address lets us now by clicking link below</p>
<a href="%s"><button type="button" class="btn-success">Reset Password</button></a>
</div>
<div class="footer">
<p>&copy; %s Evyos Ltd Şti. All rights reserved.</p>
</div>
</div>
</body>
</html>
""" % (
user_name,
address["city"],
address["zip"],
address["country"],
address["region"],
address["regionName"],
kwargs["notice_link"],
current_year,
)
return template

View File

View File

@ -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()

View File

@ -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",
]

View File

@ -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

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More