import typing from fastapi import status, HTTPException from databases import ( BuildParts, Build, BuildLivingSpace, OccupantTypes, ) from api_events.events.abstract_class import MethodToEvent, ActionsSchema from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject from api_validations.core_response import return_json_response_from_alchemy from api_validations import ( InsertBuildLivingSpace, ListOptions, ) class BuildingLivingSpacesPartsListEventMethods(MethodToEvent): event_type = "SELECT" __event_keys__ = { "8fd04d94-68fb-4a07-9549-8b47aee3a870": "building_build_parts_list", "2f3041a9-6184-44c2-ac38-8ea934297ed1": "building_build_parts_list_with_expired", } @classmethod def building_build_parts_list(cls, list_options: ListOptions, token_dict): build_id_list_query = Build.select_action( employee_id=token_dict.selected_company.employee_id ) Build.filter_attr = list_options build_part_id_list_query = BuildParts.filter_active( BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]), ) list_options.query.pop("expiry_starts", None) list_options.query.pop("expiry_ends", None) records = BuildLivingSpace.filter_active( BuildLivingSpace.build_parts_id.in_( [build_part.id for build_part in build_part_id_list_query.data] ), *BuildLivingSpace.get_smart_query(smart_query=list_options.query), ) return return_json_response_from_alchemy( response=records, pagination=list_options ) @classmethod def building_build_parts_list_with_expired( cls, list_options: ListOptions, token_dict ): build_id_list_query = Build.select_action( employee_id=token_dict.selected_company.employee_id ) Build.filter_attr = list_options build_part_id_list_query = BuildParts.filter_active( BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]), ) records = BuildLivingSpace.filter_active( BuildLivingSpace.build_parts_id.in_( [build_part.id for build_part in build_part_id_list_query.data] ), *BuildLivingSpace.get_smart_query(smart_query=list_options.query), expired=False, ) return return_json_response_from_alchemy( response=records, pagination=list_options ) class BuildingLivingSpacesPartsCreateEventMethods(MethodToEvent): event_type = "CREATE" __event_keys__ = { "b78ca45c-b9f4-41f6-9ddb-2c6f2faa2570": "building_live_space_create" } @classmethod def building_live_space_create( cls, data: InsertBuildLivingSpace, token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject], ): from service_app.application import DateTimeLocal from database_sql_models import People from sqlalchemy.sql import select data_dict = data.dump() build_id_list_query = Build.select_action( employee_id=token_dict.selected_company.employee_id ) build_part = BuildParts.filter_active( BuildParts.uu_id == data.build_parts_uu_id, BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]), ) if not build_part.get(1): raise HTTPException( status_code=status.HTTP_418_IM_A_TEAPOT, detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id", ) build_part = build_part.get(1) life_person = People.find_one(uu_id=data.person_uu_id or "") if not life_person: raise HTTPException( status_code=status.HTTP_418_IM_A_TEAPOT, detail=f"{data.life_person_uu_id} - Living Person is not found in database. " f"Check build live person uu_id", ) occupant_type = OccupantTypes.find_one(uu_id=data.occupant_type_uu_id) if not occupant_type: raise HTTPException( status_code=status.HTTP_418_IM_A_TEAPOT, detail=f"{data.occupant_type_uu_id} - Occupant Type is not found in database. " f"Check 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.session.execute( select(BuildLivingSpace.id) .where( *[ BuildLivingSpace.build_parts_id == build_part.id, BuildLivingSpace.person_id == life_person.id, BuildLivingSpace.occupant_type == occupant_type.id, BuildLivingSpace.active == True, BuildLivingSpace.is_confirmed == True, str(DateTimeLocal.now()) < BuildLivingSpace.expiry_ends, str(DateTimeLocal.now()) >= BuildLivingSpace.expiry_starts, ] ) .order_by(BuildLivingSpace.expiry_starts.desc()) ).first() last_living_space = BuildLivingSpace.find_one( id=living_space_id[0] if living_space_id else None ) data_dict["expiry_starts"] = str(DateTimeLocal.now()) created_living_space = BuildLivingSpace.create_action( data=data_dict, token_dict=token_dict ) if last_living_space: if last_living_space.expiry_ends > DateTimeLocal.now(): last_living_space.expiry_ends = str(DateTimeLocal.shift(minutes=-10)) last_living_space.save() return created_living_space class BuildingLivingSpacesPartsUpdateEventMethods(MethodToEvent): event_type = "UPDATE" __event_keys__ = { "70b4666f-4ceb-46ec-b89e-24be8712f0e7": "building_build_parts_update" } @classmethod def building_build_parts_update(cls, build_uu_id: str, data, token_dict): from service_app.application import DateTimeLocal from database_sql_models import People from sqlalchemy.sql import select data_dict = data.dump() build_id_list_query = Build.select_action( employee_id=token_dict.selected_company.employee_id ) build_part = BuildParts.filter_active( BuildParts.uu_id == data.build_parts_uu_id, BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]), ) if not build_part.get(1): raise HTTPException( status_code=status.HTTP_418_IM_A_TEAPOT, detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id", ) build_part = build_part.get(1) life_person = People.find_one(uu_id=data.life_person_uu_id or "") if not life_person: raise HTTPException( status_code=status.HTTP_418_IM_A_TEAPOT, detail=f"{data.life_person_uu_id} - Living Person is not found in database. " f"Check build live person uu_id", ) living_spaces = select(BuildLivingSpace.id).order_by( BuildLivingSpace.expiry_starts.desc() ) living_space_id = BuildLivingSpace.session.execute(living_spaces).first() last_living_space = BuildLivingSpace.find_one( id=getattr(living_space_id[0], "id", None) if living_space_id else None ) data_dict["expiry_starts"] = DateTimeLocal.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: raise HTTPException( status_code=status.HTTP_418_IM_A_TEAPOT, detail=dict( 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"] BuildingLivingSpacesPartsListEventMethod = BuildingLivingSpacesPartsListEventMethods( action=ActionsSchema(endpoint="/building/living_space/list") ) BuildingLivingSpacesPartsCreateEventMethod = ( BuildingLivingSpacesPartsCreateEventMethods( action=ActionsSchema(endpoint="/building/living_space/create") ) ) BuildingLivingSpacesPartsUpdateEventMethod = ( BuildingLivingSpacesPartsUpdateEventMethods( action=ActionsSchema(endpoint="/building/living_space/update") ) )