diff --git a/ApiDefaults/create_app.py b/ApiDefaults/create_app.py index 5f4654b..94e667f 100644 --- a/ApiDefaults/create_app.py +++ b/ApiDefaults/create_app.py @@ -5,8 +5,10 @@ from fastapi.responses import RedirectResponse cluster_is_set = False + def create_events_if_any_cluster_set(): import Events + global cluster_is_set if not Events.__all__ or cluster_is_set: return @@ -60,7 +62,7 @@ def create_app(): route_register = RouteRegisterController(app=application, router_list=get_routes()) application = route_register.register_routes() - + create_events_if_any_cluster_set() application.openapi = lambda _=application: create_openapi_schema(_) return application diff --git a/ApiServices/DealerService/app.py b/ApiServices/DealerService/app.py index f3a9d3b..bcd844d 100644 --- a/ApiServices/DealerService/app.py +++ b/ApiServices/DealerService/app.py @@ -1,12 +1,12 @@ from Controllers.Postgres.database import get_db -from Schemas import Users, Employees, BuildLivingSpace +from Schemas import Users, Employees, BuildLivingSpace, Services from init_service_to_events import init_service_to_event_matches_for_super_user from init_applications import ( init_applications_for_super_user, - init_applications_for_general_manager, - init_applications_for_build_manager, - init_applications_for_owner, - init_applications_for_tenant, + # init_applications_for_general_manager, + # init_applications_for_build_manager, + # init_applications_for_owner, + # init_applications_for_tenant, ) @@ -16,62 +16,59 @@ if __name__ == "__main__": Set Events to service | Set Service to employee """ with get_db() as db_session: - if super_man := Users.filter_one( - Users.email == "karatay.berkay.sup@evyos.com.tr", db=db_session - ).data: - super_employee = Employees.filter_one( - Employees.people_id == super_man.person_id, db=db_session - ).data - + service_super_user = Services.filter_one(Services.service_code == "SRE-SUE", db=db_session).data + user_super_user = Users.filter_one(Users.email == "karatay.berkay.sup@evyos.com.tr", db=db_session).data + employee_super_user = Employees.filter_one(Employees.people_id == user_super_user.person_id, db=db_session).data + if service_super_user and user_super_user and employee_super_user: init_service_to_event_matches_for_super_user( - super_user=super_employee, db_session=db_session + service_match=service_super_user, employee_match=employee_super_user, db_session=db_session ) init_applications_for_super_user( - super_user=super_employee, db_session=db_session + service_match=service_super_user, employee_match=employee_super_user, db_session=db_session ) - with get_db() as db_session: - print("Createing GM") - if gen_man := Users.filter_one( - Users.email == "example.general@evyos.com.tr", db=db_session - ).data: - gen_man_employee = Employees.filter_one( - Employees.people_id == gen_man.person_id, db=db_session - ).data - print("General Manager : ", gen_man_employee) - init_applications_for_general_manager( - super_user=gen_man_employee, db_session=db_session - ) + # with get_db() as db_session: + # print("Createing GM") + # if gen_man := Users.filter_one( + # Users.email == "example.general@evyos.com.tr", db=db_session + # ).data: + # gen_man_employee = Employees.filter_one( + # Employees.people_id == gen_man.person_id, db=db_session + # ).data + # print("General Manager : ", gen_man_employee) + # init_applications_for_general_manager( + # super_user=gen_man_employee, db_session=db_session + # ) - with get_db() as db_session: - if build_man := Users.filter_one( - Users.email == "example.build.manager@gmail.com", db=db_session - ).data: - build_man_employee = BuildLivingSpace.filter_one( - BuildLivingSpace.person_id == build_man.person_id, db=db_session - ).data - init_applications_for_build_manager( - super_user=build_man_employee, db_session=db_session - ) + # with get_db() as db_session: + # if build_man := Users.filter_one( + # Users.email == "example.build.manager@gmail.com", db=db_session + # ).data: + # build_man_employee = BuildLivingSpace.filter_one( + # BuildLivingSpace.person_id == build_man.person_id, db=db_session + # ).data + # init_applications_for_build_manager( + # super_user=build_man_employee, db_session=db_session + # ) - with get_db() as db_session: - if own_flt := Users.filter_one( - Users.email == "example.owner@gmail.com", db=db_session - ).data: - own_flt_employee = BuildLivingSpace.filter_one( - BuildLivingSpace.person_id == own_flt.person_id, db=db_session - ).data - init_applications_for_owner( - super_user=own_flt_employee, db_session=db_session - ) + # with get_db() as db_session: + # if own_flt := Users.filter_one( + # Users.email == "example.owner@gmail.com", db=db_session + # ).data: + # own_flt_employee = BuildLivingSpace.filter_one( + # BuildLivingSpace.person_id == own_flt.person_id, db=db_session + # ).data + # init_applications_for_owner( + # super_user=own_flt_employee, db_session=db_session + # ) - with get_db() as db_session: - if ten_flt := Users.filter_one( - Users.email == "example.tenant@gmail.com", db=db_session - ).data: - ten_flt_employee = BuildLivingSpace.filter_one( - BuildLivingSpace.person_id == ten_flt.person_id, db=db_session - ).data - init_applications_for_tenant( - super_user=ten_flt_employee, db_session=db_session - ) + # with get_db() as db_session: + # if ten_flt := Users.filter_one( + # Users.email == "example.tenant@gmail.com", db=db_session + # ).data: + # ten_flt_employee = BuildLivingSpace.filter_one( + # BuildLivingSpace.person_id == ten_flt.person_id, db=db_session + # ).data + # init_applications_for_tenant( + # super_user=ten_flt_employee, db_session=db_session + # ) diff --git a/ApiServices/DealerService/init_applications.py b/ApiServices/DealerService/init_applications.py index 6eb3a6b..ca4c8e1 100644 --- a/ApiServices/DealerService/init_applications.py +++ b/ApiServices/DealerService/init_applications.py @@ -4,222 +4,193 @@ from Schemas import ( Application2Occupant, Employees, BuildLivingSpace, + Services, + Service2Application, ) -def init_applications_for_super_user(super_user: Employees, db_session=None) -> None: - list_of_created_apps = [ - dict( - name="Dashboard1", - application_code="app000001", - site_url="/dashboard", - application_type="info", - description="Dashboard Page", - ), - dict( - name="Individual", - application_code="app000003", - site_url="/individual", - application_type="Dash", - description="Individual Page for people", - ), - dict( - name="User", - application_code="app000004", - site_url="/user", - application_type="Dash", - description="Individual Page for user", - ), - dict( - name="Build", - application_code="app000005", - site_url="/build", - application_type="Dash", - description="Individual Page for build", - ), - dict( - name="BuildParts", - application_code="app000006", - site_url="/build/parts", - application_type="Dash", - description="Individual Page for build parts", - ), - dict( - name="BuildArea", - application_code="app000007", - site_url="/build/area", - application_type="Dash", - description="Individual Page for build area", - ), - dict( - name="ManagementAccounting", - application_code="app000008", - site_url="/management/accounting", - application_type="Dash", - description="Individual Page for management accounting", - ), - dict( - name="ManagementBudget", - application_code="app000009", - site_url="/management/budget", - application_type="Dash", - description="Individual Page for management accounting2", - ), - dict( - name="ManagementMeetingClose", - application_code="app000010", - site_url="/annual/meeting/close", - application_type="Dash", - description="Individual Page for management accounting3", - ), - dict( - name="EmergencyMeeting", - application_code="app000011", - site_url="/emergency/meeting", - application_type="Dash", - description="Individual Page for management accounting4", - ), - dict( - name="EmergencyMeetingClose", - application_code="app000012", - site_url="/emergency/meeting/close", - application_type="Dash", - description="Individual Page for management accounting5", - ), - dict( - name="MeetingParticipation", - application_code="app000013", - site_url="/meeting/participation", - application_type="Dash", - description="Individual Page for management accounting6", - ), - ] - for list_of_created_app in list_of_created_apps: - created_page = Applications.find_or_create( - **list_of_created_app, +def init_applications_for_super_user(service_match: Services, employee_match: Employees, db_session=None) -> None: + list_of_all_events = Applications.filter_all(db=db_session).data + Service2Application.filter_all(db=db_session).query.delete() + Service2Application.save(db=db_session) + + for list_of_event_code in list_of_all_events: + service_to_event_found = Service2Application.filter_one_system( + Service2Application.application_id == list_of_event_code.id, + Service2Application.service_id == service_match.id, db=db_session, + ) + if service_to_event_found.data: + service_to_event_found.destroy(db=db_session) + print( + f"UUID: {service_to_event_found.uu_id} application is deleted from {service_match.service_description}" + ) + + employee_added_application = Service2Application.find_or_create( + service_id=service_match.id, + service_uu_id=str(service_match.uu_id), + application_id=list_of_event_code.id, + application_uu_id=str(list_of_event_code.uu_id), + application_code=list_of_event_code.application_code, + site_url=list_of_event_code.site_url, is_confirmed=True, - ) - if created_page.meta_data.created: - created_page.save(db=db_session) - - application_employee_created = Application2Employee.find_or_create( - employee_id=super_user.id, - employee_uu_id=str(super_user.uu_id), - site_url=created_page.site_url, - application_code=created_page.application_code, - application_id=created_page.id, - application_uu_id=str(created_page.uu_id), - is_confirmed=True, + active=True, db=db_session, ) - if application_employee_created.meta_data.created: - application_employee_created.save(db=db_session) + if employee_added_application.meta_data.created: + employee_added_application.save(db=db_session) + print( + f"UUID: {employee_added_application.uu_id} application is saved to {service_match.service_description}" + ) - -def init_applications_for_general_manager( - super_user: Employees, db_session=None -) -> None: - list_of_created_apps = [ - dict( - name="Dashboard1", - application_code="app000001", - site_url="/dashboard", - application_type="info", - description="Dashboard Page", - ), - dict( - name="ManagementAccounting", - application_code="app000008", - site_url="/management/accounting", - application_type="Dash", - description="Individual Page for management accounting", - ), - ] - for list_of_created_app in list_of_created_apps: - created_page = Applications.find_or_create( - **list_of_created_app, - db=db_session, + employee_added_service = Application2Employee.find_or_create( + service_id=service_match.id, + service_uu_id=str(service_match.uu_id), + employee_id=employee_match.id, + employee_uu_id=str(employee_match.uu_id), + is_confirmed=True, + db=db_session, + ) + if employee_added_service.meta_data.created: + employee_added_service.save(db=db_session) + print( + f"UUID: {employee_added_service.uu_id} service is saved to {employee_match.uu_id}" ) - print("Application : ", created_page) - if created_page.meta_data.created: - created_page.save(db=db_session) - - application_employee_created = Application2Employee.find_or_create( - employee_id=super_user.id, - employee_uu_id=str(super_user.uu_id), - site_url=created_page.site_url, - application_code=created_page.application_code, - application_id=created_page.id, - application_uu_id=str(created_page.uu_id), - is_confirmed=True, - db=db_session, - ) - print("Application Employee : ", application_employee_created) - if application_employee_created.meta_data.created: - application_employee_created.save(db=db_session) -def init_applications_for_build_manager( - super_user: BuildLivingSpace, db_session=None -) -> None: - list_of_created_apps = [] +# def init_applications_for_general_manager( +# super_user: Employees, db_session=None +# ) -> None: +# list_of_created_apps = Applications.filter_all_system(db=db_session).data +# if not list_of_created_apps: +# raise Exception("No applications found") + +# for list_of_created_app in list_of_created_apps: +# application_employee_created = Application2Employee.find_or_create( +# employee_id=super_user.id, +# employee_uu_id=str(super_user.uu_id), +# site_url=list_of_created_app.site_url, +# application_code=list_of_created_app.application_code, +# application_id=list_of_created_app.id, +# application_uu_id=str(list_of_created_app.uu_id), +# is_confirmed=True, +# db=db_session, +# ) +# if application_employee_created.meta_data.created: +# application_employee_created.save(db=db_session) -def init_applications_for_owner(super_user: BuildLivingSpace, db_session=None) -> None: - pass + +# def init_applications_for_build_manager( +# super_user: BuildLivingSpace, db_session=None +# ) -> None: +# list_of_created_apps = Applications.filter_all_system(db=db_session).data +# if not list_of_created_apps: +# raise Exception("No applications found") + +# for list_of_created_app in list_of_created_apps: +# application_employee_created = Application2Employee.find_or_create( +# employee_id=super_user.id, +# employee_uu_id=str(super_user.uu_id), +# site_url=list_of_created_app.site_url, +# application_code=list_of_created_app.application_code, +# application_id=list_of_created_app.id, +# application_uu_id=str(list_of_created_app.uu_id), +# is_confirmed=True, +# db=db_session, +# ) +# if application_employee_created.meta_data.created: +# application_employee_created.save(db=db_session) -def init_applications_for_tenant(super_user: BuildLivingSpace, db_session=None) -> None: - list_of_created_apps = [ - dict( - name="Dashboard1", - application_code="app000001", - site_url="/dashboard", - application_type="info", - description="Dashboard Page", - ), - dict( - name="TenantSendMessageToBuildManager", - application_code="app000022", - site_url="/tenant/messageToBM", - application_type="Dash", - description="Individual Page for tenant send message to build manager", - ), - dict( - name="TenantSendMessageToOwner", - application_code="app000018", - site_url="/tenant/messageToOwner", - application_type="Dash", - description="Individual Page for tenant send message to owner", - ), - dict( - name="TenantAccountView", - application_code="app000019", - site_url="/tenant/accounting", - application_type="Dash", - description="Individual Page for tenant account view", - ), - ] +# def init_applications_for_owner(super_user: BuildLivingSpace, db_session=None) -> None: +# list_of_created_apps = Applications.filter_all_system(db=db_session).data +# if not list_of_created_apps: +# raise Exception("No applications found") - for list_of_created_app in list_of_created_apps: - created_page = Applications.find_or_create( - **list_of_created_app, - db=db_session, - is_confirmed=True, - ) - if created_page.meta_data.created: - created_page.save(db=db_session) +# for list_of_created_app in list_of_created_apps: +# application_employee_created = Application2Employee.find_or_create( +# employee_id=super_user.id, +# employee_uu_id=str(super_user.uu_id), +# site_url=list_of_created_app.site_url, +# application_code=list_of_created_app.application_code, +# application_id=list_of_created_app.id, +# application_uu_id=str(list_of_created_app.uu_id), +# is_confirmed=True, +# db=db_session, +# ) +# if application_employee_created.meta_data.created: +# application_employee_created.save(db=db_session) - application_occupant_created = Application2Occupant.find_or_create( - build_living_space_id=super_user.id, - build_living_space_uu_id=str(super_user.uu_id), - site_url=created_page.site_url, - application_code=created_page.application_code, - application_id=created_page.id, - application_uu_id=str(created_page.uu_id), - is_confirmed=True, - db=db_session, - ) - if application_occupant_created.meta_data.created: - application_occupant_created.save(db=db_session) + +# def init_applications_for_tenant(super_user: BuildLivingSpace, db_session=None) -> None: +# list_of_created_apps = Applications.filter_all_system(db=db_session).data +# if not list_of_created_apps: +# raise Exception("No applications found") + +# for list_of_created_app in list_of_created_apps: +# application_employee_created = Application2Employee.find_or_create( +# employee_id=super_user.id, +# employee_uu_id=str(super_user.uu_id), +# site_url=list_of_created_app.site_url, +# application_code=list_of_created_app.application_code, +# application_id=list_of_created_app.id, +# application_uu_id=str(list_of_created_app.uu_id), +# is_confirmed=True, +# db=db_session, +# ) +# if application_employee_created.meta_data.created: +# application_employee_created.save(db=db_session) + +# list_of_created_apps = [ +# dict( +# name="Dashboard1", +# application_code="app000001", +# site_url="/dashboard", +# application_type="info", +# description="Dashboard Page", +# ), +# dict( +# name="TenantSendMessageToBuildManager", +# application_code="app000022", +# site_url="/tenant/messageToBM", +# application_type="Dash", +# description="Individual Page for tenant send message to build manager", +# ), +# dict( +# name="TenantSendMessageToOwner", +# application_code="app000018", +# site_url="/tenant/messageToOwner", +# application_type="Dash", +# description="Individual Page for tenant send message to owner", +# ), +# dict( +# name="TenantAccountView", +# application_code="app000019", +# site_url="/tenant/accounting", +# application_type="Dash", +# description="Individual Page for tenant account view", +# ), +# ] + +# for list_of_created_app in list_of_created_apps: +# created_page = Applications.find_or_create( +# **list_of_created_app, +# db=db_session, +# is_confirmed=True, +# ) +# if created_page.meta_data.created: +# created_page.save(db=db_session) + +# application_occupant_created = Application2Occupant.find_or_create( +# build_living_space_id=super_user.id, +# build_living_space_uu_id=str(super_user.uu_id), +# site_url=created_page.site_url, +# application_code=created_page.application_code, +# application_id=created_page.id, +# application_uu_id=str(created_page.uu_id), +# is_confirmed=True, +# db=db_session, +# ) +# if application_occupant_created.meta_data.created: +# application_occupant_created.save(db=db_session) diff --git a/ApiServices/DealerService/init_service_to_events.py b/ApiServices/DealerService/init_service_to_events.py index e0487bd..df47530 100644 --- a/ApiServices/DealerService/init_service_to_events.py +++ b/ApiServices/DealerService/init_service_to_events.py @@ -11,11 +11,7 @@ from Schemas import ( ) -def init_service_to_event_matches_for_super_user(super_user, db_session=None) -> None: - service_match = Services.filter_one( - Services.service_name == "Super User", - db=db_session, - ).data +def init_service_to_event_matches_for_super_user(service_match: Services, employee_match: Employees, db_session=None) -> None: list_of_all_events = Events.filter_all(db=db_session).data Service2Events.filter_all(db=db_session).query.delete() Service2Events.save(db=db_session) @@ -29,10 +25,9 @@ def init_service_to_event_matches_for_super_user(super_user, db_session=None) -> if service_to_event_found.data: service_to_event_found.destroy(db=db_session) print( - f"UUID: {service_to_event_found.uu_id} event is deleted from {service_match.uu_id}" + f"UUID: {service_to_event_found.uu_id} event is deleted from {service_match.service_description}" ) - - created_service = Service2Events.find_or_create( + added_service = Service2Events.find_or_create( service_id=service_match.id, service_uu_id=str(service_match.uu_id), event_id=list_of_event_code.id, @@ -41,23 +36,22 @@ def init_service_to_event_matches_for_super_user(super_user, db_session=None) -> active=True, db=db_session, ) - if created_service.meta_data.created: - created_service.save(db=db_session) + if added_service.meta_data.created: + added_service.save(db=db_session) print( - f"UUID: {created_service.uu_id} event is saved to {service_match.uu_id}" + f"UUID: {added_service.uu_id} event is saved to {service_match.service_description}" ) - - employee_added_service = Event2Employee.find_or_create( - event_service_id=service_match.id, - event_service_uu_id=str(service_match.uu_id), - employee_id=super_user.id, - employee_uu_id=str(super_user.uu_id), - is_confirmed=True, - db=db_session, + employee_added_service = Event2Employee.find_or_create( + event_service_id=service_match.id, + event_service_uu_id=str(service_match.uu_id), + employee_id=employee_match.id, + employee_uu_id=str(employee_match.uu_id), + is_confirmed=True, + db=db_session, + ) + if employee_added_service.meta_data.created: + employee_added_service.save(db=db_session) + print( + f"UUID: {employee_added_service.uu_id} event is saved to employee {employee_match.uu_id}" ) - if employee_added_service.meta_data.created: - employee_added_service.save(db=db_session) - print( - f"UUID: {employee_added_service.uu_id} event is saved to {super_user.uu_id}" - ) diff --git a/ApiServices/IdentityService/Endpoints/user/route.py b/ApiServices/IdentityService/Endpoints/user/route.py index a9bba73..6a38a4a 100644 --- a/ApiServices/IdentityService/Endpoints/user/route.py +++ b/ApiServices/IdentityService/Endpoints/user/route.py @@ -69,4 +69,4 @@ def user_update_route( event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) FoundCluster = UserRouterCluster.get_event_cluster("UserUpdate") event_cluster_matched = FoundCluster.match_event(event_key=event_key) - return event_cluster_matched.event_callable(data=data) \ No newline at end of file + return event_cluster_matched.event_callable(data=data) diff --git a/ApiServices/ManagementService/Endpoints/application/route.py b/ApiServices/ManagementService/Endpoints/application/route.py index da53240..407b453 100644 --- a/ApiServices/ManagementService/Endpoints/application/route.py +++ b/ApiServices/ManagementService/Endpoints/application/route.py @@ -7,45 +7,113 @@ from ApiControllers.providers.token_provider import TokenProvider from Controllers.Postgres.pagination import PaginateOnly, Pagination, PaginationResult from Controllers.Postgres.response import EndpointResponse, CreateEndpointResponse from Schemas import Applications -from Validations.application.validations import ( - RequestApplication, -) +from Validations.application.validations import RequestApplication +from Events.application.cluster import ApplicationRouterCluster +from Validations.application.validations import AddRemoveService + # Create API router application_route = APIRouter(prefix="/application", tags=["Application Management"]) @application_route.post( - path="/list", - description="List applications endpoint", - operation_id="3189a049-bdb0-49f3-83ff-feb8cb4cb57a", + path="/list/all", + description="List all applications endpoint", + operation_id="fe30481d-802c-4490-897f-a4e95310e6bc", ) -def application_list_route( - list_options: PaginateOnly, +def application_list_all_route( + data: PaginateOnly, headers: CommonHeaders = Depends(CommonHeaders.as_dependency), ): """ - List applications with pagination and filtering options + List all applications with pagination and filtering options """ token_object = TokenProvider.get_dict_from_redis(token=headers.token) - list_options = PaginateOnly(**list_options.model_dump()) - with Applications.new_session() as db_session: - if list_options.query: - applications_list = Applications.filter_all( - *Applications.convert(list_options.query), db=db_session - ) - else: - applications_list = Applications.filter_all(db=db_session) - pagination = Pagination(data=applications_list) - pagination.change(**list_options.model_dump()) - pagination_result = PaginationResult( - data=applications_list, - pagination=pagination, - ) - return EndpointResponse( - message="MSG0003-LIST", - pagination_result=pagination_result, - ).response + event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) + event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) + FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationListAll") + event_cluster_matched = FoundCluster.match_event(event_key=event_key) + return event_cluster_matched.event_callable(list_options=data) + + +@application_route.post( + path="/list/available", + description="List available applications endpoint", + operation_id="7492bb02-a074-4320-b58c-4bc7d9fba3a6", +) +def application_list_available_route( + data: PaginateOnly, + headers: CommonHeaders = Depends(CommonHeaders.as_dependency), +): + """ + List available applications with pagination and filtering options + """ + token_object = TokenProvider.get_dict_from_redis(token=headers.token) + event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) + event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) + FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationListAvailable") + event_cluster_matched = FoundCluster.match_event(event_key=event_key) + return event_cluster_matched.event_callable(list_options=data) + + +@application_route.post( + path="/list/appended", + description="List appended applications endpoint", + operation_id="ea7bbd58-da09-407c-a630-c324e0272385", +) +def application_list_appended_route( + data: PaginateOnly, + headers: CommonHeaders = Depends(CommonHeaders.as_dependency), +): + """ + List appended applications with pagination and filtering options + """ + token_object = TokenProvider.get_dict_from_redis(token=headers.token) + event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) + event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) + FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationListAppended") + event_cluster_matched = FoundCluster.match_event(event_key=event_key) + return event_cluster_matched.event_callable(list_options=data) + + +@application_route.post( + path="/register/service", + description="Register event to service endpoint", + operation_id="92e0870f-f8bb-4879-ba03-c2901cc70ecc", +) +def application_register_service_route( + data: AddRemoveService, + headers: CommonHeaders = Depends(CommonHeaders.as_dependency), +): + """ + Register event to service + """ + token_object = TokenProvider.get_dict_from_redis(token=headers.token) + event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) + event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) + FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationRegisterService") + event_cluster_matched = FoundCluster.match_event(event_key=event_key) + return event_cluster_matched.event_callable(data=data) + + +@application_route.post( + path="/unregister/service", + description="Unregister event from service endpoint", + operation_id="7fa1a183-4c99-4746-b675-148f65ad7ba7", +) +def application_unregister_service_route( + data: AddRemoveService, + headers: CommonHeaders = Depends(CommonHeaders.as_dependency), +): + """ + Unregister event from service + """ + token_object = TokenProvider.get_dict_from_redis(token=headers.token) + event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) + event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) + FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationUnRegisterService") + event_cluster_matched = FoundCluster.match_event(event_key=event_key) + return event_cluster_matched.event_callable(data=data) @application_route.post( @@ -61,26 +129,11 @@ def application_create_route( Create a new application """ token_object = TokenProvider.get_dict_from_redis(token=headers.token) - with Applications.new_session() as db_session: - created_application_dict = data.model_dump() - created_application = Applications.find_or_create( - db=db_session, - include_args=[ - Applications.application_for, - Applications.application_code, - Applications.site_url, - ], - **created_application_dict, - ) - if created_application.meta_data.created: - return CreateEndpointResponse( - message="MSG0001-INSERT", - data=created_application, - ).response - return CreateEndpointResponse( - message="MSG0002-FOUND", - data=created_application, - ).response + event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) + event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) + FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationCreate") + event_cluster_matched = FoundCluster.match_event(event_key=event_key) + return event_cluster_matched.event_callable(data=data) @application_route.post( @@ -97,27 +150,11 @@ def application_update_route( Update an existing application """ token_object = TokenProvider.get_dict_from_redis(token=headers.token) - with Applications.new_session() as db_session: - updated_application_dict = data.model_dump(exclude_unset=True, exclude_none=True) - found_application = Applications.filter_one( - Applications.uu_id == application_uuid, db=db_session - ).data - if not found_application: - return CreateEndpointResponse( - message="MSG0002-FOUND", - data=found_application, - ).response - updated_application = found_application.update(db=db_session,**updated_application_dict) - updated_application.save(db_session) - if updated_application.meta_data.updated: - return CreateEndpointResponse( - message="MSG0003-UPDATE", - data=updated_application, - ).response - return CreateEndpointResponse( - message="MSG0003-UPDATE", - data=updated_application, - ).response + event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) + event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) + FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationUpdate") + event_cluster_matched = FoundCluster.match_event(event_key=event_key) + return event_cluster_matched.event_callable(data=data, uu_id=application_uuid) @application_route.post( @@ -158,4 +195,3 @@ def application_bind_occupant_route( FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationBindOccupant") event_cluster_matched = FoundCluster.match_event(event_key=event_key) return event_cluster_matched.event_callable(data=data) - \ No newline at end of file diff --git a/ApiServices/ManagementService/Endpoints/event_endpoints/route.py b/ApiServices/ManagementService/Endpoints/event_endpoints/route.py index 4de5734..b503a29 100644 --- a/ApiServices/ManagementService/Endpoints/event_endpoints/route.py +++ b/ApiServices/ManagementService/Endpoints/event_endpoints/route.py @@ -5,7 +5,11 @@ from ApiControllers.abstracts.default_validations import CommonHeaders from ApiControllers.providers.token_provider import TokenProvider from Controllers.Postgres.pagination import PaginateOnly, Pagination, PaginationResult from Controllers.Postgres.response import EndpointResponse -from Validations.service_endpoints.validations import Event2Employee, Event2Occupant, AddRemoveService +from Validations.service_endpoints.validations import ( + Event2Employee, + Event2Occupant, + AddRemoveService, +) from Events.event_endpoints.cluster import EventsEndpointRouterCluster # Create API router @@ -50,7 +54,7 @@ def event_list_appended_route( FoundCluster = EventsEndpointRouterCluster.get_event_cluster("EventsListAppended") event_cluster_matched = FoundCluster.match_event(event_key=event_key) return event_cluster_matched.event_callable(list_options=data) - + @event_endpoint_route.post( path="/register/service", @@ -87,7 +91,9 @@ def event_unregister_service_route( token_object = TokenProvider.get_dict_from_redis(token=headers.token) event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) - FoundCluster = EventsEndpointRouterCluster.get_event_cluster("EventUnregisterService") + FoundCluster = EventsEndpointRouterCluster.get_event_cluster( + "EventUnregisterService" + ) event_cluster_matched = FoundCluster.match_event(event_key=event_key) return event_cluster_matched.event_callable(data=data) @@ -107,7 +113,9 @@ def event_bind_employee_extra_route( token_object = TokenProvider.get_dict_from_redis(token=headers.token) event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) - FoundCluster = EventsEndpointRouterCluster.get_event_cluster("EventBindEmployeeExtra") + FoundCluster = EventsEndpointRouterCluster.get_event_cluster( + "EventBindEmployeeExtra" + ) event_cluster_matched = FoundCluster.match_event(event_key=event_key) return event_cluster_matched.event_callable(data=data) @@ -127,6 +135,8 @@ def event_bind_occupant_extra_route( token_object = TokenProvider.get_dict_from_redis(token=headers.token) event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) - FoundCluster = EventsEndpointRouterCluster.get_event_cluster("EventBindOccupantExtra") + FoundCluster = EventsEndpointRouterCluster.get_event_cluster( + "EventBindOccupantExtra" + ) event_cluster_matched = FoundCluster.match_event(event_key=event_key) return event_cluster_matched.event_callable(data=data) diff --git a/ApiServices/ManagementService/Endpoints/routes.py b/ApiServices/ManagementService/Endpoints/routes.py index 8ed511a..95767f8 100644 --- a/ApiServices/ManagementService/Endpoints/routes.py +++ b/ApiServices/ManagementService/Endpoints/routes.py @@ -7,7 +7,12 @@ def get_routes() -> list[APIRouter]: from .service_managements.route import service_management_route from .event_endpoints.route import event_endpoint_route - return [application_route, service_endpoint_route, service_management_route, event_endpoint_route] + return [ + application_route, + service_endpoint_route, + service_management_route, + event_endpoint_route, + ] def get_safe_endpoint_urls() -> list[tuple[str, str]]: diff --git a/ApiServices/ManagementService/Events/__init__.py b/ApiServices/ManagementService/Events/__init__.py index dec62dd..1c78a52 100644 --- a/ApiServices/ManagementService/Events/__init__.py +++ b/ApiServices/ManagementService/Events/__init__.py @@ -2,4 +2,8 @@ from .service_endpoints.cluster import ServiceEndpointRouterCluster from .event_endpoints.cluster import EventsEndpointRouterCluster from .application.cluster import ApplicationRouterCluster -__all__ = ["ServiceEndpointRouterCluster", "EventsEndpointRouterCluster", "ApplicationRouterCluster"] +__all__ = [ + "ServiceEndpointRouterCluster", + "EventsEndpointRouterCluster", + "ApplicationRouterCluster", +] diff --git a/ApiServices/ManagementService/Events/application/cluster.py b/ApiServices/ManagementService/Events/application/cluster.py index f247ea7..eb8bdf9 100644 --- a/ApiServices/ManagementService/Events/application/cluster.py +++ b/ApiServices/ManagementService/Events/application/cluster.py @@ -1,18 +1,40 @@ from ApiControllers.abstracts.event_clusters import EventCluster, RouterCluster from .supers_events import ( - ApplicationListEvent, + ApplicationListAllEvent, + ApplicationListAvailableEvent, + ApplicationListAppendedEvent, + ApplicationRegisterServiceEvent, + ApplicationUnRegisterServiceEvent, ApplicationCreateEvent, ApplicationUpdateEvent, - ApplicationBindEmployeeEvent, - ApplicationBindOccupantEvent, ) ApplicationRouterCluster = RouterCluster(name="ApplicationRouterCluster") -ApplicationEventClusterList = EventCluster( - name="ApplicationList", endpoint_uu_id="3189a049-bdb0-49f3-83ff-feb8cb4cb57a" +ApplicationEventClusterListAll = EventCluster( + name="ApplicationListAll", endpoint_uu_id="fe30481d-802c-4490-897f-a4e95310e6bc" ) -ApplicationEventClusterList.add_event(ApplicationListEvent) +ApplicationEventClusterListAll.add_event(ApplicationListAllEvent) + +ApplicationEventClusterListAvailable = EventCluster( + name="ApplicationListAvailable", endpoint_uu_id="7492bb02-a074-4320-b58c-4bc7d9fba3a6" +) +ApplicationEventClusterListAvailable.add_event(ApplicationListAvailableEvent) + +ApplicationEventClusterListAppended = EventCluster( + name="ApplicationListAppended", endpoint_uu_id="ea7bbd58-da09-407c-a630-c324e0272385" +) +ApplicationEventClusterListAppended.add_event(ApplicationListAppendedEvent) + +ApplicationEventClusterRegisterService = EventCluster( + name="ApplicationRegisterService", endpoint_uu_id="92e0870f-f8bb-4879-ba03-c2901cc70ecc" +) +ApplicationEventClusterRegisterService.add_event(ApplicationRegisterServiceEvent) + +ApplicationEventClusterUnregisterService = EventCluster( + name="ApplicationUnRegisterService", endpoint_uu_id="7fa1a183-4c99-4746-b675-148f65ad7ba7" +) +ApplicationEventClusterUnregisterService.add_event(ApplicationUnRegisterServiceEvent) ApplicationEventClusterCreate = EventCluster( name="ApplicationCreate", endpoint_uu_id="5570be78-030a-438e-8674-7e751447608b" @@ -24,18 +46,10 @@ ApplicationEventClusterUpdate = EventCluster( ) ApplicationEventClusterUpdate.add_event(ApplicationUpdateEvent) -ApplicationEventClusterBindEmployee = EventCluster( - name="ApplicationBindEmployee", endpoint_uu_id="2bab94fa-becb-4d8e-80f1-f4631119a521" -) -ApplicationEventClusterBindEmployee.add_event(ApplicationBindEmployeeEvent) - -ApplicationEventClusterBindOccupant = EventCluster( - name="ApplicationBindOccupant", endpoint_uu_id="fccf1a59-0650-4e5c-ba8d-f389dadce01c" -) -ApplicationEventClusterBindOccupant.add_event(ApplicationBindOccupantEvent) - -ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterList) +ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterListAvailable) +ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterListAppended) +ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterListAll) +ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterRegisterService) +ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterUnregisterService) ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterCreate) ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterUpdate) -ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterBindEmployee) -ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterBindOccupant) diff --git a/ApiServices/ManagementService/Events/application/supers_events.py b/ApiServices/ManagementService/Events/application/supers_events.py index 0f2e025..dd6d668 100644 --- a/ApiServices/ManagementService/Events/application/supers_events.py +++ b/ApiServices/ManagementService/Events/application/supers_events.py @@ -1,3 +1,5 @@ +from typing import Any + from ApiControllers.abstracts.event_clusters import Event from Controllers.Postgres.pagination import Pagination, PaginationResult, PaginateOnly from Controllers.Postgres.response import EndpointResponse @@ -5,16 +7,53 @@ from Schemas import ( Applications, Application2Employee, Application2Occupant, + Service2Application, + Services, ) - -# List endpoint -ApplicationListEvent = Event( - name="application_list", - key="b4efda1e-bde7-4659-ab1a-ef74c0fd88b6", +# List all endpoint +ApplicationListAllEvent = Event( + name="application_list_all", + key="1971ce4d-4f59-4aa8-83e2-ca19d7da6d11", request_validator=None, # TODO: Add request validator response_validator=None, # TODO: Add response validator - description="Super Users List applications endpoint", + description="Super Users List all applications endpoint", +) + +# List available endpoint +ApplicationListAvailableEvent = Event( + name="application_list_available", + key="d8e733f5-b53a-4c36-9082-12579bf9cc4a", + request_validator=None, # TODO: Add request validator + response_validator=None, # TODO: Add response validator + description="Super Users List available applications endpoint", +) + +# List appended endpoint +ApplicationListAppendedEvent = Event( + name="application_list_appended", + key="ea7bbd58-da09-407c-a630-c324e0272385", + request_validator=None, # TODO: Add request validator + response_validator=None, # TODO: Add response validator + description="Super Users List appended applications endpoint", +) + +# Register application to service endpoint +ApplicationRegisterServiceEvent = Event( + name="application_register_service", + key="47d7cfc8-6004-4442-8357-16ceac5d9d18", + request_validator=None, # TODO: Add request validator + response_validator=None, # TODO: Add response validator + description="Super Users Register application to service endpoint", +) + +# Unregister application to service endpoint +ApplicationUnRegisterServiceEvent = Event( + name="application_unregister_service", + key="d228ab26-0b74-440f-8f1f-8f40be5a22f2", + request_validator=None, # TODO: Add request validator + response_validator=None, # TODO: Add response validator + description="Super Users Unregister application to service endpoint", ) # Create endpoint @@ -35,114 +74,247 @@ ApplicationUpdateEvent = Event( description="Super Users Update applications endpoint", ) - #Bind Application to employee -ApplicationBindEmployeeEvent = Event( - name="application_bind_employee", - key="26a96c2d-bca8-41cb-8ac1-f3ca8124434b", - request_validator=None, # TODO: Add request validator - response_validator=None, # TODO: Add response validator - description="Super Users Application Bind employee endpoint", -) -#Bind Application to occupant -ApplicationBindOccupantEvent = Event( - name="application_bind_occupant", - key="4eaf2bb0-2a42-4d21-ae65-a9259ebee189", - request_validator=None, # TODO: Add request validator - response_validator=None, # TODO: Add response validator - description="Super Users Application Bind occupant endpoint", -) - - -def application_list_callable(list_options: PaginateOnly): - """ - Example callable method - """ +def application_list_all_callable(list_options: PaginateOnly): list_options = PaginateOnly(**list_options.model_dump()) with Applications.new_session() as db_session: if list_options.query: - applications_list = Applications.filter_all( - *Applications.convert(list_options.query), db=db_session - ) + applications_list = Applications.filter_all(*Applications.convert(list_options.query), db=db_session) else: applications_list = Applications.filter_all(db=db_session) pagination = Pagination(data=applications_list) pagination.change(**list_options.model_dump()) - pagination_result = PaginationResult( - data=applications_list, - pagination=pagination, - # response_model="", - ) - return EndpointResponse( - message="MSG0003-LIST", - pagination_result=pagination_result, - ).response + pagination_result = PaginationResult(data=applications_list, pagination=pagination) + return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response -ApplicationListEvent.event_callable = application_list_callable +ApplicationListAllEvent.event_callable = application_list_all_callable -def application_create_callable(): +def application_list_available_callable(list_options: PaginateOnly): """ Example callable method """ - return { - "completed": True, - "message": "Example callable method 2", - "info": { - "host": "example_host", - "user_agent": "example_user_agent", - }, - } + list_options = PaginateOnly(**list_options.model_dump()) + service_uu_id = list_options.query.get("service_uu_id__ilike", None) + if not service_uu_id: + return { + "message": "MSG0003-PARAM-MISSING", + "data": list_options.query, + "completed": False, + } + list_options.query.pop("service_uu_id__ilike", None) + list_options.query.pop("service_uu_id", None) + with Applications.new_session() as db_session: + service2applications = Service2Application.filter_all( + *Service2Application.convert({"service_uu_id__ilike": service_uu_id}), + db=db_session, + ) + already_events = [ + service_to_application.application_id for service_to_application in service2applications.data + ] + if list_options.query: + applications_list = Applications.filter_all( + *Applications.convert(list_options.query), Applications.id.not_in(already_events), db=db_session + ) + else: + applications_list = Applications.filter_all(Applications.id.not_in(already_events), db=db_session) + pagination = Pagination(data=applications_list) + pagination.change(**list_options.model_dump()) + pagination_result = PaginationResult(data=applications_list, pagination=pagination) + return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response + + +ApplicationListAvailableEvent.event_callable = application_list_available_callable + + +def application_list_appended_callable(list_options: PaginateOnly): + """ + Example callable method + """ + list_options = PaginateOnly(**list_options.model_dump()) + service_uu_id = list_options.query.get("service_uu_id__ilike", None) + if not service_uu_id: + return { + "message": "MSG0003-PARAM-MISSING", + "data": list_options.query, + "completed": False, + } + list_options.query.pop("service_uu_id__ilike", None) + list_options.query.pop("service_uu_id", None) + + with Applications.new_session() as db_session: + service2applications = Service2Application.filter_all( + *Service2Application.convert({"service_uu_id__ilike": service_uu_id}), + db=db_session, + ) + already_events = [ + service_to_application.application_id for service_to_application in service2applications.data + ] + if list_options.query: + applications_list = Applications.filter_all( + *Applications.convert(list_options.query), Applications.id.in_(already_events), db=db_session + ) + else: + applications_list = Applications.filter_all(Applications.id.in_(already_events), db=db_session) + pagination = Pagination(data=applications_list) + pagination.change(**list_options.model_dump()) + pagination_result = PaginationResult(data=applications_list, pagination=pagination) + return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response + + +ApplicationListAppendedEvent.event_callable = application_list_appended_callable + + +def application_create_callable(data: Any): + """ + Create a new application + """ + with Applications.new_session() as db_session: + created_application_dict = data.model_dump() + created_application = Applications.find_or_create( + db=db_session, + include_args=[Applications.application_for, Applications.application_code, Applications.site_url], + **created_application_dict, + ) + if created_application.meta_data.created: + created_application.save(db=db_session) + return { + "completed": True, + "message": "MSG0001-INSERT", + "data": created_application, + } + return { + "completed": False, + "message": "MSG0002-ERROR", + "data": created_application, + } ApplicationCreateEvent.event_callable = application_create_callable -def application_update_callable(): +def application_update_callable(data: Any, uu_id: str): """ - Example callable method + Update an existing application """ - return { - "completed": True, - "message": "Example callable method 2", - "info": { - "host": "example_host", - "user_agent": "example_user_agent", - }, - } + with Applications.new_session() as db_session: + updated_application_dict = data.model_dump( + exclude_unset=True, exclude_none=True + ) + found_application = Applications.filter_one( + Applications.uu_id == uu_id, db=db_session + ).data + if not found_application: + return { + "completed": False, + "message": "MSG0002-FOUND", + "data": found_application, + } + updated_application = found_application.update( + db=db_session, **updated_application_dict + ) + updated_application.save(db_session) + if updated_application.meta_data.updated: + return { + "completed": True, + "message": "MSG0003-UPDATE", + "data": updated_application, + } + return { + "completed": False, + "message": "MSG0003-UPDATE", + "data": updated_application, + } ApplicationUpdateEvent.event_callable = application_update_callable -def application_bind_employee_callable(): +def application_register_service_callable(data: Any): """ - Example callable method + Register an application to a service """ + with Applications.new_session() as db_session: + event = Applications.filter_one_system(Applications.uu_id == data.application_uu_id, db=db_session) + if not event.data: + return { + "message": "MSG0003-NOT-FOUND", + "data": data.model_dump(), + "completed": False, + } + service = Services.filter_one_system(Services.uu_id == data.service_uu_id, db=db_session) + if not service.data: + return { + "message": "MSG0003-NOT-FOUND", + "data": data.model_dump(), + "completed": False, + } + service_to_application = Service2Application.find_or_create( + db=db_session, + include_args=[Service2Application.service_uu_id, Service2Application.application_uu_id], + service_id=service.data.id, + service_uu_id=str(service.data.uu_id), + application_id=event.data.id, + application_uu_id=str(event.data.uu_id), + application_code=event.data.application_code, + site_url=event.data.site_url, + is_confirmed=True, + ) + if not service_to_application.meta_data.created: + return { + "message": "MSG0003-ALREADY-FOUND", + "data": data.model_dump(), + "completed": False, + } + service_to_application.save(db=db_session) return { + "message": "MSG0003-REGISTER", + "data": data.model_dump(), "completed": True, - "message": "Example callable method 2", - "info": { - "host": "example_host", - "user_agent": "example_user_agent", - }, } -ApplicationBindEmployeeEvent.event_callable = application_bind_employee_callable + +ApplicationRegisterServiceEvent.event_callable = application_register_service_callable -def application_bind_occupant_callable(): +def application_unregister_service_callable(data: Any): """ - Example callable method + Unregister an application from a service """ + with Applications.new_session() as db_session: + application = Applications.filter_one_system(Applications.uu_id == data.application_uu_id, db=db_session) + if not application.data: + return { + "message": "MSG0003-NOT-FOUND", + "data": data.model_dump(), + "completed": False, + } + service = Services.filter_one_system(Services.uu_id == data.service_uu_id, db=db_session) + if not service.data: + return { + "message": "MSG0003-NOT-FOUND", + "data": data.model_dump(), + "completed": False, + } + service_to_application = Service2Application.filter_one_system( + Service2Application.service_id == service.data.id, + Service2Application.application_id == application.data.id, + db=db_session, + ) + if not service_to_application.data: + return { + "message": "MSG0003-NOT-FOUND", + "data": data.model_dump(), + "completed": False, + } + service_to_application.query.delete() + db_session.commit() return { + "message": "MSG0003-UNREGISTER", + "data": data.model_dump(), "completed": True, - "message": "Example callable method 2", - "info": { - "host": "example_host", - "user_agent": "example_user_agent", - }, } -ApplicationBindOccupantEvent.event_callable = application_bind_occupant_callable + +ApplicationUnRegisterServiceEvent.event_callable = application_unregister_service_callable diff --git a/ApiServices/ManagementService/Events/event_endpoints/cluster.py b/ApiServices/ManagementService/Events/event_endpoints/cluster.py index d978369..e741c8b 100644 --- a/ApiServices/ManagementService/Events/event_endpoints/cluster.py +++ b/ApiServices/ManagementService/Events/event_endpoints/cluster.py @@ -43,6 +43,12 @@ EventsEndpointEventClusterBindOccupantExtra.add_event(EventBindOccupantExtraEven EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterListAvailable) EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterListAppended) EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterRegisterService) -EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterUnregisterService) -EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterBindEmployeeExtra) -EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterBindOccupantExtra) +EventsEndpointRouterCluster.set_event_cluster( + EventsEndpointEventClusterUnregisterService +) +EventsEndpointRouterCluster.set_event_cluster( + EventsEndpointEventClusterBindEmployeeExtra +) +EventsEndpointRouterCluster.set_event_cluster( + EventsEndpointEventClusterBindOccupantExtra +) diff --git a/ApiServices/ManagementService/Events/event_endpoints/supers_events.py b/ApiServices/ManagementService/Events/event_endpoints/supers_events.py index 5cce2d1..1cec7e6 100644 --- a/ApiServices/ManagementService/Events/event_endpoints/supers_events.py +++ b/ApiServices/ManagementService/Events/event_endpoints/supers_events.py @@ -72,22 +72,33 @@ def events_list_available_callable(list_options: PaginateOnly): List available events with pagination and filtering options """ list_options = PaginateOnly(**list_options.model_dump()) - service_uu_id = list_options.query.get('service_uu_id__ilike', None) + service_uu_id = list_options.query.get("service_uu_id__ilike", None) if not service_uu_id: return { "message": "MSG0003-PARAM-MISSING", "data": list_options.query, "completed": False, } + list_options.query.pop("service_uu_id__ilike", None) + list_options.query.pop("service_uu_id", None) with Events.new_session() as db_session: - service2events = Service2Events.filter_all(*Service2Events.convert(list_options.query), db=db_session) - already_events = [service_to_event.event_id for service_to_event in service2events.data] - list_options.query.pop('service_uu_id__ilike', None) - list_options.query.pop('service_uu_id', None) + service2events = Service2Events.filter_all( + *Service2Events.convert({"service_uu_id__ilike": service_uu_id}), + db=db_session, + ) + already_events = [ + service_to_event.event_id for service_to_event in service2events.data + ] if list_options.query: - events_list = Events.filter_all(*Events.convert(list_options.query), Events.id.not_in(already_events), db=db_session) + events_list = Events.filter_all( + *Events.convert(list_options.query), + Events.id.not_in(already_events), + db=db_session, + ) else: - events_list = Events.filter_all(Events.id.not_in(already_events), db=db_session) + events_list = Events.filter_all( + Events.id.not_in(already_events), db=db_session + ) pagination = Pagination(data=events_list) pagination.change(**list_options.model_dump()) pagination_result = PaginationResult(data=events_list, pagination=pagination) @@ -105,22 +116,34 @@ def events_list_appended_callable(list_options: PaginateOnly): List appended events with pagination and filtering options """ list_options = PaginateOnly(**list_options.model_dump()) - service_uu_id = list_options.query.get('service_uu_id__ilike', None) + service_uu_id = list_options.query.get("service_uu_id__ilike", None) if not service_uu_id: return { "message": "MSG0003-PARAM-MISSING", "data": list_options.query, "completed": False, } + list_options.query.pop("service_uu_id__ilike", None) + list_options.query.pop("service_uu_id", None) with Events.new_session() as db_session: - service2events = Service2Events.filter_all(*Service2Events.convert(list_options.query), db=db_session) - already_events = [service_to_event.event_id for service_to_event in service2events.data] - list_options.query.pop('service_uu_id__ilike', None) - list_options.query.pop('service_uu_id', None) + service2events = Service2Events.filter_all( + *Service2Events.convert({"service_uu_id__ilike": service_uu_id}), + db=db_session, + ) + already_events = [ + service_to_event.event_id for service_to_event in service2events.data + ] + if list_options.query: - events_list = Events.filter_all(*Events.convert(list_options.query), Events.id.in_(already_events), db=db_session) + events_list = Events.filter_all( + *Events.convert(list_options.query), + Events.id.in_(already_events), + db=db_session, + ) else: - events_list = Events.filter_all(Events.id.in_(already_events), db=db_session) + events_list = Events.filter_all( + Events.id.in_(already_events), db=db_session + ) pagination = Pagination(data=events_list) pagination.change(**list_options.model_dump()) pagination_result = PaginationResult(data=events_list, pagination=pagination) @@ -139,10 +162,9 @@ def event_register_service_callable(data: Any): """ with Events.new_session() as db_session: event = Events.filter_one_system( - Events.uu_id == data.event_uu_id, - db=db_session + Events.uu_id == data.event_uu_id, db=db_session ) - print('event', event.data) + print("event", event.data) if not event.data: return { "message": "MSG0003-NOT-FOUND", @@ -150,10 +172,9 @@ def event_register_service_callable(data: Any): "completed": False, } service = Services.filter_one_system( - Services.uu_id == data.service_uu_id, - db=db_session + Services.uu_id == data.service_uu_id, db=db_session ) - print('service', service.data) + print("service", service.data) if not service.data: return { "message": "MSG0003-NOT-FOUND", @@ -169,10 +190,10 @@ def event_register_service_callable(data: Any): service_id=service.data.id, event_id=event.data.id, is_confirmed=True, - service_uu_id=str(service.data.uu_id), + service_uu_id=str(service.data.uu_id), event_uu_id=str(event.data.uu_id), ) - print('service_to_event', service_to_event) + print("service_to_event", service_to_event) if not service_to_event.meta_data.created: return { "message": "MSG0003-ALREADY-FOUND", @@ -214,8 +235,8 @@ def event_unregister_service_callable(data: Any): "completed": False, } service_to_event = Service2Events.filter_one_system( - Service2Events.service_id==service.data.id, - Service2Events.event_id==event.data.id, + Service2Events.service_id == service.data.id, + Service2Events.event_id == event.data.id, db=db_session, ) if not service_to_event.data: diff --git a/ApiServices/ManagementService/Events/service_endpoints/supers_events.py b/ApiServices/ManagementService/Events/service_endpoints/supers_events.py index 31b101c..aa8734c 100644 --- a/ApiServices/ManagementService/Events/service_endpoints/supers_events.py +++ b/ApiServices/ManagementService/Events/service_endpoints/supers_events.py @@ -21,13 +21,17 @@ def service_endpoint_list_callable(data: PaginateOnly): list_options = PaginateOnly(**data.model_dump()) with Services.new_session() as db_session: if data.query: - services_list = Services.filter_all_system(*Services.convert(data.query), db=db_session) + services_list = Services.filter_all_system( + *Services.convert(data.query), db=db_session + ) else: services_list = Services.filter_all_system(db=db_session) pagination = Pagination(data=services_list) pagination.change(**data.model_dump()) pagination_result = PaginationResult(data=services_list, pagination=pagination) - return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response + return EndpointResponse( + message="MSG0003-LIST", pagination_result=pagination_result + ).response ServiceEndpointListEvent.event_callable = service_endpoint_list_callable @@ -49,13 +53,17 @@ def service_endpoint_to_events_callable(data: PaginateOnly): list_options = PaginateOnly(**data.model_dump()) with Service2Events.new_session() as db_session: if data.query: - services_list = Service2Events.filter_all_system(*Service2Events.convert(data.query), db=db_session) + services_list = Service2Events.filter_all_system( + *Service2Events.convert(data.query), db=db_session + ) else: services_list = Service2Events.filter_all_system(db=db_session) pagination = Pagination(data=services_list) pagination.change(**data.model_dump()) pagination_result = PaginationResult(data=services_list, pagination=pagination) - return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response + return EndpointResponse( + message="MSG0003-LIST", pagination_result=pagination_result + ).response ServiceEndpointToEventsEvent.event_callable = service_endpoint_to_events_callable diff --git a/ApiServices/ManagementService/Validations/application/validations.py b/ApiServices/ManagementService/Validations/application/validations.py index 2169ea7..2cd8fdc 100644 --- a/ApiServices/ManagementService/Validations/application/validations.py +++ b/ApiServices/ManagementService/Validations/application/validations.py @@ -13,3 +13,10 @@ class RequestApplication(BaseModel): ) application_for: str = Field(..., description="Application for (EMP, OCC)") description: Optional[str] = Field(None, description="Application description") + + +class AddRemoveService(BaseModel): + """Base model for add/remove service data""" + + application_uu_id: str = Field(..., description="Application UUID") + service_uu_id: str = Field(..., description="Service UUID") diff --git a/ApiServices/ManagementService/Validations/service_endpoints/validations.py b/ApiServices/ManagementService/Validations/service_endpoints/validations.py index 0a15f28..c7fb0ac 100644 --- a/ApiServices/ManagementService/Validations/service_endpoints/validations.py +++ b/ApiServices/ManagementService/Validations/service_endpoints/validations.py @@ -1,5 +1,6 @@ from pydantic import BaseModel + class Event2Employee(BaseModel): pass diff --git a/BankServices/RoutineEmailService/app.py b/BankServices/RoutineEmailService/app.py index c4b5822..9aabf8f 100644 --- a/BankServices/RoutineEmailService/app.py +++ b/BankServices/RoutineEmailService/app.py @@ -108,7 +108,9 @@ def set_account_records_to_send_email() -> bool: balance_error = expected_second_balance != second_record.bank_balance if balance_error: - print(f"Balance error detected {expected_second_balance} != {second_record.bank_balance}") + print( + f"Balance error detected {expected_second_balance} != {second_record.bank_balance}" + ) # Format rows for the email template list_of_rows = [] diff --git a/Schemas/__init__.py b/Schemas/__init__.py index 3efeccb..a69a36c 100644 --- a/Schemas/__init__.py +++ b/Schemas/__init__.py @@ -75,6 +75,7 @@ from Schemas.event.event import ( Modules, Services, Service2Events, + Service2Application, Events, Event2Occupant, Event2Employee, @@ -83,6 +84,8 @@ from Schemas.event.event import ( Applications, Application2Employee, Application2Occupant, + Application2EmployeeExtra, + Application2OccupantExtra, ) from Schemas.identity.identity import ( UsersTokens, diff --git a/Schemas/event/event.py b/Schemas/event/event.py index 1ad847c..da95ebe 100644 --- a/Schemas/event/event.py +++ b/Schemas/event/event.py @@ -27,7 +27,9 @@ class Applications(CrudCollection): String, nullable=False, comment="Application Code" ) application_type: Mapped[str] = mapped_column(String, comment="Application Type") - application_for: Mapped[str] = mapped_column(String, server_default="EMP", comment="Application For") + application_for: Mapped[str] = mapped_column( + String, server_default="EMP", comment="Application For" + ) description: Mapped[str] = mapped_column(String, comment="Application Description") @@ -199,8 +201,30 @@ class Service2Events(CrudCollection): __table_args__ = ({"comment": "Service2Events Information"},) -# class Service2Application(CrudCollection): -# pass +class Service2Application(CrudCollection): + """ + Service2Application class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "services2applications" + __exclude__fields__ = [] + + application_id: Mapped[int] = mapped_column( + ForeignKey("applications.id"), nullable=False + ) + application_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Application UUID" + ) + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Service UUID" + ) + application_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Application Code" + ) + site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") + + __table_args__ = {"comment": "Service2Applications Information"} class Event2OccupantExtra(CrudCollection): @@ -295,17 +319,14 @@ class Event2Employee(CrudCollection): db=db, ).data service_ids = list(set([event.event_service_id for event in employee_events])) - print("service_ids", service_ids) active_event_ids = Service2Events.filter_all( Service2Events.service_id.in_(service_ids), db=db, ).data - print("active_event_ids", active_event_ids) active_events = Events.filter_all( Events.id.in_([event.event_id for event in active_event_ids]), db=db, ).data - print("active_events", active_events) if extra_events := Event2EmployeeExtra.filter_all( Event2EmployeeExtra.employee_id == employee_id, db=db, @@ -321,7 +342,6 @@ class Event2Employee(CrudCollection): events_dict[str(event.endpoint_code)] = str(event.function_code) else: ValueError("Duplicate event code found for single endpoint") - print("events_dict", events_dict) return events_dict @@ -400,45 +420,54 @@ class Application2Employee(CrudCollection): __exclude__fields__ = [] employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) - employee_uu_id: Mapped[str] = mapped_column( - String, nullable=False, comment="Employee UUID" - ) - - application_id: Mapped[int] = mapped_column(ForeignKey("applications.id")) - application_uu_id: Mapped[str] = mapped_column( - String, nullable=False, comment="Application UUID" - ) - - site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") - application_code: Mapped[str] = mapped_column( - String, nullable=False, comment="Application Code" - ) + employee_uu_id = mapped_column(String, nullable=False, comment="Employee UUID") + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id = mapped_column(String, nullable=False, comment="Service UUID") @classmethod - def get_application_codes(cls, employee_id: int, db) -> dict[str, str]: - print("employee_id", employee_id) - employee_applications = cls.filter_all( - Application2Employee.employee_id == employee_id, + def get_application_codes(cls, employee_id: int, db) -> list[int]: + employee_services = cls.filter_all( + cls.employee_id == employee_id, db=db, ).data + service_ids = [service.service_id for service in employee_services] + active_applications = Service2Application.filter_all( + Service2Application.service_id.in_(service_ids), + db=db, + ).data + applications = Applications.filter_all( + Applications.id.in_( + [application.application_id for application in active_applications] + ), + db=db, + ).data + if extra_applications := Application2EmployeeExtra.filter_all( + Application2EmployeeExtra.employee_id == employee_id, + db=db, + ).data: + applications_extra = Applications.filter_all( + Applications.id.in_( + [application.application_id for application in extra_applications] + ), + db=db, + ).data + applications.extend(applications_extra) applications_dict = {} - print("employee_applications", employee_applications) - for employee_application in employee_applications: - if employee_application.site_url not in applications_dict: - applications_dict[str(employee_application.site_url)] = str( - employee_application.application_code - ) + for application in applications: + if not application.site_url in applications_dict: + applications_dict[str(application.site_url)] = str(application.application_code) + else: + ValueError("Duplicate application code found for single endpoint") return applications_dict __table_args__ = ( Index( - "application_to_employee", - employee_id, - site_url, - application_id, + "application2employee_employee_to_service", + employee_uu_id, + service_uu_id, unique=True, ), - {"comment": "Application2Employee Information"}, + {"comment": "Application to Employee Information"}, ) @@ -453,33 +482,114 @@ class Application2Occupant(CrudCollection): build_living_space_id: Mapped[int] = mapped_column( ForeignKey("build_living_space.id"), nullable=False ) - build_living_space_uu_id: Mapped[str] = mapped_column( + build_living_space_uu_id = mapped_column( String, nullable=False, comment="Build Living Space UUID" ) + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id = mapped_column(String, nullable=False, comment="Service UUID") + @classmethod + def get_application_codes(cls, build_living_space_id: int, db) -> list[int]: + occupant_services = cls.filter_all( + cls.build_living_space_id == build_living_space_id, + db=db, + ).data + service_ids = [service.service_id for service in occupant_services] + active_applications = Service2Application.filter_all( + Service2Application.service_id.in_(service_ids), + db=db, + ).data + applications = Applications.filter_all( + Applications.id.in_( + [application.application_id for application in active_applications] + ), + db=db, + ).data + if extra_applications := Application2OccupantExtra.filter_all( + Application2OccupantExtra.build_living_space_id == build_living_space_id, + db=db, + ).data: + applications_extra = Applications.filter_all( + Applications.id.in_( + [application.application_id for application in extra_applications] + ), + db=db, + ).data + applications.extend(applications_extra) + applications_dict = {} + for application in applications: + if not application.site_url in applications_dict: + applications_dict[str(application.site_url)] = str(application.application_code) + else: + ValueError("Duplicate application code found for single endpoint") + return applications_dict + + __table_args__ = ( + Index( + "application2occupant_occupant_to_service", + build_living_space_uu_id, + service_uu_id, + unique=True, + ), + {"comment": "Application to Occupant Information"}, + ) + + +class Application2EmployeeExtra(CrudCollection): + """ + Application2EmployeeExtra class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "application2employee_extra" + __exclude__fields__ = [] + + employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) + employee_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Employee UUID" + ) application_id: Mapped[int] = mapped_column(ForeignKey("applications.id")) application_uu_id: Mapped[str] = mapped_column( String, nullable=False, comment="Application UUID" ) - site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") application_code: Mapped[str] = mapped_column( String, nullable=False, comment="Application Code" ) - @classmethod - def get_application_codes(cls, build_living_space_id: int, db) -> dict[str, str]: - occupant_applications = cls.filter_all( - cls.build_living_space_id == build_living_space_id, - db=db, - ).data - applications_dict = {} - for occupant_application in occupant_applications: - if occupant_application.site_url not in applications_dict: - applications_dict[str(occupant_application.site_url)] = str( - occupant_application.application_code - ) - return applications_dict + __table_args__ = ( + Index( + "application_to_employee", + employee_id, + site_url, + application_id, + unique=True, + ), + {"comment": "Application2Employee Information"}, + ) + + +class Application2OccupantExtra(CrudCollection): + """ + Application2OccupantExtra class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "application2occupant_extra" + __exclude__fields__ = [] + + build_living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), nullable=False + ) + build_living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Build Living Space UUID" + ) + application_id: Mapped[int] = mapped_column(ForeignKey("applications.id")) + application_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Application UUID" + ) + site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") + application_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Application Code" + ) __table_args__ = ( Index( diff --git a/WebServices/management-frontend/src/apicalls/application/endpoints.tsx b/WebServices/management-frontend/src/apicalls/application/endpoints.tsx index 1a2e8ea..250aee5 100644 --- a/WebServices/management-frontend/src/apicalls/application/endpoints.tsx +++ b/WebServices/management-frontend/src/apicalls/application/endpoints.tsx @@ -1,87 +1,198 @@ "use server"; - import { fetchDataWithToken } from "../api-fetcher"; import { baseUrlApplication } from "../basics"; import { PaginationParams } from "../schemas/list"; -import type { PaginatedApiResponse } from "@/app/api/utils/types"; +import { + collectPaginationFromApiResponse, + defaultPaginationResponse, + type PaginatedApiResponse +} from "@/app/api/utils/types"; + +const applicationListEndpoint = `${baseUrlApplication}/application/list/all`; +const applicationListAvailableEndpoint = `${baseUrlApplication}/application/list/available`; +const applicationListAppendedEndpoint = `${baseUrlApplication}/application/list/appended`; +const applicationRegisterServiceEndpoint = `${baseUrlApplication}/application/register/service`; +const applicationUnregisterServiceEndpoint = `${baseUrlApplication}/application/unregister/service`; -const applicationListEndpoint = `${baseUrlApplication}/application/list`; const applicationUpdateEndpoint = `${baseUrlApplication}/application/update`; const applicationCreateEndpoint = `${baseUrlApplication}/application/create`; const applicationDeleteEndpoint = `${baseUrlApplication}/application/delete`; +interface AppendApplicationToService { + application_uu_id: string; + service_uu_id: string; +} + +interface RemoveApplicationFromService extends AppendApplicationToService { } + + +async function listApplicationsAvailable(payload: PaginationParams): Promise> { + if (!payload.query.service_uu_id__ilike) { + console.warn('Missing service_uu_id in query parameters'); + return { + data: [], + pagination: defaultPaginationResponse, + }; + } -async function listApplications(payload: PaginationParams): Promise> { try { + const requestBody = { + page: payload.page, + size: payload.size, + order_field: payload.orderField, + order_type: payload.orderType, + query: payload.query, + }; + + console.log('Sending request to backend with service_uu_id:', payload.query.service_uu_id); + console.log('Full request body:', JSON.stringify(requestBody, null, 2)); + const response = await fetchDataWithToken( - applicationListEndpoint, - { - page: payload.page, - size: payload.size, - order_field: payload.orderField, - order_type: payload.orderType, - query: payload.query, - }, + applicationListAvailableEndpoint, + requestBody, "POST", false ); if (response?.status === 200 || response?.status === 202) { - const responseData = response.data as any; + const responseData = response.data as PaginatedApiResponse; + console.log('list_events_available responseData:', JSON.stringify(responseData, null, 2)); return { data: responseData.data || [], - pagination: { - page: responseData.pagination?.page || 1, - size: responseData.pagination?.size || 10, - totalCount: responseData.pagination?.totalCount || 0, - totalItems: responseData.pagination?.totalItems || 0, - totalPages: responseData.pagination?.totalPages || 0, - pageCount: responseData.pagination?.pageCount || 0, - orderField: responseData.pagination?.orderField || ['name'], - orderType: responseData.pagination?.orderType || ['asc'], - query: responseData.pagination?.query || {}, - next: responseData.pagination?.next || false, - back: responseData.pagination?.back || false - } + pagination: collectPaginationFromApiResponse(responseData) }; } return { data: [], - pagination: { - page: 1, - size: 10, - totalCount: 0, - totalItems: 0, - totalPages: 0, - pageCount: 0, - orderField: ['name'], - orderType: ['asc'], - query: {}, - next: false, - back: false - } + pagination: defaultPaginationResponse, }; } catch (error) { - console.error("Error fetching application list:", error); + console.error("Error fetching events list:", error); return { data: [], - pagination: { - page: 1, - size: 10, - totalCount: 0, - totalItems: 0, - totalPages: 0, - pageCount: 0, - orderField: ['name'], - orderType: ['asc'], - query: {}, - next: false, - back: false - } + pagination: defaultPaginationResponse, }; } } +async function listApplicationsAppended(payload: PaginationParams): Promise> { + if (!payload.query.service_uu_id__ilike) { + console.warn('Missing service_uu_id in query parameters'); + return { + data: [], + pagination: defaultPaginationResponse, + }; + } + + try { + const requestBody = { + page: payload.page, + size: payload.size, + order_field: payload.orderField, + order_type: payload.orderType, + query: payload.query, + }; + + console.log('Sending request to backend with service_uu_id:', payload.query.service_uu_id); + console.log('Full request body:', JSON.stringify(requestBody, null, 2)); + + const response = await fetchDataWithToken( + applicationListAppendedEndpoint, + requestBody, + "POST", + false + ); + + if (response?.status === 200 || response?.status === 202) { + const responseData = response.data as PaginatedApiResponse; + console.log('list_events_available responseData:', JSON.stringify(responseData, null, 2)); + return { + data: responseData.data || [], + pagination: collectPaginationFromApiResponse(responseData) + }; + } + return { + data: [], + pagination: defaultPaginationResponse, + }; + } catch (error) { + console.error("Error fetching events list:", error); + return { + data: [], + pagination: defaultPaginationResponse, + }; + } +} + +async function listAllApplications(payload: PaginationParams): Promise> { + try { + const requestBody = { + page: payload.page, + size: payload.size, + order_field: payload.orderField, + order_type: payload.orderType, + query: payload.query, + }; + + console.log('Sending request to backend with service_uu_id:', payload.query.service_uu_id); + console.log('Full request body:', JSON.stringify(requestBody, null, 2)); + + const response = await fetchDataWithToken( + applicationListEndpoint, + requestBody, + "POST", + false + ); + + if (response?.status === 200 || response?.status === 202) { + const responseData = response.data as PaginatedApiResponse; + console.log('list_events_available responseData:', JSON.stringify(responseData, null, 2)); + return { + data: responseData.data || [], + pagination: collectPaginationFromApiResponse(responseData) + }; + } + return { + data: [], + pagination: defaultPaginationResponse, + }; + } catch (error) { + console.error("Error fetching events list:", error); + return { + data: [], + pagination: defaultPaginationResponse, + }; + } +} + +async function appendApplicationToService(payload: AppendApplicationToService) { + try { + const response = await fetchDataWithToken( + applicationRegisterServiceEndpoint, + payload, + "POST", + false + ); + return response?.status === 200 || response?.status === 202 ? response.data : null; + } catch (error) { + console.error("Error appending event to service:", error); + } +} + +async function removeApplicationFromService(payload: RemoveApplicationFromService) { + try { + const response = await fetchDataWithToken( + applicationUnregisterServiceEndpoint, + payload, + "POST", + false + ); + return response?.status === 200 || response?.status === 202 ? response.data : null; + } catch (error) { + console.error("Error removing event from service:", error); + } +} + async function createApplication(payload: any) { try { const response = await fetchDataWithToken( @@ -100,6 +211,7 @@ async function createApplication(payload: any) { } async function updateApplication(payload: any, uuId: string) { + console.log("Updating application with payload:", payload, 'uuId:', uuId); try { const response = await fetchDataWithToken( `${applicationUpdateEndpoint}/${uuId}`, @@ -134,7 +246,11 @@ async function deleteApplication(uuId: string) { } export { - listApplications, + listApplicationsAvailable, + listApplicationsAppended, + listAllApplications, + appendApplicationToService, + removeApplicationFromService, createApplication, updateApplication, deleteApplication, diff --git a/WebServices/management-frontend/src/app/api/appenders/applications/create/route.ts b/WebServices/management-frontend/src/app/api/appenders/applications/create/route.ts new file mode 100644 index 0000000..5c1849f --- /dev/null +++ b/WebServices/management-frontend/src/app/api/appenders/applications/create/route.ts @@ -0,0 +1,22 @@ +import { appendApplicationToService } from "@/apicalls/application/endpoints"; +import { NextRequest } from "next/server"; +import { withErrorHandling } from "@/app/api/utils/requestHandlers"; +import { + successResponse, + errorResponse, +} from "@/app/api/utils/responseHandlers"; + +export const POST = withErrorHandling( + async (request: NextRequest, body: any) => { + const payload = { + application_uu_id: body.application_uu_id, + service_uu_id: body.service_uu_id, + }; + const result = await appendApplicationToService(payload); + if (!result) { + return errorResponse("Error appending application to service"); + } else { + return successResponse(result); + } + } +); diff --git a/WebServices/management-frontend/src/app/api/appenders/applications/delete/route.ts b/WebServices/management-frontend/src/app/api/appenders/applications/delete/route.ts new file mode 100644 index 0000000..251ccc1 --- /dev/null +++ b/WebServices/management-frontend/src/app/api/appenders/applications/delete/route.ts @@ -0,0 +1,22 @@ +import { removeApplicationFromService } from "@/apicalls/application/endpoints"; +import { NextRequest } from "next/server"; +import { withErrorHandling } from "@/app/api/utils/requestHandlers"; +import { + successResponse, + errorResponse, +} from "@/app/api/utils/responseHandlers"; + +export const POST = withErrorHandling( + async (request: NextRequest, body: any) => { + const payload = { + application_uu_id: body.application_uu_id, + service_uu_id: body.service_uu_id, + }; + const result = await removeApplicationFromService(payload); + if (!result) { + return errorResponse("Error removing application from service"); + } else { + return successResponse(result); + } + } +); diff --git a/WebServices/management-frontend/src/app/api/appenders/applications/list/route.ts b/WebServices/management-frontend/src/app/api/appenders/applications/list/route.ts new file mode 100644 index 0000000..bf0c160 --- /dev/null +++ b/WebServices/management-frontend/src/app/api/appenders/applications/list/route.ts @@ -0,0 +1,4 @@ +import { listApplicationsAppended } from "@/apicalls/application/endpoints"; +import { createListHandler } from "@/app/api/utils/apiOperations"; + +export const POST = createListHandler(listApplicationsAppended); diff --git a/WebServices/management-frontend/src/app/api/appenders/create/route.ts b/WebServices/management-frontend/src/app/api/appenders/events/create/route.ts similarity index 100% rename from WebServices/management-frontend/src/app/api/appenders/create/route.ts rename to WebServices/management-frontend/src/app/api/appenders/events/create/route.ts diff --git a/WebServices/management-frontend/src/app/api/appenders/delete/route.ts b/WebServices/management-frontend/src/app/api/appenders/events/delete/route.ts similarity index 100% rename from WebServices/management-frontend/src/app/api/appenders/delete/route.ts rename to WebServices/management-frontend/src/app/api/appenders/events/delete/route.ts diff --git a/WebServices/management-frontend/src/app/api/appenders/list/route.ts b/WebServices/management-frontend/src/app/api/appenders/events/list/route.ts similarity index 100% rename from WebServices/management-frontend/src/app/api/appenders/list/route.ts rename to WebServices/management-frontend/src/app/api/appenders/events/list/route.ts diff --git a/WebServices/management-frontend/src/app/api/applications/bind/employee/route.ts b/WebServices/management-frontend/src/app/api/applications/bind/employee/route.ts deleted file mode 100644 index e69de29..0000000 diff --git a/WebServices/management-frontend/src/app/api/applications/bind/occupant/route.ts b/WebServices/management-frontend/src/app/api/applications/bind/occupant/route.ts deleted file mode 100644 index e69de29..0000000 diff --git a/WebServices/management-frontend/src/app/api/applications/bind/route.ts b/WebServices/management-frontend/src/app/api/applications/bind/route.ts new file mode 100644 index 0000000..eb1438a --- /dev/null +++ b/WebServices/management-frontend/src/app/api/applications/bind/route.ts @@ -0,0 +1,4 @@ +import { createCreateHandler } from "@/app/api/utils"; +import { appendApplicationToService } from "@/apicalls/application/endpoints"; + +export const POST = createCreateHandler(appendApplicationToService); diff --git a/WebServices/management-frontend/src/app/api/applications/list/route.ts b/WebServices/management-frontend/src/app/api/applications/list/route.ts index 286f5a8..ec529ce 100644 --- a/WebServices/management-frontend/src/app/api/applications/list/route.ts +++ b/WebServices/management-frontend/src/app/api/applications/list/route.ts @@ -1,4 +1,4 @@ -import { listApplications } from "@/apicalls/application/endpoints"; +import { listApplicationsAvailable } from "@/apicalls/application/endpoints"; import { createListHandler } from "@/app/api/utils"; -export const POST = createListHandler(listApplications); +export const POST = createListHandler(listApplicationsAvailable); diff --git a/WebServices/management-frontend/src/app/api/applications/pages/route.ts b/WebServices/management-frontend/src/app/api/applications/pages/route.ts new file mode 100644 index 0000000..759438a --- /dev/null +++ b/WebServices/management-frontend/src/app/api/applications/pages/route.ts @@ -0,0 +1,4 @@ +import { listAllApplications } from "@/apicalls/application/endpoints"; +import { createListHandler } from "@/app/api/utils"; + +export const POST = createListHandler(listAllApplications); diff --git a/WebServices/management-frontend/src/app/api/applications/unbind/route.ts b/WebServices/management-frontend/src/app/api/applications/unbind/route.ts new file mode 100644 index 0000000..24f354d --- /dev/null +++ b/WebServices/management-frontend/src/app/api/applications/unbind/route.ts @@ -0,0 +1,4 @@ +import { createCreateHandler } from "@/app/api/utils"; +import { removeApplicationFromService } from "@/apicalls/application/endpoints"; + +export const POST = createCreateHandler(removeApplicationFromService); diff --git a/WebServices/management-frontend/src/components/common/FormDisplay/UpdateComponent.tsx b/WebServices/management-frontend/src/components/common/FormDisplay/UpdateComponent.tsx index 4875fbe..cebaa2c 100644 --- a/WebServices/management-frontend/src/components/common/FormDisplay/UpdateComponent.tsx +++ b/WebServices/management-frontend/src/components/common/FormDisplay/UpdateComponent.tsx @@ -167,7 +167,7 @@ export function UpdateComponent({ console.error("API URL is missing or undefined"); return; } - const uuid = initialData ? (initialData as any).uuid || (initialData as any).uu_id : null; + const uuid = initialData ? (initialData as any).uu_id : null; if (!uuid) { console.error("UUID not found in initialData"); throw new Error("UUID is required for update operations"); @@ -181,6 +181,7 @@ export function UpdateComponent({ }); const updateUrl = `${apiUrl}/update?uuid=${uuid}`; + console.log("Updating application with payload:", dataToSend, 'uuId:', uuid); try { let response = await fetch(updateUrl, { method: 'POST', diff --git a/WebServices/management-frontend/src/components/common/Loader/loader.tsx b/WebServices/management-frontend/src/components/common/Loader/loader.tsx new file mode 100644 index 0000000..ada4310 --- /dev/null +++ b/WebServices/management-frontend/src/components/common/Loader/loader.tsx @@ -0,0 +1,15 @@ +import React from 'react' + +const Loader = () => { + return ( + <> +
+
+
+
+
+ + ) +} + +export default Loader diff --git a/WebServices/management-frontend/src/components/common/hooks/useApiData.ts b/WebServices/management-frontend/src/components/common/hooks/useApiData.ts index b1d29b2..3f8ec3d 100644 --- a/WebServices/management-frontend/src/components/common/hooks/useApiData.ts +++ b/WebServices/management-frontend/src/components/common/hooks/useApiData.ts @@ -1,5 +1,6 @@ import { useDataFetching, ApiResponse } from "./useDataFetching"; import { RequestParams } from "../schemas"; +import { defaultPaginationResponse } from "@/app/api/utils/types"; /** * Hook for fetching data from Next.js API routes @@ -23,8 +24,7 @@ export function useApiData( query: params.query, }; - const listEndpoint = `${endpoint}/list`; - const response = await fetch(listEndpoint, { + const response = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json", @@ -42,19 +42,7 @@ export function useApiData( return { data: [], - pagination: { - page: params.page, - size: params.size, - totalCount: 0, - totalItems: 0, - totalPages: 0, - pageCount: 0, - orderField: params.orderField, - orderType: params.orderType, - query: params.query, - next: false, - back: false, - }, + pagination: defaultPaginationResponse, }; } }; diff --git a/WebServices/management-frontend/src/eventRouters/appenderApplication/language.ts b/WebServices/management-frontend/src/eventRouters/appenderApplication/language.ts new file mode 100644 index 0000000..3973a57 --- /dev/null +++ b/WebServices/management-frontend/src/eventRouters/appenderApplication/language.ts @@ -0,0 +1,168 @@ +import { + LanguageKey, + TranslationSet, +} from "@/validations/translations/translation"; +import { + ServiceBaseTranslationEn, + ServiceBaseTranslationTr, +} from "./schemaList/services"; +import { + ApplicationBaseTranslationTr, + ApplicationBaseTranslationEn, +} from "./schemaList/application"; + +const translations = { + en: { + // Page title + mainTitle: "Services", + + // Common actions + create: "Create", + update: "Update", + delete: "Delete", + view: "View", + save: "Save", + cancel: "Cancel", + + // Search and filters + search: "Search", + typeSelection: "Type Selection", + filterSelection: "Filter Selection", + siteUrl: "Site URL", + resetAll: "Reset All", + + // Type options + web: "Web", + mobile: "Mobile", + + // Status options + status: "Status", + active: "Active", + inactive: "Inactive", + pending: "Pending", + + // User types + employee: "Employee", + occupant: "Occupant", + + // Pagination + showing: "Showing", + of: "of", + items: "items", + total: "Total", + filtered: "Filtered", + previous: "Previous", + next: "Next", + page: "Page", + itemsPerPage: "Items per page", + + // Messages + noData: "No data found", + serviceSelectedTitle: "Selected Service", + serviceSelectedContent: "is selected to appende events", + + // Other + applicationType: "Application Type", + availableApplications: "Available Applications", + code: "Code", + sortBy: "Sort by:", + formErrors: "Please correct the errors in the form", + + // Form group titles + identificationInfo: "Identification Information", + applicationDetails: "Application Details", + statusInfo: "Status Information", + systemInfo: "System Information", + createDescription: "Create Application", + }, + tr: { + // Page title + mainTitle: "Servisler", + + // Common actions + create: "Oluştur", + update: "Güncelle", + delete: "Sil", + view: "Görüntüle", + save: "Kaydet", + cancel: "İptal", + // Search and filters + search: "Ara", + typeSelection: "Tür Seçimi", + filterSelection: "Filtre Seçimi", + siteUrl: "Site URL", + resetAll: "Tümünü Sıfırla", + + // Type options + web: "Web", + mobile: "Mobil", + + // Status options + status: "Durum", + active: "Aktif", + inactive: "Pasif", + pending: "Beklemede", + + // User types + employee: "Çalışan", + occupant: "Sakin", + + // Pagination + showing: "Gösteriliyor", + of: "of", + items: "öğeler", + total: "Toplam", + filtered: "Filtreli", + previous: "Önceki", + next: "Sonraki", + page: "Sayfa", + itemsPerPage: "Sayfa başına öğeler", + + // Messages + noData: "Veri bulunamadı", + serviceSelectedTitle: "Seçili Servis", + serviceSelectedContent: "is selected to appende events", + + // Other + applicationType: "Uygulama Türü", + availableApplications: "Mevcut Uygulamalar", + code: "Kod", + sortBy: "Sırala:", + formErrors: "Lütfen formdaki hataları düzeltiniz", + + // Form group titles + identificationInfo: "Kimlik Bilgileri", + applicationDetails: "Uygulama Detayları", + statusInfo: "Durum Bilgileri", + systemInfo: "Sistem Bilgileri", + createDescription: "Yeni bir uygulama oluşturun", + }, +}; + +const translationsServices = { + en: { + ...translations.en, + ...ServiceBaseTranslationEn, + }, + tr: { + ...translations.tr, + ...ServiceBaseTranslationTr, + }, +}; + +const translationsApplications = { + en: { + ...translations.en, + ...ApplicationBaseTranslationEn, + }, + tr: { + ...translations.tr, + ...ApplicationBaseTranslationTr, + }, +}; + +export { translations, translationsServices, translationsApplications }; + +export function getTranslation(lang: LanguageKey): TranslationSet { + return translations[lang]; +} diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/listComponent.tsx b/WebServices/management-frontend/src/eventRouters/appenderApplication/listComponent.tsx similarity index 100% rename from WebServices/management-frontend/src/eventRouters/appendersService/listComponent.tsx rename to WebServices/management-frontend/src/eventRouters/appenderApplication/listComponent.tsx diff --git a/WebServices/management-frontend/src/eventRouters/appenderApplication/page.tsx b/WebServices/management-frontend/src/eventRouters/appenderApplication/page.tsx new file mode 100644 index 0000000..befab59 --- /dev/null +++ b/WebServices/management-frontend/src/eventRouters/appenderApplication/page.tsx @@ -0,0 +1,372 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import { z } from "zod"; + +import { + ServiceData, + serviceViewFieldDefinitions, + ServiceFieldDefinitionsType, + ServiceSchema, + serviceFieldsByMode, +} from "./schemaList/services"; +import { + ApplicationData, + ApplicationFieldDefinitionsType, + ApplicationSchema, + applicationFieldsByMode, + applicationViewFieldDefinitions +} from "./schemaList/application"; +import { ListComponentEvents, ListComponentServices } from "./listComponent"; +import { translations, translationsServices, translationsApplications } from "./language"; + +import { PageProps } from "@/validations/translations/translation"; +import { FormModeView, FormMode } from "@/components/common/FormDisplay/types"; +import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay"; +import { GridSelectionComponent, GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent"; +import { useApiData } from "@/components/common"; +import { Language } from "@/components/common/schemas"; +import { Card, CardContent, CardHeader } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { CardSize } from "@/components/common/CardDisplay/schema"; +import { translationsAppenders } from "../appendersEvents/language"; +import Loader from "@/components/common/Loader/loader"; + +const AppendersApplicationPage: React.FC = ({ lang }: { lang: Language }) => { + + const urlServices = '/api/services/list'; + const urlEvents = '/api/applications/list'; + const urlAppenders = '/api/appenders/applications/list'; + const urlAppendersCreate = '/api/appenders/applications/create'; + const urlAppendersDelete = '/api/appenders/applications/delete'; + + const showFieldsServices = ["service_name", "service_code", "related_responsibility"]; + const showFieldsEvents = ["description", "name", "site_url", "application_code"]; + + const { + data: dataServices, + pagination: paginationServices, + loading: loadingServices, + error: errorServices, + updatePagination: updatePaginationServices, + refetch: refetchServices + } = useApiData(urlServices); + const { + data: dataEvents, + pagination: paginationEvents, + loading: loadingEvents, + error: errorEvents, + updatePagination: updatePaginationEvents, + refetch: refetchEvents + } = useApiData(urlEvents); + const { + data: dataAppenders, + pagination: paginationAppenders, + loading: loadingAppenders, + error: errorAppenders, + updatePagination: updatePaginationAppenders, + refetch: refetchAppenders + } = useApiData(urlAppenders); + + const [mode, setMode] = useState("list"); + const [gridCols, setGridCols] = useState(3); + + const [selectedItemServices, setSelectedItemServices] = useState(null); + const [selectedItemEvents, setSelectedItemEvents] = useState(null); + const [selectedItemAppenders, setSelectedItemAppenders] = useState(null); + + const [fieldDefinitionsServices, setFieldDefinitionsServices] = useState(null); + const [fieldDefinitionsEvents, setFieldDefinitionsEvents] = useState(null); + const [fieldDefinitionsAppenders, setFieldDefinitionsAppenders] = useState(null); + + const [validationSchemaServices, setValidationSchemaServices] = useState(null); + const [validationSchemaEvents, setValidationSchemaEvents] = useState(null); + const [validationSchemaAppenders, setValidationSchemaAppenders] = useState(null); + const [selectionBar, setSelectionBar] = useState(""); + const [languageTranslations, setLanguageTranslations] = useState({ + mainTitle: translations[lang].mainTitle, + serviceSelectedTitle: translations[lang].serviceSelectedTitle, + serviceSelectedContent: translations[lang].serviceSelectedContent, + cancel: translations[lang].cancel, + }); + + const appendServiceEvent = async (app: ApplicationData) => { + if (!selectedItemServices?.uu_id) { + throw new Error("Service not selected"); + } + const payload = { application_uu_id: app.uu_id, service_uu_id: selectedItemServices.uu_id } + fetch(urlAppendersCreate, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload) + }).then((res) => { + if (res.ok) { + updatePaginationAppenders({ + ...paginationAppenders, + query: { + ...paginationAppenders.query, + service_uu_id: selectedItemServices.uu_id + } + }); + updatePaginationEvents({ + ...paginationEvents, + query: { + ...paginationEvents.query, + service_uu_id: selectedItemServices.uu_id + } + }); + } + }) + } + + const removeServiceEvent = async (app: ApplicationData) => { + if (!selectedItemServices?.uu_id) { + throw new Error("Service not selected"); + } + const payload = { application_uu_id: app.uu_id, service_uu_id: selectedItemServices.uu_id } + fetch(urlAppendersDelete, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload) + }).then((res) => { + if (res.ok) { + updatePaginationAppenders({ + ...paginationAppenders, + query: { + ...paginationAppenders.query, + service_uu_id: selectedItemServices.uu_id + } + }); + updatePaginationEvents({ + ...paginationEvents, + query: { + ...paginationEvents.query, + service_uu_id: selectedItemServices.uu_id + } + }); + } + }) + } + + useEffect(() => { + setFieldDefinitionsServices(serviceViewFieldDefinitions); setValidationSchemaServices(ServiceSchema); + setFieldDefinitionsEvents(applicationViewFieldDefinitions); setValidationSchemaEvents(ApplicationSchema); + setFieldDefinitionsAppenders(applicationViewFieldDefinitions); setValidationSchemaAppenders(ApplicationSchema); + setLanguageTranslations({ + mainTitle: translations[lang].mainTitle, + serviceSelectedTitle: translations[lang].serviceSelectedTitle, + serviceSelectedContent: translations[lang].serviceSelectedContent, + cancel: translations[lang].cancel, + }); + }, [lang]); + + useEffect(() => { + if (selectedItemServices && selectedItemServices?.uu_id) { + updatePaginationAppenders({ + page: paginationAppenders.page, + size: paginationAppenders.size, + orderField: paginationAppenders.orderField, + orderType: paginationAppenders.orderType, + query: { + ...paginationAppenders.query, + service_uu_id: selectedItemServices.uu_id + } + }); + + updatePaginationEvents({ + page: paginationEvents.page, + size: paginationEvents.size, + orderField: paginationEvents.orderField, + orderType: paginationEvents.orderType, + query: { + ...paginationEvents.query, + service_uu_id: selectedItemServices.uu_id + } + }); + setSelectionBar( + selectedItemServices ? + `${selectedItemServices.uu_id} ${selectedItemServices?.service_name} ${translations[lang].serviceSelectedContent}` : + "No service is selected to be appended to applications" + ); + } + }, [selectedItemServices]); + + const handleQueryChangeServices = (key: string, value: string | null) => { + const newQuery = { ...paginationServices.query }; + if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value } + updatePaginationServices({ page: 1, query: newQuery }) + }; + + const handleQueryChangeEvents = (key: string, value: string | null) => { + const newQuery = { ...paginationEvents.query }; + if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value } + if (selectedItemServices?.uu_id) { + newQuery.service_uu_id = selectedItemServices.uu_id; + } + updatePaginationEvents({ page: 1, query: newQuery }); + }; + + const handleQueryChangeAppenders = (key: string, value: string | null) => { + const newQuery = { ...paginationAppenders.query }; + if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value } + if (selectedItemServices?.uu_id) { + newQuery.service_uu_id = selectedItemServices.uu_id; + } + updatePaginationAppenders({ page: 1, query: newQuery }); + }; + + const handleServicesCardClick = (item: ServiceData) => { setSelectedItemServices(item) }; + const handleServicesViewClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("view"); }; + + const handleEventsCardClick = (item: ApplicationData) => { appendServiceEvent(item); }; + const handleEventsViewClick = (item: ApplicationData) => { setSelectedItemEvents(item); setMode("view"); }; + + const handleAppendersCardClick = (item: ApplicationData) => { removeServiceEvent(item); }; + const handleAppendersViewClick = (item: ApplicationData) => { setSelectedItemAppenders(item); setMode("view"); }; + + const cancelAllSelections = () => { + setMode("list"); + setSelectedItemServices(null); + setSelectedItemEvents(null); + setSelectedItemAppenders(null); + }; + + const serviceListProps = { + lang, + loading: loadingServices, + error: errorServices, + data: dataServices, + pagination: paginationServices, + showFields: showFieldsServices, + gridCols: gridCols, + titleField: "service_name", + size: "lg" as CardSize, + handleQueryChange: handleQueryChangeServices, + updatePagination: updatePaginationServices, + handleCardClick: handleServicesCardClick, + handleViewClick: handleServicesViewClick + }; + + const eventsListProps = { + lang, + loading: loadingEvents, + error: errorEvents, + data: dataEvents, + pagination: paginationEvents, + showFields: showFieldsEvents, + gridCols: 1, + titleField: "description", + size: "lg" as CardSize, + handleQueryChange: handleQueryChangeEvents, + updatePagination: updatePaginationEvents, + handleCardClick: handleEventsCardClick, + handleViewClick: handleEventsViewClick + }; + + const appendersListProps = { + lang, + loading: loadingAppenders, + error: errorAppenders, + data: dataAppenders, + pagination: paginationAppenders, + showFields: showFieldsEvents, + gridCols: 1, + titleField: "description", + size: "lg" as CardSize, + handleQueryChange: handleQueryChangeAppenders, + updatePagination: updatePaginationAppenders, + handleCardClick: handleAppendersCardClick, + handleViewClick: handleAppendersViewClick + }; + + const serviceFormProps = { + initialData: selectedItemServices || undefined, + mode: mode, + refetch: refetchServices, + setMode: setMode, + setSelectedItem: setSelectedItemServices, + onCancel: cancelAllSelections, + lang: lang, + translations: translationsServices, + apiUrl: '/api/services', + formProps: { + fieldDefinitions: fieldDefinitionsServices, + validationSchema: validationSchemaServices, + fieldsByMode: serviceFieldsByMode + } + }; + + const eventsFormProps = { + initialData: selectedItemEvents || undefined, + mode: mode, + refetch: refetchEvents, + setMode: setMode, + setSelectedItem: setSelectedItemEvents, + onCancel: cancelAllSelections, + lang: lang, + translations: translationsApplications, + apiUrl: '/api/applications', + formProps: { + fieldDefinitions: fieldDefinitionsEvents, + validationSchema: validationSchemaEvents, + fieldsByMode: applicationFieldsByMode, + } + }; + + const appendersFormProps = { + initialData: selectedItemAppenders || undefined, + mode: mode, + refetch: refetchAppenders, + setMode: setMode, + setSelectedItem: setSelectedItemAppenders, + onCancel: cancelAllSelections, + lang: lang, + translations: translationsAppenders, + apiUrl: '/api/appenders/applications', + formProps: { + fieldDefinitions: fieldDefinitionsAppenders, + validationSchema: validationSchemaAppenders, + fieldsByMode: applicationFieldsByMode, + } + }; + + + return ( +
+
+

{languageTranslations.mainTitle}

+
+
+ + + {languageTranslations.serviceSelectedTitle} + {selectionBar} + + {mode === "list" ? ( +
+ { + !selectedItemServices ?
: +
+ +
+ { + loadingEvents ? :
+ } + { + loadingAppenders ? :
+ } +
+
+ } +
+ ) : ( +
+ {selectedItemServices && {...serviceFormProps} />} + {selectedItemEvents && {...eventsFormProps} />} + {selectedItemAppenders && {...appendersFormProps} />} +
+ )} +
+ ); +}; + +export default AppendersApplicationPage; diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/schemaList/schema.ts b/WebServices/management-frontend/src/eventRouters/appenderApplication/schemaList/application.ts similarity index 60% rename from WebServices/management-frontend/src/eventRouters/appendersService/schemaList/schema.ts rename to WebServices/management-frontend/src/eventRouters/appenderApplication/schemaList/application.ts index 963c391..f351e7c 100644 --- a/WebServices/management-frontend/src/eventRouters/appendersService/schemaList/schema.ts +++ b/WebServices/management-frontend/src/eventRouters/appenderApplication/schemaList/application.ts @@ -1,8 +1,8 @@ import { z } from "zod"; import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas"; -export interface ApplicationData { - id?: number; +interface ApplicationData { + uu_id: string; name: string; application_code: string; site_url: string; @@ -15,7 +15,6 @@ export interface ApplicationData { updated_at?: string; } -// Validation error messages by language const errorMessages = { en: { nameRequired: "Name is required", @@ -31,7 +30,6 @@ const errorMessages = { }, }; -// Function to get schema with language-specific validation messages const getApplicationBaseSchema = (lang: "en" | "tr" = "en") => z.object({ // Identification fields @@ -58,10 +56,9 @@ const getApplicationBaseSchema = (lang: "en" | "tr" = "en") => updated_at: z.string().optional(), }); -// For backward compatibility const ApplicationBaseSchema = getApplicationBaseSchema("en"); -export const ApplicationBaseTranslationTr = { +const ApplicationBaseTranslationTr = { uu_id: "UUID", name: "Name", application_code: "Application Code", @@ -75,7 +72,7 @@ export const ApplicationBaseTranslationTr = { updated_at: "Updated At", }; -export const ApplicationBaseTranslationEn = { +const ApplicationBaseTranslationEn = { uu_id: "UUID", name: "Name", application_code: "Application Code", @@ -89,7 +86,6 @@ export const ApplicationBaseTranslationEn = { updated_at: "Updated At", }; -// Create schema for creating new applications with language support const getCreateApplicationSchema = (lang: "en" | "tr" = "en") => getApplicationBaseSchema(lang).omit({ uu_id: true, @@ -98,7 +94,6 @@ const getCreateApplicationSchema = (lang: "en" | "tr" = "en") => deleted: true, }); -// Update schema for updating existing applications with language support const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") => getApplicationBaseSchema(lang) .omit({ @@ -110,34 +105,14 @@ const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") => uu_id: true, }); -// For backward compatibility -const CreateApplicationSchema = getCreateApplicationSchema("en"); -const UpdateApplicationSchema = getUpdateApplicationSchema("en"); - -// Schema for viewing an application (all fields) const ViewApplicationSchema = ApplicationBaseSchema; - -// Default schema (used for validation) const ApplicationSchema = ApplicationBaseSchema; -// Export all schemas and schema generators -export { - ApplicationBaseSchema, - ApplicationSchema, - CreateApplicationSchema, - UpdateApplicationSchema, - ViewApplicationSchema, - getApplicationBaseSchema, - getCreateApplicationSchema, - getUpdateApplicationSchema, -}; +type ApplicationFormData = z.infer; +type ViewApplicationFormData = z.infer; -export type ApplicationFormData = z.infer; -export type CreateApplicationFormData = z.infer; -export type UpdateApplicationFormData = z.infer; -export type ViewApplicationFormData = z.infer; - -const baseFieldDefinitions = { +const applicationBaseFieldDefinitions = { + // Identification fields identificationInfo: { title: "Identification Information", order: 1, @@ -171,6 +146,8 @@ const baseFieldDefinitions = { }, }, }, + + // Application details applicationDetails: { title: "Application Details", order: 2, @@ -215,6 +192,8 @@ const baseFieldDefinitions = { }, }, }, + + // Status fields statusInfo: { title: "Status Information", order: 3, @@ -241,6 +220,8 @@ const baseFieldDefinitions = { }, }, }, + + // System fields systemInfo: { title: "System Information", order: 4, @@ -266,198 +247,101 @@ const baseFieldDefinitions = { }, }, }; +const applicationFlatFieldDefinitions = flattenFieldDefinitions( + applicationBaseFieldDefinitions +); -const flatFieldDefinitions = flattenFieldDefinitions(baseFieldDefinitions); - -export const createFieldDefinitions = { - name: { - ...flatFieldDefinitions.name, - readOnly: false, - required: true, - defaultValue: "", - }, - application_code: { - ...flatFieldDefinitions.application_code, - readOnly: false, - required: true, - defaultValue: "", - }, - site_url: { - ...flatFieldDefinitions.site_url, - readOnly: false, - required: true, - defaultValue: "", - }, - application_type: { - ...flatFieldDefinitions.application_type, - readOnly: false, - required: true, - defaultValue: "", - }, - application_for: { - ...flatFieldDefinitions.application_for, - readOnly: false, - required: false, - defaultValue: "EMP", - }, - description: { - ...flatFieldDefinitions.description, - readOnly: false, - required: false, - defaultValue: "", - }, - active: { - ...flatFieldDefinitions.active, - readOnly: false, - required: false, - defaultValue: true, - }, -}; - -export const updateFieldDefinitions = { +const applicationViewFieldDefinitions = { uu_id: { - ...flatFieldDefinitions.uu_id, - readOnly: true, - required: false, - defaultValue: "", - }, - name: { - ...flatFieldDefinitions.name, - readOnly: false, - required: true, - defaultValue: "", - }, - application_code: { - ...flatFieldDefinitions.application_code, - readOnly: false, - required: true, - defaultValue: "", - }, - site_url: { - ...flatFieldDefinitions.site_url, - readOnly: false, - required: true, - defaultValue: "", - }, - application_type: { - ...flatFieldDefinitions.application_type, - readOnly: false, - required: true, - defaultValue: "", - }, - application_for: { - ...flatFieldDefinitions.application_for, - readOnly: false, - required: false, - defaultValue: "", - }, - description: { - ...flatFieldDefinitions.description, - readOnly: false, - required: false, - defaultValue: "", - }, - active: { - ...flatFieldDefinitions.active, - readOnly: false, - required: false, - defaultValue: true, - }, -}; - -export const viewFieldDefinitions = { - uu_id: { - ...flatFieldDefinitions.uu_id, + ...applicationFlatFieldDefinitions.uu_id, readOnly: true, required: false, defaultValue: 0, }, name: { - ...flatFieldDefinitions.name, + ...applicationFlatFieldDefinitions.name, readOnly: true, required: false, defaultValue: "", }, application_code: { - ...flatFieldDefinitions.application_code, + ...applicationFlatFieldDefinitions.application_code, readOnly: true, required: false, defaultValue: "", }, site_url: { - ...flatFieldDefinitions.site_url, + ...applicationFlatFieldDefinitions.site_url, readOnly: true, required: false, defaultValue: "", }, application_type: { - ...flatFieldDefinitions.application_type, + ...applicationFlatFieldDefinitions.application_type, readOnly: true, required: false, defaultValue: "", }, application_for: { - ...flatFieldDefinitions.application_for, + ...applicationFlatFieldDefinitions.application_for, readOnly: true, required: false, defaultValue: "", }, description: { - ...flatFieldDefinitions.description, + ...applicationFlatFieldDefinitions.description, readOnly: true, required: false, defaultValue: "", }, active: { - ...flatFieldDefinitions.active, + ...applicationFlatFieldDefinitions.active, readOnly: true, required: false, defaultValue: true, }, deleted: { - ...flatFieldDefinitions.deleted, + ...applicationFlatFieldDefinitions.deleted, readOnly: true, required: false, defaultValue: false, }, created_at: { - ...flatFieldDefinitions.created_at, + ...applicationFlatFieldDefinitions.created_at, readOnly: true, required: false, defaultValue: "", }, updated_at: { - ...flatFieldDefinitions.updated_at, + ...applicationFlatFieldDefinitions.updated_at, readOnly: true, required: false, defaultValue: "", }, }; - -export const fieldDefinitions = { - ...baseFieldDefinitions, - getDefinitionsByMode: (mode: "create" | "update" | "view") => { +const applicationFieldDefinitions = { + ...applicationBaseFieldDefinitions, + getDefinitionsByMode: (mode: "view") => { switch (mode) { - case "create": - return createFieldDefinitions; - case "update": - return updateFieldDefinitions; case "view": - return viewFieldDefinitions; + return applicationViewFieldDefinitions; default: - return baseFieldDefinitions; + return applicationFieldDefinitions; } }, }; - -// Fields to show based on mode - dynamically generated from field definitions -export const fieldsByMode = { - create: Object.keys(createFieldDefinitions), - update: Object.keys(updateFieldDefinitions), - view: Object.keys(viewFieldDefinitions), +const applicationFieldsByMode = { + view: Object.keys(applicationViewFieldDefinitions), }; -export type FieldDefinitionsType = - | typeof createFieldDefinitions - | typeof updateFieldDefinitions - | typeof viewFieldDefinitions; +type ApplicationFieldDefinitionsType = typeof applicationViewFieldDefinitions; + +export type { ApplicationData, ApplicationFieldDefinitionsType }; +export { + ApplicationSchema, + applicationFlatFieldDefinitions, + ApplicationBaseTranslationEn, + ApplicationBaseTranslationTr, + applicationFieldsByMode, + applicationViewFieldDefinitions, +}; diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/schemaList/services.ts b/WebServices/management-frontend/src/eventRouters/appenderApplication/schemaList/services.ts similarity index 100% rename from WebServices/management-frontend/src/eventRouters/appendersService/schemaList/services.ts rename to WebServices/management-frontend/src/eventRouters/appenderApplication/schemaList/services.ts diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/type.ts b/WebServices/management-frontend/src/eventRouters/appenderApplication/type.ts similarity index 100% rename from WebServices/management-frontend/src/eventRouters/appendersService/type.ts rename to WebServices/management-frontend/src/eventRouters/appenderApplication/type.ts diff --git a/WebServices/management-frontend/src/eventRouters/appenderEvent/page.tsx b/WebServices/management-frontend/src/eventRouters/appenderEvent/page.tsx deleted file mode 100644 index 9a8f9a6..0000000 --- a/WebServices/management-frontend/src/eventRouters/appenderEvent/page.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { PageProps } from "@/validations/translations/translation"; -import React from "react"; - -const EventAppendPage: React.FC = () => { - return
EventAppendPage
; -}; - -export default EventAppendPage; diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/language.ts b/WebServices/management-frontend/src/eventRouters/appendersEvents/language.ts similarity index 100% rename from WebServices/management-frontend/src/eventRouters/appendersService/language.ts rename to WebServices/management-frontend/src/eventRouters/appendersEvents/language.ts diff --git a/WebServices/management-frontend/src/eventRouters/appendersEvents/listComponent.tsx b/WebServices/management-frontend/src/eventRouters/appendersEvents/listComponent.tsx new file mode 100644 index 0000000..e3390bc --- /dev/null +++ b/WebServices/management-frontend/src/eventRouters/appendersEvents/listComponent.tsx @@ -0,0 +1,217 @@ +import React from 'react'; +import { translations } from './language'; +import { Filter } from 'lucide-react'; + +import { Card, CardContent } from '@/components/ui/card'; +import { TextQueryModifier } from '@/components/common/QueryModifiers/TextQueryModifier'; +import { PaginationToolsComponent } from '@/components/common/PaginationModifiers/PaginationToolsComponent'; +import { CardDisplay } from '@/components/common/CardDisplay/CardDisplay'; +import { ListComponentEventsProps, ListComponentServicesProps } from './type'; + +const ListComponentServices: React.FC = ({ + lang, + loading, + error, + data, + pagination, + showFields, + gridCols, + titleField, + size, + handleQueryChange, + updatePagination, + handleCardClick, + handleViewClick, +}) => { + const fieldKey = "service_name"; + return ( + <> + {/* Search Filters */} + + +
+ {/* Filters on the right */} +
+
+
+ {translations[lang].filterSelection} +
+
+ {/* Search input */} + +
+
+
+
+ + {/* Pagination Tools Component */} + + + + + + + {/* Card Display Component */} +
+ +
+ + ); +}; + +const ListComponentEvents: React.FC = ({ + lang, + loading, + error, + data, + pagination, + showFields, + gridCols, + size, + handleQueryChange, + updatePagination, + handleCardClick, + handleViewClick, +}) => { + const fieldKey = "description"; + return ( + <> + {/* Search Filters */} + + +
+ {/* Filters on the right */} +
+
+
+ {translations[lang].filterSelection} +
+
+ {/* Search input */} + +
+
+
+
+ + {/* Pagination Tools Component */} + + + + + + + {/* Card Display Component */} +
+ +
+ + ); +}; + +const ListComponentAppenders: React.FC = ({ + lang, + loading, + error, + data, + pagination, + showFields, + gridCols, + size, + updatePagination, + handleCardClick, + handleViewClick, +}) => { + return ( + <> + {/* Pagination Tools Component */} + + + + + + + {/* Card Display Component */} +
+ +
+ + ); +}; + +export { + ListComponentEvents, + ListComponentServices, + ListComponentAppenders, +}; \ No newline at end of file diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/page.tsx b/WebServices/management-frontend/src/eventRouters/appendersEvents/page.tsx similarity index 84% rename from WebServices/management-frontend/src/eventRouters/appendersService/page.tsx rename to WebServices/management-frontend/src/eventRouters/appendersEvents/page.tsx index 52ad06f..da5ce83 100644 --- a/WebServices/management-frontend/src/eventRouters/appendersService/page.tsx +++ b/WebServices/management-frontend/src/eventRouters/appendersEvents/page.tsx @@ -1,7 +1,6 @@ "use client"; import React, { useState, useEffect } from "react"; import { z } from "zod"; - import { ServiceData, serviceViewFieldDefinitions, @@ -18,7 +17,6 @@ import { } from "./schemaList/events"; import { ListComponentEvents, ListComponentServices } from "./listComponent"; import { translations, translationsServices, translationsAppenders, translationsEvents } from "./language"; - import { PageProps } from "@/validations/translations/translation"; import { FormModeView, FormMode } from "@/components/common/FormDisplay/types"; import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay"; @@ -28,8 +26,17 @@ import { Language } from "@/components/common/schemas"; import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { CardSize } from "@/components/common/CardDisplay/schema"; +import Loader from "@/components/common/Loader/loader"; -const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) => { +const AppendersEventsPage: React.FC = ({ lang }: { lang: Language }) => { + + const urlServices = '/api/services/list'; + const urlEvents = '/api/events/list'; + const urlAppenders = '/api/appenders/events/list'; + const urlAppendersCreate = '/api/appenders/events/create'; + const urlAppendersDelete = '/api/appenders/events/delete'; + const showFieldsServices = ["service_name", "service_code", "related_responsibility"]; + const showFieldsEvents = ["description", "marketing_layer", "cost"]; const { data: dataServices, @@ -38,7 +45,7 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) error: errorServices, updatePagination: updatePaginationServices, refetch: refetchServices - } = useApiData('/api/services'); + } = useApiData(urlServices); const { data: dataEvents, pagination: paginationEvents, @@ -46,7 +53,7 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) error: errorEvents, updatePagination: updatePaginationEvents, refetch: refetchEvents - } = useApiData('/api/events'); + } = useApiData(urlEvents); const { data: dataAppenders, pagination: paginationAppenders, @@ -54,7 +61,7 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) error: errorAppenders, updatePagination: updatePaginationAppenders, refetch: refetchAppenders - } = useApiData('/api/appenders'); + } = useApiData(urlAppenders); const [mode, setMode] = useState("list"); const [gridCols, setGridCols] = useState(3); @@ -70,14 +77,33 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) const [validationSchemaServices, setValidationSchemaServices] = useState(null); const [validationSchemaEvents, setValidationSchemaEvents] = useState(null); const [validationSchemaAppenders, setValidationSchemaAppenders] = useState(null); + const [selectionBar, setSelectionBar] = useState(""); + const [languageTranslations, setLanguageTranslations] = useState({ + mainTitle: translations[lang].mainTitle, + serviceSelectedTitle: translations[lang].serviceSelectedTitle, + serviceSelectedContent: translations[lang].serviceSelectedContent, + cancel: translations[lang].cancel, + }); - const showFieldsServices = ["service_name", "service_code", "related_responsibility"]; - const showFieldsEvents = ["description", "marketing_layer", "cost"]; + const handleServicesCardClick = (item: ServiceData) => { setSelectedItemServices(item) }; + const handleServicesViewClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("view"); }; + + const handleEventsCardClick = (item: EventData) => { appendServiceEvent(item); }; + const handleEventsViewClick = (item: EventData) => { setSelectedItemEvents(item); setMode("view"); }; + + const handleAppendersCardClick = (item: EventData) => { removeServiceEvent(item); }; + const handleAppendersViewClick = (item: EventData) => { setSelectedItemAppenders(item); setMode("view"); }; useEffect(() => { setFieldDefinitionsServices(serviceViewFieldDefinitions); setValidationSchemaServices(ServiceSchema); setFieldDefinitionsEvents(eventFlatFieldDefinitions); setValidationSchemaEvents(EventSchema); setFieldDefinitionsAppenders(eventFlatFieldDefinitions); setValidationSchemaAppenders(EventSchema); + setLanguageTranslations({ + mainTitle: translations[lang].mainTitle, + serviceSelectedTitle: translations[lang].serviceSelectedTitle, + serviceSelectedContent: translations[lang].serviceSelectedContent, + cancel: translations[lang].cancel, + }); }, [lang]); useEffect(() => { @@ -92,7 +118,6 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) service_uu_id: selectedItemServices.uu_id } }); - updatePaginationEvents({ page: paginationEvents.page, size: paginationEvents.size, @@ -103,7 +128,13 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) service_uu_id: selectedItemServices.uu_id } }); + setSelectionBar( + selectedItemServices ? + `${selectedItemServices.uu_id} ${selectedItemServices?.service_name} ${translations[lang].serviceSelectedContent}` : + "No service is selected to be appended to events" + ); } + }, [selectedItemServices]); const handleQueryChangeServices = (key: string, value: string | null) => { @@ -115,7 +146,6 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) const handleQueryChangeEvents = (key: string, value: string | null) => { const newQuery = { ...paginationEvents.query }; if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value } - if (selectedItemServices?.uu_id) { newQuery.service_uu_id = selectedItemServices.uu_id; } @@ -136,7 +166,7 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) throw new Error("Service not selected"); } const payload = { event_uu_id: event.uu_id, service_uu_id: selectedItemServices.uu_id } - fetch('/api/appenders/create', { + fetch(urlAppendersCreate, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) @@ -165,7 +195,7 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) throw new Error("Service not selected"); } const payload = { event_uu_id: event.uu_id, service_uu_id: selectedItemServices.uu_id } - fetch('/api/appenders/delete', { + fetch(urlAppendersDelete, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) @@ -189,15 +219,6 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) }) } - const handleServicesCardClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("list"); }; - const handleServicesViewClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("view"); }; - - const handleEventsCardClick = (item: EventData) => { appendServiceEvent(item); }; - const handleEventsViewClick = (item: EventData) => { setSelectedItemEvents(item); setMode("view"); }; - - const handleAppendersCardClick = (item: EventData) => { removeServiceEvent(item); }; - const handleAppendersViewClick = (item: EventData) => { setSelectedItemAppenders(item); setMode("view"); }; - const cancelAllSelections = () => { setMode("list"); setSelectedItemServices(null); @@ -307,22 +328,22 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) return (
-

{translations[lang].mainTitle}

+

{languageTranslations.mainTitle}

+ + + {languageTranslations.serviceSelectedTitle} + {selectionBar} + {mode === "list" ? (
{ !selectedItemServices ?
:
- - - {translations[lang].serviceSelectedTitle} - {selectedItemServices.uu_id}{" "}{selectedItemServices?.service_name}{" "}{translations[lang].serviceSelectedContent} -
-
-
+ {loadingEvents ? :
} + {loadingAppenders ? :
}
} @@ -338,4 +359,4 @@ const AppendersServicePage: React.FC = ({ lang }: { lang: Language }) ); }; -export default AppendersServicePage; +export default AppendersEventsPage; diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/schemaList/appenders.ts b/WebServices/management-frontend/src/eventRouters/appendersEvents/schemaList/appenders.ts similarity index 100% rename from WebServices/management-frontend/src/eventRouters/appendersService/schemaList/appenders.ts rename to WebServices/management-frontend/src/eventRouters/appendersEvents/schemaList/appenders.ts diff --git a/WebServices/management-frontend/src/eventRouters/appendersService/schemaList/events.ts b/WebServices/management-frontend/src/eventRouters/appendersEvents/schemaList/events.ts similarity index 100% rename from WebServices/management-frontend/src/eventRouters/appendersService/schemaList/events.ts rename to WebServices/management-frontend/src/eventRouters/appendersEvents/schemaList/events.ts diff --git a/WebServices/management-frontend/src/eventRouters/appendersEvents/schemaList/services.ts b/WebServices/management-frontend/src/eventRouters/appendersEvents/schemaList/services.ts new file mode 100644 index 0000000..7de98c8 --- /dev/null +++ b/WebServices/management-frontend/src/eventRouters/appendersEvents/schemaList/services.ts @@ -0,0 +1,295 @@ +import { z } from "zod"; +import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas"; + +interface ServiceData { + uu_id: string; + module_uu_id: string; + service_name: string; + service_description?: string; + service_code: string; + related_responsibility?: string; + is_confirmed: boolean; + active: boolean; + deleted?: boolean; + created_at?: string; + updated_at?: string; +} + +const errorMessages = { + en: { + moduleUuIdRequired: "Module UUID is required", + serviceNameRequired: "Service name is required", + serviceCodeRequired: "Service code is required", + }, + tr: { + moduleUuIdRequired: "Modül UUID'si gereklidir", + serviceNameRequired: "Servis adı gereklidir", + serviceCodeRequired: "Servis kodu gereklidir", + }, +}; + +const getServiceBaseSchema = (lang: "en" | "tr" = "en") => + z.object({ + uu_id: z.string().optional(), + module_uu_id: z.string().min(1, errorMessages[lang].moduleUuIdRequired), + service_name: z.string().min(1, errorMessages[lang].serviceNameRequired), + service_description: z.string().optional(), + service_code: z.string().min(1, errorMessages[lang].serviceCodeRequired), + related_responsibility: z.string().optional(), + is_confirmed: z.boolean().default(false), + active: z.boolean().default(true), + deleted: z.boolean().default(false), + created_at: z.string().optional(), + updated_at: z.string().optional(), + }); + +const ServiceBaseSchema = getServiceBaseSchema("en"); +const ServiceBaseTranslationTr = { + uu_id: "UUID", + module_uu_id: "Modül UUID'si", + service_name: "Servis Adı", + service_description: "Servis Açıklaması", + service_code: "Servis Kodu", + related_responsibility: "İlgili Sorumluluk", + is_confirmed: "Onaylandı", + active: "Active", + deleted: "Deleted", + created_at: "Created At", + updated_at: "Updated At", +}; +const ServiceBaseTranslationEn = { + uu_id: "UUID", + module_uu_id: "Module UUID", + service_name: "Service Name", + service_description: "Service Description", + service_code: "Service Code", + related_responsibility: "Related Responsibility", + is_confirmed: "Confirmed", + active: "Active", + deleted: "Deleted", + created_at: "Created At", + updated_at: "Updated At", +}; +const ViewServiceSchema = ServiceBaseSchema; +const ServiceSchema = ServiceBaseSchema; +const serviceBaseFieldDefinitions = { + identificationInfo: { + title: "Service Information", + order: 1, + fields: { + uu_id: { + type: "text", + label: { + tr: ServiceBaseTranslationTr.uu_id, + en: ServiceBaseTranslationEn.uu_id, + }, + readOnly: true, + required: false, + }, + module_uu_id: { + type: "text", + label: { + tr: ServiceBaseTranslationTr.module_uu_id, + en: ServiceBaseTranslationEn.module_uu_id, + }, + readOnly: false, + required: true, + }, + service_name: { + type: "text", + label: { + tr: ServiceBaseTranslationTr.service_name, + en: ServiceBaseTranslationEn.service_name, + }, + readOnly: false, + required: true, + }, + service_description: { + type: "text", + label: { + tr: ServiceBaseTranslationTr.service_description, + en: ServiceBaseTranslationEn.service_description, + }, + readOnly: false, + required: true, + }, + service_code: { + type: "text", + label: { + tr: ServiceBaseTranslationTr.service_code, + en: ServiceBaseTranslationEn.service_code, + }, + readOnly: false, + required: true, + }, + related_responsibility: { + type: "text", + label: { + tr: ServiceBaseTranslationTr.related_responsibility, + en: ServiceBaseTranslationEn.related_responsibility, + }, + readOnly: false, + required: false, + }, + }, + }, + + statusInfo: { + title: "Status Information", + order: 3, + fields: { + active: { + type: "checkbox", + label: { + tr: ServiceBaseTranslationTr.active, + en: ServiceBaseTranslationEn.active, + }, + readOnly: false, + required: false, + defaultValue: true, + }, + deleted: { + type: "checkbox", + label: { + tr: ServiceBaseTranslationTr.deleted, + en: ServiceBaseTranslationEn.deleted, + }, + readOnly: true, + required: false, + defaultValue: false, + }, + is_confirmed: { + type: "checkbox", + label: { + tr: ServiceBaseTranslationTr.is_confirmed, + en: ServiceBaseTranslationEn.is_confirmed, + }, + readOnly: false, + required: true, + }, + }, + }, + + systemInfo: { + title: "System Information", + order: 4, + fields: { + created_at: { + type: "date", + label: { + tr: ServiceBaseTranslationTr.created_at, + en: ServiceBaseTranslationEn.created_at, + }, + readOnly: true, + required: false, + }, + updated_at: { + type: "date", + label: { + tr: ServiceBaseTranslationTr.updated_at, + en: ServiceBaseTranslationEn.updated_at, + }, + readOnly: true, + required: false, + }, + }, + }, +}; +const serviceFlatFieldDefinitions = flattenFieldDefinitions( + serviceBaseFieldDefinitions +); +const serviceViewFieldDefinitions = { + uu_id: { + ...serviceFlatFieldDefinitions.uu_id, + readOnly: true, + required: false, + defaultValue: 0, + }, + module_uu_id: { + ...serviceFlatFieldDefinitions.module_uu_id, + readOnly: true, + required: false, + defaultValue: "", + }, + service_name: { + ...serviceFlatFieldDefinitions.service_name, + readOnly: true, + required: false, + defaultValue: "", + }, + service_description: { + ...serviceFlatFieldDefinitions.service_description, + readOnly: true, + required: false, + defaultValue: "", + }, + service_code: { + ...serviceFlatFieldDefinitions.service_code, + readOnly: true, + required: false, + defaultValue: "", + }, + related_responsibility: { + ...serviceFlatFieldDefinitions.related_responsibility, + readOnly: true, + required: false, + defaultValue: "", + }, + active: { + ...serviceFlatFieldDefinitions.active, + readOnly: true, + required: false, + defaultValue: true, + }, + is_confirmed: { + ...serviceFlatFieldDefinitions.is_confirmed, + readOnly: true, + required: false, + defaultValue: true, + }, + deleted: { + ...serviceFlatFieldDefinitions.deleted, + readOnly: true, + required: false, + defaultValue: false, + }, + created_at: { + ...serviceFlatFieldDefinitions.created_at, + readOnly: true, + required: false, + defaultValue: "", + }, + updated_at: { + ...serviceFlatFieldDefinitions.updated_at, + readOnly: true, + required: false, + defaultValue: "", + }, +}; +const serviceFieldDefinitions = { + ...serviceBaseFieldDefinitions, + getDefinitionsByMode: (mode: "view") => { + switch (mode) { + case "view": + return serviceViewFieldDefinitions; + default: + return serviceBaseFieldDefinitions; + } + }, +}; +const serviceFieldsByMode = { + view: Object.keys(serviceViewFieldDefinitions), +}; + +type ServiceFormData = z.infer; +type ServiceViewFormData = z.infer; +type ServiceFieldDefinitionsType = typeof serviceViewFieldDefinitions; + +export type { ServiceData, ServiceFieldDefinitionsType }; +export { + ServiceSchema, + serviceViewFieldDefinitions, + ServiceBaseTranslationEn, + ServiceBaseTranslationTr, + serviceFieldsByMode, +}; diff --git a/WebServices/management-frontend/src/eventRouters/appendersEvents/type.ts b/WebServices/management-frontend/src/eventRouters/appendersEvents/type.ts new file mode 100644 index 0000000..943139d --- /dev/null +++ b/WebServices/management-frontend/src/eventRouters/appendersEvents/type.ts @@ -0,0 +1,37 @@ +import { Language } from "@/components/common/schemas"; +import { GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent"; +import { CardSize } from "@/components/common/CardDisplay/schema"; +import * as schemaServices from "./schemaList/services"; +import * as schemaEvents from "./schemaList/events"; + +export interface ListComponentServicesProps { + lang: Language; + loading: boolean; + error: any; + data: schemaServices.ServiceData[]; + pagination: any; + showFields: string[]; + gridCols: GridSize | number; + titleField: string; + size: CardSize; + handleQueryChange: (key: string, value: string | null) => void; + updatePagination: (pagination: any) => void; + handleCardClick: (item: schemaServices.ServiceData) => void; + handleViewClick: (item: schemaServices.ServiceData) => void; +} + +export interface ListComponentEventsProps { + lang: Language; + loading: boolean; + error: any; + data: schemaEvents.EventData[]; + pagination: any; + showFields: string[]; + gridCols: GridSize | number; + titleField: string; + size: CardSize; + handleQueryChange: (key: string, value: string | null) => void; + updatePagination: (pagination: any) => void; + handleCardClick: (item: schemaEvents.EventData) => void; + handleViewClick: (item: schemaEvents.EventData) => void; +} diff --git a/WebServices/management-frontend/src/eventRouters/application/page.tsx b/WebServices/management-frontend/src/eventRouters/application/page.tsx index 151da07..ad9caf6 100644 --- a/WebServices/management-frontend/src/eventRouters/application/page.tsx +++ b/WebServices/management-frontend/src/eventRouters/application/page.tsx @@ -22,7 +22,7 @@ import { Language } from "@/components/common/schemas"; const ApplicationPage: React.FC = ({ lang }: { lang: Language }) => { - const { data, pagination, loading, error, updatePagination, refetch } = useApiData('/api/applications'); + const { data, pagination, loading, error, updatePagination, refetch } = useApiData('/api/applications/pages'); const [mode, setMode] = useState("list"); const [selectedItem, setSelectedItem] = useState(null); diff --git a/WebServices/management-frontend/src/eventRouters/application/schema.ts b/WebServices/management-frontend/src/eventRouters/application/schema.ts index 83da62c..2c5adc6 100644 --- a/WebServices/management-frontend/src/eventRouters/application/schema.ts +++ b/WebServices/management-frontend/src/eventRouters/application/schema.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas"; export interface ApplicationData { - id?: number; + uu_id: string; name: string; application_code: string; site_url: string; diff --git a/WebServices/management-frontend/src/eventRouters/index.tsx b/WebServices/management-frontend/src/eventRouters/index.tsx index bc08bb8..cb42453 100644 --- a/WebServices/management-frontend/src/eventRouters/index.tsx +++ b/WebServices/management-frontend/src/eventRouters/index.tsx @@ -1,13 +1,13 @@ import DashboardPage from "./dashboard/page"; import ApplicationPage from "./application/page"; -import EventAppendPage from "./appenderEvent/page"; -import ServiceAppendPage from "./appendersService/page"; +import AppendersEventsPage from "./appenderApplication/page"; +import AppendersServicePage from "./appendersEvents/page"; const menuPages = { "/dashboard": DashboardPage, "/application": ApplicationPage, - "/append/event": EventAppendPage, - "/append/service": ServiceAppendPage + "/append/event": AppendersEventsPage, + "/append/service": AppendersServicePage }; export default menuPages; diff --git a/docker-compose.yml b/docker-compose.yml index 65a2b62..5b27917 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -117,7 +117,19 @@ services: context: . dockerfile: ApiServices/InitialService/Dockerfile environment: - - SET_ALEMBIC=0 + - SET_ALEMBIC=1 + networks: + - wag-services + env_file: + - api_env.env + mem_limit: 512m + cpus: 0.5 + + dealer_service: + container_name: dealer_service + build: + context: . + dockerfile: ApiServices/DealerService/Dockerfile networks: - wag-services env_file: @@ -152,18 +164,6 @@ services: # mem_limit: 512m # cpus: 0.5 - dealer_service: - container_name: dealer_service - build: - context: . - dockerfile: ApiServices/DealerService/Dockerfile - networks: - - wag-services - env_file: - - api_env.env - mem_limit: 512m - cpus: 0.5 - networks: wag-services: # template_service: