from fastapi.exceptions import HTTPException from fastapi.responses import JSONResponse from databases import ( AddressPostcode, Addresses, RelationshipEmployee2PostCode, AddressStreet, ) from api_validations.validations_request import ( ListOptions, InsertAddress, InsertPostCode, SearchAddress ) from api_validations.core_response import return_json_response_from_alchemy 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_keys__ = { "9c251d7d-da70-4d63-a72c-e69c26270442": "address_list_super_user", # 1 "52afe375-dd95-4f4b-aaa2-4ec61bc6de52": "address_list_employee", } @classmethod def address_list_super_user(cls, list_options: ListOptions, token_dict): from sqlalchemy import select post_code_list = RelationshipEmployee2PostCode.filter_active( 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 = AddressPostcode.session.execute( select(AddressPostcode.street_id).where( AddressPostcode.id.in_(post_code_id_list) ) ).all() Addresses.pre_query = Addresses.filter_active( Addresses.street_id.in_(*get_street_ids) if get_street_ids else None ).query Addresses.filter_attr = list_options records = Addresses.filter_active( *Addresses.get_smart_query(list_options.query) ) return return_json_response_from_alchemy( response=records, pagination=list_options ) @classmethod def address_list_employee(cls, list_options: ListOptions, token_dict): Addresses.filter_attr = list_options records = Addresses.list_via_employee( token_dict=token_dict, filter_expr=Addresses.get_smart_query(list_options.query), ) return return_json_response_from_alchemy( response=records, pagination=list_options ) class AddressCreateEventMethods(MethodToEvent): event_type = "CREATE" __event_keys__ = { "ffdc445f-da10-4ce4-9531-d2bdb9a198ae": "create_address", } @classmethod def create_address(cls, data: InsertAddress, token_dict): post_code = AddressPostcode.find_one(uu_id=data.post_code_uu_id) 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 del data_dict["post_code_uu_id"] address = Addresses.find_or_create(**data_dict) if not address.is_found: RelationshipEmployee2PostCode.find_or_create( employee_id=token_dict.selected_company.employee_id, member_id=post_code.id, company_id=token_dict.selected_company.company_id, is_confirmed=True, ) return JSONResponse( content={ "completed": True, "message": "Create Address record", "data": address.get_dict(), }, status_code=200, ) class AddressSearchEventMethods(MethodToEvent): event_type = "SEARCH" __event_keys__ = { "e0ac1269-e9a7-4806-9962-219ac224b0d0": "search_address", } @classmethod def search_address(cls, data: SearchAddress, token_dict): import database_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( database_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_keys__ = { "1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27": "update_address", } @classmethod def update_address(cls, address_uu_id: str, data: InsertAddress, token_dict): address = Addresses.find_one_or_abort(uu_id=address_uu_id) post_code = RelationshipEmployee2PostCode.postcode.find_one( member_id=address.post_code_id ) if not post_code: raise HTTPException( status_code=404, detail="Post code not found. User can not update address without post code.", ) data_dict = data.excluded_dump() data_dict["post_code_id"] = post_code.id del data_dict["post_code_uu_id"] updated_address = address.update(**data_dict) return JSONResponse( content={ "completed": True, "message": "Update Address record", "data": updated_address.get_dict(), }, status_code=200, ) class AddressPatchEventMethods(MethodToEvent): event_type = "PATCH" __event_keys__ = { "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d": "patch_address", } @classmethod def patch_address(cls, address_uu_id: str, data: InsertAddress, token_dict): address = Addresses.find_one_or_abort(uu_id=address_uu_id) post_code = RelationshipEmployee2PostCode.postcode.find_one( 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_keys__ = { "6f1406ac-577d-4f2c-8077-71fff2252c5f": "create_post_code_address", } @classmethod def create_post_code_address(cls, data: InsertPostCode, token_dict): data_dump = data.excluded_dump() street = AddressStreet.find_one(uu_id=data.street_uu_id) 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["street_uu_id"], data_dump["post_code"] post_code = AddressPostcode.find_or_create(**data_dump) if not post_code.is_found: 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, is_confirmed=True, ) 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_keys__ = { "df18e489-a63c-477f-984c-aa52d30640ad": "update_post_code_address", } @classmethod def update_post_code_address( cls, post_code_uu_id: str, data: InsertPostCode, token_dict ): post_code = AddressPostcode.find_one_or_abort(uu_id=post_code_uu_id) street = AddressStreet.find_one(uu_id=data.street_uu_id) if not street: raise HTTPException( status_code=404, detail="Street not found. User can not update post code without street.", ) updated_post_code = post_code.update(**data.excluded_dump()) return JSONResponse( content={ "completed": True, "message": "Update Post Code record", "data": updated_post_code.get_dict(), }, status_code=200, ) class AddressPostCodeListEventMethods(MethodToEvent): event_type = "SELECT" __event_keys__ = { "88d37b78-1ac4-4513-9d25-090ac3a24f31": "list_post_code_address", } @classmethod def list_post_code_address(cls, list_options: ListOptions, token_dict): post_code_list = AddressPostcode.__many__table__.filter_active( 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_active( AddressPostcode.id.in_( [post_code.member_id for post_code in post_code_list] ) ).query AddressPostcode.filter_attr = list_options records = AddressPostcode.filter_active( *Addresses.get_smart_query(list_options.query) ) return return_json_response_from_alchemy( response=records, pagination=list_options ) 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") )