Compare commits

...

97 Commits

Author SHA1 Message Date
78615a7f8e build update pydantic renewed 2025-01-04 12:13:46 +03:00
410ee2d6c4 database engine_config updated 2025-01-04 11:00:23 +03:00
fa66741b48 endpoint_restriction_available updated 2025-01-01 16:45:34 +03:00
17a6609a8f endpoint_restriction_available updated 2025-01-01 16:43:40 +03:00
1c6fffd29d endpoint_restriction_available updated 2025-01-01 14:37:54 +03:00
39a839c43c endpoint_restriction_available updated 2025-01-01 14:11:21 +03:00
73645ce3ca single endpoint check 2025-01-01 13:21:04 +03:00
05c8af2310 updated 2024-12-30 23:04:10 +03:00
be8a5212d8 updated 2024-12-30 19:50:04 +03:00
7997e561f7 events updated 2024-12-29 19:16:26 +03:00
5223f36da7 events updated 2024-12-23 13:07:25 +03:00
b8cebd9af4 updated update base models 2024-12-20 22:05:42 +03:00
de9af544bb is_bank_retrieve_account_records updated 2024-12-20 12:58:54 +03:00
b61f00d61c yaml updated 2024-12-20 12:48:04 +03:00
6089f1cc8e bank service updated 2024-12-20 12:16:46 +03:00
a0ec0b5b69 bank service updated 2024-12-20 12:08:50 +03:00
6bdf887437 yaml updated 2024-12-19 11:41:44 +03:00
aa6fb5a683 yaml updated 2024-12-19 11:40:31 +03:00
c248db29fe bank records updated 2024-12-19 11:37:25 +03:00
eab9e93969 events updated 2024-12-14 18:46:36 +03:00
6682d50228 event validations and event response models will be updated 2024-12-12 17:12:18 +03:00
1b15b77036 updated response models and event validations 2024-12-11 19:54:36 +03:00
3c8ec13dfe validation requester updated 2024-12-10 18:00:08 +03:00
a61efdf473 validation requester updated 2024-12-10 17:35:06 +03:00
4308f1e7b1 validation requester updated 2024-12-10 16:45:53 +03:00
6ba0e37ffd event list token updated 2024-12-07 16:18:11 +03:00
9e955841c3 auth updated availaible event 2024-12-06 16:35:25 +03:00
88309eb49d super_user and services updated 2024-12-05 18:59:46 +03:00
88f94c37c2 endpoint retriever updated 2024-12-03 21:27:33 +03:00
efb528bd46 bank and account service is updated 2024-12-03 15:53:36 +03:00
7e4cec2d0b bank and account service is updated 2024-12-03 15:33:37 +03:00
55abf7c80f bank and account service is updated 2024-12-03 15:32:32 +03:00
c2dd464fc6 bank and account service is updated 2024-12-03 15:31:52 +03:00
ac5a71f1a8 events updated 2024-12-02 22:18:46 +03:00
a038a1b8ee events updated 2024-12-02 13:07:22 +03:00
aaeb7f4d00 bank updated 2024-12-02 11:42:29 +03:00
665d961be8 bank updated 2024-12-02 11:40:51 +03:00
a4fd52c28a auth password forgot and change tested 2024-12-01 15:08:59 +03:00
288a393719 TIMESTAMP(timezone=True) updated 2024-11-26 12:29:01 +03:00
3539a26d77 bank service update 2024-11-26 12:05:20 +03:00
3e38bdf113 bank service update 2024-11-26 12:01:41 +03:00
ea6a5b20f3 bank service update 2024-11-26 11:57:21 +03:00
40b6c63e2a bank service update 2024-11-26 11:37:40 +03:00
193fca1248 bank service update 2024-11-26 11:35:00 +03:00
77a57279f2 yaml updated 2024-11-26 11:27:00 +03:00
c01b729e1d yaml updated 2024-11-26 11:22:30 +03:00
3b32cdcf62 yaml updated 2024-11-26 11:21:47 +03:00
5a5e58ff78 bank service update [config] 2024-11-26 11:18:34 +03:00
c525ac1117 app accounts updated 2024-11-25 21:34:33 +03:00
a371d5d6e3 build managment added 2024-11-25 11:29:44 +03:00
523b2c5033 crontab updated 2024-11-24 18:47:13 +03:00
e119c66d3c crontab updated 2024-11-24 18:33:49 +03:00
a71939c651 account records balancer added 2024-11-24 17:35:54 +03:00
54ccc55c34 account records balancer added 2024-11-24 17:33:52 +03:00
6ad1ba7d62 service acout records updated 2024-11-20 20:06:36 +03:00
1291ac87e2 project item updated 2024-11-20 15:16:16 +03:00
5e3bd35603 project item updated 2024-11-20 15:13:09 +03:00
40bf6d8ae1 project item updated 2024-11-20 14:41:23 +03:00
73d41b8e10 project item updated 2024-11-20 14:12:56 +03:00
0b3e0c299c project budget updated 2024-11-20 12:04:02 +03:00
48682b1914 project events updated 2024-11-19 14:47:35 +03:00
34400ffa4d project events updated 2024-11-19 13:04:07 +03:00
dca3cf90ff project events updated 2024-11-19 12:28:58 +03:00
1e8f5023e8 project items added 2024-11-18 20:21:38 +03:00
7bc16e02d1 project book event 2024-11-18 14:12:07 +03:00
b4dc24cf50 decision book decision book items updated 2024-11-18 12:41:10 +03:00
ac20226aa1 event decision book item updated 2024-11-17 21:01:26 +03:00
58ee49a1fc event decision book item updated 2024-11-17 19:55:17 +03:00
295dbe2cd8 save and confirmed added 2024-11-17 16:30:50 +03:00
7e1b26f3c4 test application updated@build living space 2024-11-15 19:23:08 +03:00
d2cc195ccf events updated 2024-11-14 22:25:54 +03:00
6ccb13809a decision book create update 2024-11-14 21:29:36 +03:00
1ae1264ace migrator completed 2024-11-14 18:11:53 +03:00
ac037ae54a build & events updated 2024-11-13 22:31:42 +03:00
83b3a5989e events updated 2024-11-13 20:53:06 +03:00
4199cc16b4 alchemy updated 2024-11-13 14:59:05 +03:00
052d1f7b9c get smart query removed 2024-11-13 14:03:47 +03:00
129e8015f3 events and auth updated 2024-11-13 13:38:11 +03:00
934c7bc845 events and auth updated 2024-11-13 13:11:56 +03:00
5fa183c12e events updated 2024-11-13 11:05:01 +03:00
72bf3b8ddf events updated 2024-11-13 10:59:57 +03:00
077d264b28 events updated 2024-11-13 10:38:00 +03:00
952d742999 build area updated 2024-11-12 13:57:14 +03:00
ffb85a62f6 migrator functions updated 2024-11-11 22:23:07 +03:00
f6135ced5f alchemy flush and save functions updated 2024-11-11 18:58:28 +03:00
1f1222c32d alchemy flush and save functions updated 2024-11-11 18:55:53 +03:00
c42a19c262 init defaults completed 2024-11-10 20:14:13 +03:00
aeda315119 alchemy functions updated 2024-11-10 14:13:38 +03:00
a28d4c22d1 alchemy functions updated 2024-11-10 13:39:34 +03:00
be100a6615 alchemy functions updated 2024-11-10 13:36:52 +03:00
eb947ecb3d alchemy functions updated 2024-11-10 13:16:45 +03:00
7a7241c71c alchemy functions updated 2024-11-10 12:49:31 +03:00
e01a2c8afb alchemy functions updated 2024-11-10 12:14:10 +03:00
1f75e49a07 alcehmy and event functions updated 2024-11-09 22:31:12 +03:00
e7a9b8c313 orm get dict and id columns mappers updated 2024-11-09 12:47:58 +03:00
df5927e5ac events are updated 2024-11-08 18:23:28 +03:00
c5b771e5cb services are checked 2024-11-08 17:14:02 +03:00
340 changed files with 568530 additions and 5079 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,30 @@
GSM Projesi 30.11.2023 -315,00 TL
GSM Projesi 31.12.2023 -300,00 TL
Doğalgaz_Anakolon Projesi 31.10.2023 -1.733,33 TL
Doğalgaz_Anakolon Projesi 30.11.2023 -1.750,00 TL
Doğalgaz_Anakolon Projesi 31.12.2023 -1.100,00 TL
Yan Alan Projesi 31.10.2023 -495,83 TL
Yan Alan Projesi 30.11.2023 -400,00 TL
Kazan çıkışı ana boru değişim projesi 29.02.2024 -180,00 TL
Kazan çıkışı ana boru değişim projesi 31.03.2024 -150,00 TL
Kazan Genleşme Tankı değişim projesi 30.04.2024 -250,00 TL
Kazan Genleşme Tankı değişim projesi 31.05.2024 -300,00 TL
2024 1 nolu proje toplamı 31.07.2024 -585
1 - Bina boru satışı -₺1.580,00
3 - Bina su depo temizliği projesi ₺3.000,00
4 - Çatı Camlarının değişim projesi ₺1.000,00
8 - Bina Uydu Bakım Projesi ₺1.700,00
2 - Bina iç tadilat, elektrik ve boya işleri projesi ₺42.200,00
5 - Dış kapının değişim projesi ₺24.000,00
9- Hurda Aliminyum Satışı -₺2.600,00
6 - Kazan borlularının ana kolondan sökülmesi projesi ₺22.500,00
7 - Yol tarafı ile bahçe tarafı logar tadilat projesi ₺0,00
16.09.2024 10:28 -2.000,00 6.327,91 0 TL dogalgaz bakimi icin
20.08.2024 13:53 -8.000,00 257,70 0 TL tadilat bedeli
15.07.2024 11:52 -500,00 7.104,23 0 TL REMZİ SU
13.07.2024 10:35 -2.400,00 6.104,23 0 TL SANTIYE TEKNIK ANKARA 0412
13.06.2024 13:37 -750,00 16.939,09 0 TL cam değişimi
12.06.2024 10:41 -3.000,00 16.701,74 0 TL depo temizliği için ödenen
10.06.2024 13:38 -200,00 19.701,74 0 TL cam için ödenen

View File

@@ -0,0 +1,14 @@
1 ₺4.120,00
1 - Bina boru satışı -₺1.580,00
3 - Bina su depo temizliği projesi ₺3.000,00
4 - Çatı Camlarının değişim projesi ₺1.000,00
8 - Bina Uydu Bakım Projesi ₺1.700,00
2 ₺63.600,00
2 - Bina iç tadilat, elektrik ve boya işleri projesi ₺42.200,00
5 - Dış kapının değişim projesi ₺24.000,00
9- Hurda Aliminyum Satışı -₺2.600,00
4 ₺22.500,00
6 - Kazan borlularının ana kolondan sökülmesi projesi ₺22.500,00
3 ₺0,00
7 - Yol tarafı ile bahçe tarafı logar tadilat projesi ₺0,00
Genel Toplam ₺90.220,00

View File

@@ -1,5 +1,5 @@
import json
import typing
from typing import Union
from fastapi import status
from fastapi.requests import Request
@@ -35,7 +35,6 @@ from api_validations.validations_request import (
EmployeeSelection,
)
from api_services import (
password_is_changed_template,
change_your_password_template,
save_access_token_to_redis,
update_selected_to_redis,
@@ -48,12 +47,15 @@ from api_configs import ApiStatic, Auth
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class AuthenticationLoginEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Login via domain and access key : [email] | [phone]"
event_category = "AUTHENTICATION"
__event_keys__ = {
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
}
@@ -62,16 +64,18 @@ class AuthenticationLoginEventMethods(MethodToEvent):
def authentication_login_with_domain_and_creds(
cls,
data: Login,
request,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
request: Request,
):
access_dict = Users.login_user_with_credentials(data=data, request=request)
found_user = access_dict.get("user", None)
if not found_user:
if not access_dict.get("user", None):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
)
if not access_dict.get("access_object", None):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This User has no active role registered. Please contact your administrator.",
)
return JSONResponse(
content={
"completed": True,
@@ -79,7 +83,7 @@ class AuthenticationLoginEventMethods(MethodToEvent):
"access_token": access_dict.get("access_token"),
"refresh_token": access_dict.get("refresher_token"),
"access_object": access_dict.get("access_object"),
"user": found_user.get_dict(),
"user": access_dict.get("user", None).get_dict(),
},
status_code=status.HTTP_200_OK,
)
@@ -96,14 +100,13 @@ class AuthenticationSelectEventMethods(MethodToEvent):
def authentication_select_company_or_occupant_type(
cls,
request: Request,
data: typing.Union[EmployeeSelection, OccupantSelection],
token_dict: dict = None,
data: Union[EmployeeSelection, OccupantSelection],
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
from api_objects.auth.token_objects import OccupantToken, CompanyToken
from api_objects import OccupantToken, CompanyToken
token_user = get_object_via_access_key(request=request)
if token_user.user_type == 1:
if data.company_uu_id not in token_user.companies_uu_id_list:
if isinstance(token_dict, EmployeeTokenObject):
if data.company_uu_id not in token_dict.companies_uu_id_list:
return JSONResponse(
content={
"completed": False,
@@ -111,41 +114,49 @@ class AuthenticationSelectEventMethods(MethodToEvent):
},
status_code=status.HTTP_401_UNAUTHORIZED,
)
if selected_company := Companies.find_one(uu_id=data.company_uu_id):
if selected_company := Companies.filter_one(
Companies.uu_id == data.company_uu_id,
).data:
department_ids = [
department.id
for department in Departments.filter_by_active(
company_id=selected_company.id
for department in Departments.filter_all(
Departments.company_id == selected_company.id,
).data
]
duties_ids = [
duties.id
for duties in Duties.filter_active(
for duties in Duties.filter_all(
Duties.company_id == selected_company.id,
Duties.department_id.in_(department_ids),
).data
]
staff_ids = [
staff.id
for staff in Staff.filter_active(
Staff.duties_id.in_(duties_ids)
for staff in Staff.filter_all(
Staff.duties_id.in_(duties_ids),
).data
]
employee = Employees.filter_active(
Employees.people_id == token_user.person_id,
employee = Employees.filter_one(
Employees.people_id == token_dict.person_id,
Employees.staff_id.in_(staff_ids),
).data[0]
reachable_event_list_id, reachable_event_list_uu_id = (
Event2Employee.get_event_id_by_employee_id(employee_id=employee.id)
)
staff = Staff.find_one(id=employee.staff_id)
duties = Duties.find_one(id=staff.duties_id)
department = Departments.find_one(id=duties.department_id)
bulk_id = Duty.find_one(duty_code="BULK")
bulk_duty_id = Duties.find_one(
company_id=selected_company.id, duties_id=bulk_id.id
).data
reachable_event_list_id = Event2Employee.get_event_id_by_employee_id(
employee_id=employee.id
)
staff = Staff.filter_one(
Staff.id == employee.staff_id,
).data
duties = Duties.filter_one(
Duties.id == staff.duties_id,
).data
department = Departments.filter_one(
Departments.id == duties.department_id,
).data
bulk_id = Duty.filter_by_one(system=True, duty_code="BULK").data
bulk_duty_id = Duties.filter_by_one(
company_id=selected_company.id,
duties_id=bulk_id.id,
**Duties.valid_record_dict,
).data
update_selected_to_redis(
request=request,
add_payload=CompanyToken(
@@ -161,7 +172,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
employee_id=employee.id,
employee_uu_id=employee.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
),
)
return JSONResponse(
@@ -171,29 +181,41 @@ class AuthenticationSelectEventMethods(MethodToEvent):
},
status_code=status.HTTP_200_OK,
)
elif token_user.user_type == 2:
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
elif isinstance(token_dict, OccupantTokenObject):
occupant_type = OccupantTypes.filter_by_one(
system=True, uu_id=data.occupant_uu_id
).data
if not occupant_type:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Occupant Type is not found",
)
build_part = BuildParts.find_one(uu_id=data.build_part_uu_id)
build_part = BuildParts.filter_by_one(
system=True, uu_id=data.build_part_uu_id
).data
if not build_part:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Build Part is not found",
)
build = Build.find_one(id=build_part.build_id)
related_company = RelationshipEmployee2Build.find_one(member_id=build.id)
company_related = Companies.find_one(id=related_company.company_id)
responsible_employee = Employees.find_one(id=related_company.employee_id)
if selected_occupant_type := BuildLivingSpace.find_one(
occupant_type=occupant_type.id,
person_id=token_user.person_id,
build_parts_id=build_part.id,
):
reachable_event_list_id, reachable_event_list_uu_id = (
build = Build.filter_one(
Build.id == build_part.build_id,
).data
related_company = RelationshipEmployee2Build.filter_one(
RelationshipEmployee2Build.member_id == build.id,
).data
company_related = Companies.filter_one(
Companies.id == related_company.company_id,
).data
responsible_employee = Employees.filter_one(
Employees.id == related_company.employee_id,
).data
if selected_occupant_type := BuildLivingSpace.filter_one(
BuildLivingSpace.occupant_type == occupant_type.id,
BuildLivingSpace.person_id == token_dict.person_id,
BuildLivingSpace.build_parts_id == build_part.id,
).data:
reachable_event_list_id = (
Event2Occupant.get_event_id_by_build_living_space_id(
build_living_space_id=selected_occupant_type.id
)
@@ -215,7 +237,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
responsible_company_id=company_related.id,
responsible_company_uuid=company_related.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
),
)
return JSONResponse(
@@ -239,8 +260,9 @@ class AuthenticationCheckTokenEventMethods(MethodToEvent):
}
@classmethod
def authentication_login_with_domain_and_creds(
cls, request, token_dict: dict = None
def authentication_check_token_is_valid(
cls,
request,
):
if get_object_via_access_key(request=request):
return JSONResponse(
@@ -261,17 +283,20 @@ class AuthenticationRefreshEventMethods(MethodToEvent):
}
@classmethod
def authentication_refresh_user_info(cls, request, token_dict: dict = None):
def authentication_refresh_user_info(
cls,
request,
):
access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
if token_user := get_object_via_access_key(request=request):
if found_user := Users.find_one(uu_id=token_user.get("uu_id")):
user_token = UsersTokens.find_one(
domain=found_user.domain_name,
user_id=found_user.id,
token_type="RememberMe",
)
if found_user := Users.filter_one(
Users.uu_id == token_user.get("uu_id"),
).data:
user_token = UsersTokens.filter_one(
UsersTokens.domain == found_user.domain_name,
UsersTokens.user_id == found_user.id,
UsersTokens.token_type == "RememberMe",
).data
access_dict = {
"access_token": access_token,
"refresh_token": getattr(user_token, "token", None),
@@ -299,27 +324,31 @@ class AuthenticationChangePasswordEventMethods(MethodToEvent):
@classmethod
def authentication_change_password(
cls, request, data: ChangePassword, token_dict: dict = None
cls,
data: ChangePassword,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
token_user = get_object_via_access_key(request=request)
if token_user.user_type == 1:
if found_user := Users.find_one(uu_id=token_user.uu_id):
if found_user.check_password(data.old_password):
found_user.set_password(data.new_password)
return JSONResponse(
content={
"completed": True,
"message": "Password is changed successfully",
},
status_code=status.HTTP_200_OK,
)
if found_user := Users.filter_one(
Users.id == token_dict.user_id,
).data:
if found_user.check_password(data.old_password):
found_user.create_password(
found_user=found_user, password=data.new_password
)
return JSONResponse(
content={
"completed": False,
"message": "Old password is not correct",
"completed": True,
"message": "Password is changed successfully",
},
status_code=status.HTTP_401_UNAUTHORIZED,
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={
"completed": False,
"message": "Old password is not correct",
},
status_code=status.HTTP_401_UNAUTHORIZED,
)
return JSONResponse(
content={"completed": False, "message": "Invalid data"},
status_code=status.HTTP_401_UNAUTHORIZED,
@@ -335,40 +364,88 @@ class AuthenticationCreatePasswordEventMethods(MethodToEvent):
@classmethod
def authentication_create_password(
cls, request, data: CreatePassword, token_dict: dict = None
cls,
data: CreatePassword,
):
if not data.re_password == data.password:
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
)
if found_user := Users.find_one(password_token=data.password_token):
found_user.create_password(password=data.password)
found_user.password_token = None
found_user.save()
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, your password has been changed.",
receivers=[str(found_user.email)],
html=password_is_changed_template(user_name=found_user.user_tag),
)
if not send_email_completed:
raise HTTPException(
status_code=400, detail="Email can not be sent. Try again later"
)
found_user = Users.filter_one(
Users.password_token == data.password_token,
).data
if not found_user:
return JSONResponse(
content={
"completed": True,
"message": "Password is created successfully",
"data": found_user.get_dict(),
"completed": False,
"message": "Record not found",
"data": {},
},
status_code=status.HTTP_200_OK,
status_code=status.HTTP_202_ACCEPTED,
)
found_user.create_password(found_user=found_user, password=data.password)
# send_email_completed = send_email(
# subject=f"Dear {found_user.user_tag}, your password has been changed.",
# receivers=[str(found_user.email)],
# html=password_is_changed_template(user_name=found_user.user_tag),
# )
# if not send_email_completed:
# raise HTTPException(
# status_code=400, detail="Email can not be sent. Try again later"
# )
return JSONResponse(
content={
"completed": True,
"message": "Password is created successfully",
"data": found_user.get_dict(),
},
status_code=status.HTTP_200_OK,
)
class AuthenticationResetPasswordEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"af9e121e-24bb-44ac-a616-471d5754360e": "authentication_reset_password",
}
@classmethod
def authentication_reset_password(cls, data: Forgot):
from sqlalchemy import or_
found_user = Users.query.filter(
or_(
Users.email == str(data.access_key).lower(),
Users.phone_number == str(data.access_key).replace(" ", ""),
),
).first()
if not found_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Given access key or domain is not matching with the any user record.",
)
reset_password_token = found_user.reset_password_token(found_user=found_user)
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, a password reset request has been received.",
receivers=[str(found_user.email)],
html=change_your_password_template(
user_name=found_user.user_tag,
forgot_link=ApiStatic.forgot_link(forgot_key=reset_password_token),
),
)
if not send_email_completed:
raise found_user.raise_http_exception(
status_code=400, message="Email can not be sent. Try again later"
)
return JSONResponse(
content={
"completed": False,
"message": "Record not found",
"data": {},
"completed": True,
"message": "Password change link is sent to your email or phone",
"data": found_user.get_dict(),
},
status_code=status.HTTP_202_ACCEPTED,
status_code=status.HTTP_200_OK,
)
@@ -381,50 +458,55 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
@classmethod
def authentication_disconnect_user(
cls, request: Request, data: Logout, token_dict: dict = None
cls,
request: Request,
data: Logout,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if token_user := get_object_via_access_key(request=request):
found_user = Users.find_one(uu_id=token_user.get("uu_id"))
if not found_user:
return JSONResponse(
content={
"completed": False,
"message": "Invalid data",
"data": None,
},
status_code=status.HTTP_202_ACCEPTED,
found_user = Users.filter_one(
Users.uu_id == token_dict.person_uu_id,
).data
if not found_user:
return JSONResponse(
content={
"completed": False,
"message": "Invalid data",
"data": None,
},
status_code=status.HTTP_202_ACCEPTED,
)
if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id):
for key, token_user in already_tokens.items():
redis_cli.delete(key)
selected_user = Users.filter_one(
Users.uu_id == token_user.get("uu_id"),
)
if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id):
for key in already_tokens:
token_user = json.loads(redis_cli.get(key) or {})
redis_cli.delete(key)
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
selected_user.remove_refresher_token(
domain=data.domain, disconnect=True
)
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
return JSONResponse(
content={
"completed": True,
"message": "All sessions are disconnected",
"data": token_user,
},
status_code=status.HTTP_200_OK,
selected_user.remove_refresher_token(
domain=data.domain, disconnect=True
)
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
return JSONResponse(
content={
"completed": True,
"message": "All sessions are disconnected",
"data": token_user,
},
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={"completed": False, "message": "Invalid data", "data": None},
status_code=status.HTTP_202_ACCEPTED,
@@ -439,47 +521,50 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
@classmethod
def authentication_logout_user(
cls, request: Request, data: Logout, token_dict: dict = None
cls, data: Logout, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
token_user = None
if already_tokens := get_object_via_access_key(request=request):
for key in already_tokens:
token_user = json.loads(redis_cli.get(key) or {})
if token_user.get("domain") == data.domain:
redis_cli.delete(key)
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
selected_user.remove_refresher_token(domain=data.domain)
# UserLogger.log_error(
# str(
# dict(
# user_id=selected_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
from api_services.redis.functions import get_object_via_user_uu_id
if not token_dict:
return JSONResponse(
content={
"completed": True,
"message": "Session is logged out",
"data": token_user,
"completed": False,
"message": "Logout is not successfully completed",
"data": None,
},
status_code=status.HTTP_200_OK,
status_code=status.HTTP_202_ACCEPTED,
)
return JSONResponse(
content={
"completed": False,
"message": "Logout is not successfully completed",
"data": None,
},
status_code=status.HTTP_202_ACCEPTED,
)
token_users = get_object_via_user_uu_id(token_dict.user_uu_id)
for token, token_user in token_users.items():
if token_user["domain"] == data.domain:
selected_user = Users.filter_one(
Users.uu_id == token_dict.user_uu_id,
).data
redis_cli.delete(token)
selected_user.remove_refresher_token(domain=data.domain)
# UserLogger.log_error(
# str(
# dict(
# user_id=selected_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
return JSONResponse(
content={
"completed": True,
"message": "Session is logged out",
"data": token_user,
},
status_code=status.HTTP_200_OK,
)
class AuthenticationRefreshTokenEventMethods(MethodToEvent):
@@ -491,17 +576,23 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
@classmethod
def authentication_refresher_token(
cls, request: Request, data: Remember, token_dict: dict = None
cls,
request: Request,
data: Remember,
token_dict: typing.Union[EmployeeSelection, OccupantSelection],
):
token_refresher = UsersTokens.find_one(
token=data.refresh_token, domain=data.domain
token_refresher = UsersTokens.filter_by_one(
system=True, token=data.refresh_token, domain=data.domain
)
if not token_refresher:
return JSONResponse(
content={"completed": False, "message": "Invalid data", "data": {}},
status_code=status.HTTP_202_ACCEPTED,
)
if found_user := Users.find_one(id=token_refresher.user_id):
if found_user := Users.filter_one(
Users.id == token_refresher.user_id,
*Users.valid_record_args(Users),
):
found_user: Users = found_user
access_key = save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain
@@ -556,7 +647,10 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
@classmethod
def authentication_forgot_password(
cls, request: Request, data: Forgot, token_dict: dict = None
cls,
request: Request,
data: Forgot,
token_dict: typing.Union[EmployeeSelection, OccupantSelection],
):
found_user: Users = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
@@ -615,12 +709,17 @@ class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
@classmethod
def authentication_download_avatar(
cls, request: Request, data: Forgot, token_dict: dict = None
cls,
request: Request,
data: Forgot,
token_dict: typing.Union[EmployeeSelection, OccupantSelection],
):
found_user = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
)
expired_str = str(system_arrow.now() - system_arrow.get(str(found_user.expiry_ends)))
expired_str = str(
system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
)
expired_int = int(
client_arrow.get(
system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
@@ -662,6 +761,9 @@ AuthenticationChangePasswordEventMethod = AuthenticationChangePasswordEventMetho
AuthenticationCreatePasswordEventMethod = AuthenticationCreatePasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/create_password")
)
AuthenticationResetPasswordEventMethod = AuthenticationResetPasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/reset_password")
)
AuthenticationDisconnectUserEventMethod = AuthenticationDisconnectUserEventMethods(
action=ActionsSchema(endpoint="/authentication/disconnect")
)

View File

@@ -15,18 +15,24 @@ from databases import (
from api_validations.validations_request import RegisterEvents2Occupant
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class EventBindOccupantEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"5702f0a9-fe8f-4aae-922e-6e04b497ef6a": "bind_events_occupant_super_user",
}
__event_validation__ = {
"5702f0a9-fe8f-4aae-922e-6e04b497ef6a": RegisterEvents2Occupant
}
@classmethod
def bind_events_occupant_super_user(
cls, data: RegisterEvents2Occupant, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: RegisterEvents2Occupant,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if not str(token_dict.user_type) == "1":
@@ -35,7 +41,10 @@ class EventBindOccupantEventMethods(MethodToEvent):
detail="This employee is not authorized to add event to this occupant",
)
occupants_build_part = BuildParts.find_one(uu_id=data.build_part_uu_id)
occupants_build_part = BuildParts.filter_one(
BuildParts.uu_id == data.build_part_uu_id,
BuildParts.active == True,
).data
if not occupants_build_part:
return JSONResponse(
content={
@@ -46,7 +55,9 @@ class EventBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
occupant_occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
occupant_occupant_type = OccupantTypes.filter_by_one(
uu_id=data.occupant_uu_id
).data
if not occupant_occupant_type:
return JSONResponse(
content={
@@ -57,8 +68,8 @@ class EventBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
events_to_add_to_occupant = Events.filter_active(
Events.uu_id.in_(list(data.event_uu_id_list))
events_to_add_to_occupant = Events.filter_all(
Events.uu_id.in_(list(data.event_uu_id_list)),
)
if not events_to_add_to_occupant.data:
return JSONResponse(
@@ -83,11 +94,11 @@ class EventBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_401_UNAUTHORIZED,
)
occupant_to_add_event = BuildLivingSpace.find_one(
build_parts_id=occupants_build_part.id,
occupant_type=occupant_occupant_type.id,
)
occupant_to_add_event = BuildLivingSpace.filter_one(
BuildLivingSpace.build_parts_id == occupants_build_part.id,
BuildLivingSpace.occupant_type == occupant_occupant_type.id,
BuildLivingSpace.active == True,
).data
if not occupant_to_add_event:
return JSONResponse(
content={
@@ -135,10 +146,15 @@ class EventBindEmployeeEventMethods(MethodToEvent):
__event_keys__ = {
"c93a3009-65a0-498d-9191-04484d5cde81": "bind_events_employee",
}
__event_validation__ = {
"c93a3009-65a0-498d-9191-04484d5cde81": RegisterEvents2Occupant
}
@classmethod
def bind_events_employee(
cls, data: RegisterEvents2Occupant, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: RegisterEvents2Occupant,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@@ -10,6 +10,7 @@ from api_configs.configs import (
TestMongo,
RelationAccess,
EmailConfig,
TestDatabase,
)
__all__ = [
@@ -24,4 +25,5 @@ __all__ = [
"TestMongo",
"RelationAccess",
"EmailConfig",
"TestDatabase",
]

View File

@@ -19,17 +19,24 @@ class Config:
"/test/create/test/gateway",
"/test/create/test/company",
"/infos/current_date",
"/authentication/select",
"/authentication/login",
"/authentication/logout",
"/authentication/refresher",
"/authentication/refresh",
"/authentication/disconnect",
"/authentication/create_password",
"/authentication/change_password",
"/authentication/reset_password",
"/authentication/forgot",
"/authentication/avatar",
"/authentication/valid",
"/api/Contact/Us/current_date",
]
NOT_SECURE_PATHS = [
"/access/endpoints/available",
"/access/endpoint/available",
"/validations/endpoint",
"/authentication/avatar",
]
APP_NAME = "evyos-web-api-gateway"
TITLE = "WAG API Web Api Gateway"
@@ -39,7 +46,7 @@ class Config:
class ApiStatic:
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg"
FORGOT_LINK = "https://www.evyos.com.tr/auth/create-password/"
FORGOT_LINK = "https://www.evyos.com.tr/password/create?tokenUrl="
BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
@@ -117,7 +124,7 @@ class TestDatabase:
SQL: str = "postgresql+psycopg2"
USERNAME: str = "berkay_wag_user"
PASSWORD: str = "berkay_wag_user_password"
HOST: str = "10.10.2.44"
HOST: str = "10.10.2.46"
PORT: str = "5434"
DATABASE_NAME: str = "wag_database"
DATABASE_URL = f"{SQL}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE_NAME}"
@@ -148,7 +155,7 @@ class EmailConfig:
EMAIL_USERNAME: str = "karatay@mehmetkaratay.com.tr"
EMAIL_PASSWORD: str = "system"
class RelationAccess:
# 77 Evyos superuser of Superuser - 78 all company superuser - 98 Manager of 77 & 78
SuperAccessList = ["77", "78", "98"]

View File

@@ -1,7 +1,6 @@
from api_events.events.identity.people import (
PeopleListEventMethod,
PeopleCreateEventMethod,
PeopleDeleteEventMethod,
PeopleUpdateEventMethod,
PeoplePatchEventMethod,
)
@@ -15,19 +14,26 @@ from api_events.events.address.address import (
AddressPostCodeUpdateEventMethod,
AddressPostCodeListEventMethod,
)
from api_events.events.authentication import (
from api_events.events.application.authentication import (
AuthenticationLoginEventMethod,
AuthenticationSelectEventMethod,
AuthenticationCheckTokenEventMethod,
AuthenticationRefreshEventMethod,
AuthenticationChangePasswordEventMethod,
AuthenticationCreatePasswordEventMethod,
AuthenticationResetPasswordEventMethod,
AuthenticationDisconnectUserEventMethod,
AuthenticationLogoutEventMethod,
AuthenticationRefreshTokenEventMethod,
AuthenticationForgotPasswordEventMethod,
AuthenticationDownloadAvatarEventMethod,
)
from api_events.events.account.account_records import (
AccountRecordsListEventMethod,
AccountRecordsCreateEventMethod,
AccountRecordsUpdateEventMethod,
AccountRecordsPatchEventMethod,
)
from api_events.events.identity.users import (
UserListEventMethod,
UserCreateEventMethod,
@@ -46,6 +52,20 @@ from api_events.events.building.building_build_parts import (
BuildingBuildPartsUpdateEventMethod,
BuildingBuildPartsPatchEventMethod,
)
from api_events.events.building.building_build_area import (
BuildAreaListEventMethod,
BuildAreaCreateEventMethod,
BuildAreaUpdateEventMethod,
BuildAreaPatchEventMethod,
)
from api_events.events.building.building_build_sites import (
BuildSitesListEventMethod,
BuildSitesCreateEventMethod,
BuildSitesUpdateEventMethod,
)
from api_events.events.building.building_build_types import (
BuildTypesListEventMethod,
)
from api_events.events.company.company_company import (
CompanyListEventMethod,
CompanyCreateEventMethod,
@@ -87,9 +107,9 @@ from api_events.events.company.company_staff import (
StaffPatchEventMethod,
)
from api_events.events.building.building_living_spaces import (
BuildingLivingSpacesPartsListEventMethod,
BuildingLivingSpacesPartsCreateEventMethod,
BuildingLivingSpacesPartsUpdateEventMethod,
BuildingLivingSpacesListEventMethod,
BuildingLivingSpacesCreateEventMethod,
BuildingLivingSpacesUpdateEventMethod,
)
from api_events.events.decision_book.decision_book_decision_book import (
DecisionBookListEventMethod,
@@ -104,10 +124,30 @@ from api_events.events.decision_book.decision_book_decision_book_items import (
DecisionBookDecisionBookItemsUpdateEventMethod,
DecisionBookDecisionBookItemsPatchEventMethod,
)
from api_events.events.events.events_bind_events import (
EventBindOccupantEventMethod,
EventBindEmployeeEventMethod,
from api_events.events.decision_book.project_decision_book import (
ProjectDecisionBookListEventMethod,
ProjectDecisionBookCreateEventMethod,
ProjectDecisionBookUpdateEventMethod,
ProjectDecisionBookApprovalEventMethod,
ProjectDecisionBookPatchEventMethod,
)
from api_events.events.decision_book.project_decision_book_person import (
ProjectDecisionBookPersonListEventMethod,
ProjectDecisionBookPersonCreateEventMethod,
ProjectDecisionBookPersonUpdateEventMethod,
ProjectDecisionBookPersonPatchEventMethod,
)
from api_events.events.decision_book.project_decision_book_items import (
BuildDecisionBookProjectItemsPatchEventMethod,
BuildDecisionBookProjectItemsUpdateEventMethod,
BuildDecisionBookProjectItemsCreateEventMethod,
BuildDecisionBookProjectItemsListEventMethod,
)
# from api_events.events.events.events_ import (
# EventBindOccupantEventMethod,
# EventBindEmployeeEventMethod,
# )
from api_events.events.events.events_bind_services import (
ServiceBindOccupantEventMethod,
ServiceBindEmployeeEventMethod,
@@ -124,6 +164,11 @@ from api_events.events.decision_book.decision_book_invitations import (
BuildDecisionBookInvitationsCreateEventMethod,
BuildDecisionBookInvitationsUpdateEventMethod,
)
from api_events.events.events.events_events import (
EventsBindEventToEmployeeMethod,
EventsBindEventToOccupantMethod,
EventsListEventMethod,
)
__all__ = [
@@ -136,7 +181,6 @@ __all__ = [
"AddressPostCodeUpdateEventMethod",
"AddressPostCodeListEventMethod",
"PeopleListEventMethod",
"PeopleDeleteEventMethod",
"PeopleUpdateEventMethod",
"PeoplePatchEventMethod",
"PeopleCreateEventMethod",
@@ -146,11 +190,16 @@ __all__ = [
"AuthenticationRefreshEventMethod",
"AuthenticationChangePasswordEventMethod",
"AuthenticationCreatePasswordEventMethod",
"AuthenticationResetPasswordEventMethod",
"AuthenticationDisconnectUserEventMethod",
"AuthenticationLogoutEventMethod",
"AuthenticationRefreshTokenEventMethod",
"AuthenticationForgotPasswordEventMethod",
"AuthenticationDownloadAvatarEventMethod",
"AccountRecordsListEventMethod",
"AccountRecordsCreateEventMethod",
"AccountRecordsUpdateEventMethod",
"AccountRecordsPatchEventMethod",
"UserListEventMethod",
"UserCreateEventMethod",
"UserUpdateEventMethod",
@@ -163,9 +212,17 @@ __all__ = [
"BuildingBuildPartsCreateEventMethod",
"BuildingBuildPartsUpdateEventMethod",
"BuildingBuildPartsPatchEventMethod",
"BuildingLivingSpacesPartsListEventMethod",
"BuildingLivingSpacesPartsCreateEventMethod",
"BuildingLivingSpacesPartsUpdateEventMethod",
"BuildingLivingSpacesListEventMethod",
"BuildingLivingSpacesCreateEventMethod",
"BuildingLivingSpacesUpdateEventMethod",
"BuildAreaListEventMethod",
"BuildAreaCreateEventMethod",
"BuildAreaUpdateEventMethod",
"BuildAreaPatchEventMethod",
"BuildSitesListEventMethod",
"BuildSitesCreateEventMethod",
"BuildSitesUpdateEventMethod",
"BuildTypesListEventMethod",
"DecisionBookListEventMethod",
"DecisionBookCreateEventMethod",
"DecisionBookUpdateEventMethod",
@@ -178,6 +235,19 @@ __all__ = [
"DecisionBookDecisionBookItemsCreateEventMethod",
"DecisionBookDecisionBookItemsUpdateEventMethod",
"DecisionBookDecisionBookItemsPatchEventMethod",
"ProjectDecisionBookListEventMethod",
"ProjectDecisionBookCreateEventMethod",
"ProjectDecisionBookUpdateEventMethod",
"ProjectDecisionBookApprovalEventMethod",
"ProjectDecisionBookPatchEventMethod",
"ProjectDecisionBookPersonListEventMethod",
"ProjectDecisionBookPersonCreateEventMethod",
"ProjectDecisionBookPersonUpdateEventMethod",
"ProjectDecisionBookPersonPatchEventMethod",
"BuildDecisionBookProjectItemsPatchEventMethod",
"BuildDecisionBookProjectItemsUpdateEventMethod",
"BuildDecisionBookProjectItemsCreateEventMethod",
"BuildDecisionBookProjectItemsListEventMethod",
"CompanyPatchEventMethod",
"CompanyCreateEventMethod",
"CompanyUpdateEventMethod",
@@ -206,8 +276,8 @@ __all__ = [
"StaffGetByUUIDEventMethod",
"StaffUpdateEventMethod",
"StaffPatchEventMethod",
"EventBindOccupantEventMethod",
"EventBindEmployeeEventMethod",
# "EventBindOccupantEventMethod",
# "EventBindEmployeeEventMethod",
"ServiceBindOccupantEventMethod",
"ServiceBindEmployeeEventMethod",
"BuildDecisionBookInvitationsListEventMethod",
@@ -215,4 +285,7 @@ __all__ = [
"BuildDecisionBookInvitationsUpdateEventMethod",
"DecisionBookPersonAttendEventMethod",
"DecisionBookPersonAssignOccupantEventMethod",
"EventsBindEventToEmployeeMethod",
"EventsBindEventToOccupantMethod",
"EventsListEventMethod",
]

View File

@@ -13,9 +13,9 @@ class ActionsSchema(ABC):
def retrieve_action_from_endpoint(self):
from databases import EndpointRestriction
endpoint_restriction = EndpointRestriction.filter_all(
EndpointRestriction.endpoint_name.ilike(f"%{self.endpoint}%")
).get(1)
endpoint_restriction = EndpointRestriction.filter_one(
EndpointRestriction.endpoint_name.ilike(f"%{self.endpoint}%"), system=True
).data
if not endpoint_restriction:
raise HTTPException(
status_code=404,
@@ -32,16 +32,18 @@ class ActionsSchemaFactory:
self.action_match = self.action.retrieve_action_from_endpoint()
except Exception as e:
err = e
self.action_match = None
print(f"ActionsSchemaFactory Error: {e}")
class MethodToEvent(ABC, ActionsSchemaFactory):
action_key: str = None
event_type: str = None
event_description: str = ""
event_category: str = ""
__event_keys__: dict = {}
__event_validation__: dict = {}
@classmethod
def call_event_method(cls, method_uu_id: str, *args, **kwargs):
@@ -50,9 +52,9 @@ class MethodToEvent(ABC, ActionsSchemaFactory):
@classmethod
def ban_token_objects(
cls,
token: typing.Union[EmployeeTokenObject, OccupantTokenObject],
ban_list: typing.Union[EmployeeTokenObject, OccupantTokenObject],
cls,
token: typing.Union[EmployeeTokenObject, OccupantTokenObject],
ban_list: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
from fastapi import status
from fastapi.exceptions import HTTPException

View File

@@ -1,4 +0,0 @@
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
class ApiEvents(MethodToEvent): ...

View File

@@ -0,0 +1,347 @@
import typing
from api_library.date_time_actions.date_functions import system_arrow
from api_validations.validations_request import (
InsertAccountRecord,
UpdateAccountRecord,
ListOptions,
)
from api_validations.core_response import AlchemyJsonResponse
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.validations_response.account import AccountListResponse
from databases import (
AccountRecords,
BuildIbans,
)
from databases.sql_models.building.build import Build, BuildLivingSpace
from databases.sql_models.building.decision_book import BuildDecisionBookPayments
from databases.sql_models.others.enums import ApiEnumDropdown
class AccountRecordsListEventMethods(MethodToEvent):
event_type = "SELECT"
event_description = ""
event_category = ""
__event_keys__ = {
"7192c2aa-5352-4e36-98b3-dafb7d036a3d": "account_records_list",
"208e6273-17ef-44f0-814a-8098f816b63a": "account_records_list_flt_res",
}
__event_validation__ = {
"7192c2aa-5352-4e36-98b3-dafb7d036a3d": AccountListResponse,
"208e6273-17ef-44f0-814a-8098f816b63a": AccountListResponse,
}
@classmethod
def account_records_list(
cls,
list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
AccountRecords.pre_query = AccountRecords.filter_all(
AccountRecords.company_id
== token_dict.selected_occupant.responsible_company_id,
)
elif isinstance(token_dict, EmployeeTokenObject):
AccountRecords.pre_query = AccountRecords.filter_all(
AccountRecords.company_id == token_dict.selected_company.company_id,
)
AccountRecords.filter_attr = list_options
records = AccountRecords.filter_all()
return AlchemyJsonResponse(
completed=True, message="List Build record", result=records
)
@classmethod
def account_records_list_flt_res(
cls,
list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if not isinstance(token_dict, OccupantTokenObject):
raise AccountRecords().raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message="Only Occupant can see this data",
data={},
)
return_list = []
living_space: BuildLivingSpace = BuildLivingSpace.filter_by_one(
id=token_dict.selected_occupant.living_space_id
).data
if not living_space:
raise AccountRecords().raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message="Living space not found",
data={},
)
if not list_options:
list_options = ListOptions()
main_filters = [
AccountRecords.living_space_id
== token_dict.selected_occupant.living_space_id,
BuildDecisionBookPayments.process_date
>= str(system_arrow.now().shift(months=-3).date()),
BuildDecisionBookPayments.process_date
< str(system_arrow.find_last_day_of_month(living_space.expiry_ends)),
BuildDecisionBookPayments.process_date
>= str(system_arrow.get(living_space.expiry_starts)),
BuildDecisionBookPayments.is_confirmed == True,
AccountRecords.active == True,
]
order_type = "desc"
if list_options.order_type:
order_type = "asc" if list_options.order_type[0] == "a" else "desc"
order_by_list = BuildDecisionBookPayments.process_date.desc()
if list_options.order_field:
if list_options.order_field == "process_date":
order_by_list = (
BuildDecisionBookPayments.process_date.asc()
if order_type == "asc"
else BuildDecisionBookPayments.process_date.desc()
)
if list_options.order_field == "bank_date":
order_by_list = (
AccountRecords.bank_date.desc()
if order_type == "asc"
else AccountRecords.bank_date.asc()
)
if list_options.order_field == "currency_value":
order_by_list = (
AccountRecords.currency_value.desc()
if order_type == "asc"
else AccountRecords.currency_value.asc()
)
if list_options.order_field == "process_comment":
order_by_list = (
AccountRecords.process_comment.desc()
if order_type == "asc"
else AccountRecords.process_comment.asc()
)
if list_options.order_field == "payment_amount":
order_by_list = (
BuildDecisionBookPayments.payment_amount.desc()
if order_type == "asc"
else BuildDecisionBookPayments.payment_amount.asc()
)
if list_options.query:
for key, value in list_options.query.items():
if key == "process_date":
main_filters.append(BuildDecisionBookPayments.process_date == value)
if key == "bank_date":
main_filters.append(AccountRecords.bank_date == value)
if key == "currency":
main_filters.append(BuildDecisionBookPayments.currency == value)
if key == "currency_value":
main_filters.append(AccountRecords.currency_value == value)
if key == "process_comment":
main_filters.append(AccountRecords.process_comment == value)
if key == "payment_amount":
main_filters.append(
BuildDecisionBookPayments.payment_amount == value
)
query = (
AccountRecords.session.query(
BuildDecisionBookPayments.process_date,
BuildDecisionBookPayments.payment_amount,
BuildDecisionBookPayments.currency,
AccountRecords.bank_date,
AccountRecords.currency_value,
AccountRecords.process_comment,
BuildDecisionBookPayments.uu_id,
)
.join(
AccountRecords,
AccountRecords.id == BuildDecisionBookPayments.account_records_id,
)
.filter(*main_filters)
).order_by(order_by_list)
query.limit(list_options.size or 5).offset(
(list_options.page or 1 - 1) * list_options.size or 5
)
for list_of_values in query.all() or []:
return_list.append(
{
"process_date": list_of_values[0],
"payment_amount": list_of_values[1],
"currency": list_of_values[2],
"bank_date": list_of_values[3],
"currency_value": list_of_values[4],
"process_comment": list_of_values[5],
}
)
return dict(completed=True, message="List Build record", result=return_list)
class AccountRecordsCreateEventMethods(MethodToEvent):
event_type = "CREATE"
event_description = ""
event_category = ""
__event_keys__ = {
"31f4f32f-0cd4-4995-8a6a-f9f56335848a": "account_records_create",
}
__event_validation__ = {
"31f4f32f-0cd4-4995-8a6a-f9f56335848a": InsertAccountRecord,
}
@classmethod
def account_records_create(
cls,
data: InsertAccountRecord,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
data_dict = data.excluded_dump()
if isinstance(token_dict, OccupantTokenObject):
build_iban = BuildIbans.filter_one(
BuildIbans.iban == data.iban,
BuildIbans.build_id == token_dict.selected_occupant.build_id,
).data
if not build_iban:
BuildIbans.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message=f"{data.iban} is not found in company related to your organization",
data={
"iban": data.iban,
},
)
account_record = AccountRecords.find_or_create(**data.excluded_dump())
return AlchemyJsonResponse(
completed=True,
message="Update Build record",
result=account_record.get_dict(),
)
elif isinstance(token_dict, EmployeeTokenObject):
# Build.pre_query = Build.select_action(
# employee_id=token_dict.selected_employee.employee_id,
# )
# build_ids_list = Build.filter_all(
# )
# build_iban = BuildIbans.filter_one(
# BuildIbans.iban == data.iban,
# BuildIbans.build_id.in_([build.id for build in build_ids_list.data]),
# ).data
# if not build_iban:
# BuildIbans.raise_http_exception(
# status_code="HTTP_404_NOT_FOUND",
# error_case="UNAUTHORIZED",
# message=f"{data.iban} is not found in company related to your organization",
# data={
# "iban": data.iban,
# },
# )
bank_date = system_arrow.get(data.bank_date)
data_dict["bank_date_w"] = bank_date.weekday()
data_dict["bank_date_m"] = bank_date.month
data_dict["bank_date_d"] = bank_date.day
data_dict["bank_date_y"] = bank_date.year
if int(data.currency_value) < 0:
debit_type = ApiEnumDropdown.filter_by_one(
system=True, enum_class="DebitTypes", key="DT-D"
).data
data_dict["receive_debit"] = debit_type.id
data_dict["receive_debit_uu_id"] = str(debit_type.uu_id)
else:
debit_type = ApiEnumDropdown.filter_by_one(
system=True, enum_class="DebitTypes", key="DT-R"
).data
data_dict["receive_debit"] = debit_type.id
data_dict["receive_debit_uu_id"] = str(debit_type.uu_id)
account_record = AccountRecords.find_or_create(**data_dict)
account_record.save()
account_record.update(is_confirmed=True)
account_record.save()
return AlchemyJsonResponse(
completed=True,
message="Create Account record are successful",
result=account_record.get_dict(),
)
class AccountRecordsUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
event_description = ""
event_category = ""
__event_keys__ = {
"ec98ef2c-bcd0-432d-a8f4-1822a56c33b2": "account_records_update",
}
__event_validation__ = {
"ec98ef2c-bcd0-432d-a8f4-1822a56c33b2": UpdateAccountRecord,
}
@classmethod
def build_area_update(
cls,
build_uu_id: str,
data: UpdateAccountRecord,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
pass
elif isinstance(token_dict, EmployeeTokenObject):
pass
return AlchemyJsonResponse(
completed=False,
message="Update Build record",
result=None,
)
class AccountRecordsPatchEventMethods(MethodToEvent):
event_type = "PATCH"
event_description = ""
event_category = ""
__event_keys__ = {
"34c38937-42a2-45f1-b2ef-a23978650aee": "account_records_patch",
}
__event_validation__ = {
"34c38937-42a2-45f1-b2ef-a23978650aee": None,
}
@classmethod
def build_area_patch(
cls,
build_uu_id: str,
data,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
return AlchemyJsonResponse(
completed=False,
message="Patch Build record",
result=None,
)
AccountRecordsListEventMethod = AccountRecordsListEventMethods(
action=ActionsSchema(endpoint="/account/records/list")
)
AccountRecordsCreateEventMethod = AccountRecordsCreateEventMethods(
action=ActionsSchema(endpoint="/account/records/create")
)
AccountRecordsUpdateEventMethod = AccountRecordsUpdateEventMethods(
action=ActionsSchema(endpoint="/account/records/update")
)
AccountRecordsPatchEventMethod = AccountRecordsPatchEventMethods(
action=ActionsSchema(endpoint="/account/records/patch")
)

View File

@@ -1,6 +1,12 @@
from typing import Union
from fastapi.exceptions import HTTPException
from fastapi.responses import JSONResponse
from api_validations.validations_response.address import (
ListAddressResponse,
AddressPostCodeResponse,
)
from databases import (
AddressPostcode,
Addresses,
@@ -8,14 +14,15 @@ from databases import (
AddressStreet,
)
from api_validations.validations_request import (
ListOptions,
InsertAddress,
UpdateAddress,
InsertPostCode,
SearchAddress
UpdatePostCode,
SearchAddress,
)
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
@@ -23,16 +30,25 @@ from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObj
class AddressListEventMethods(MethodToEvent):
event_type = "SELECT"
event_description = "List Address records"
event_category = "Address"
__event_keys__ = {
"9c251d7d-da70-4d63-a72c-e69c26270442": "address_list_super_user", # 1
"9c251d7d-da70-4d63-a72c-e69c26270442": "address_list_super_user",
"52afe375-dd95-4f4b-aaa2-4ec61bc6de52": "address_list_employee",
}
__event_validation__ = {
"9c251d7d-da70-4d63-a72c-e69c26270442": ListAddressResponse,
"52afe375-dd95-4f4b-aaa2-4ec61bc6de52": ListAddressResponse,
}
@classmethod
def address_list_super_user(cls, list_options: ListOptions, token_dict):
from sqlalchemy import select
post_code_list = RelationshipEmployee2PostCode.filter_active(
def address_list_super_user(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
post_code_list = RelationshipEmployee2PostCode.filter_all(
RelationshipEmployee2PostCode.company_id
== token_dict.selected_company.company_id,
).data
@@ -42,45 +58,69 @@ class AddressListEventMethods(MethodToEvent):
status_code=404,
detail="User has no post code registered. User can not list addresses.",
)
get_street_ids = AddressPostcode.session.execute(
select(AddressPostcode.street_id).where(
AddressPostcode.id.in_(post_code_id_list)
get_street_ids = [
street_id[0]
for street_id in AddressPostcode.select_only(
AddressPostcode.id.in_(post_code_id_list),
select_args=[AddressPostcode.street_id],
order_by=AddressPostcode.street_id.desc(),
).data
]
if not get_street_ids:
raise HTTPException(
status_code=404,
detail="User has no street registered. User can not list addresses.",
)
).all()
Addresses.pre_query = Addresses.filter_active(
Addresses.street_id.in_(*get_street_ids) if get_street_ids else None
Addresses.pre_query = Addresses.filter_all(
Addresses.street_id.in_(get_street_ids),
).query
Addresses.filter_attr = list_options
records = Addresses.filter_active(
*Addresses.get_smart_query(list_options.query)
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
records = Addresses.filter_all().data
return AlchemyJsonResponse(
completed=True,
message="List Address records",
result=records,
)
@classmethod
def address_list_employee(cls, list_options: ListOptions, token_dict):
def address_list_employee(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
Addresses.filter_attr = list_options
records = Addresses.list_via_employee(
token_dict=token_dict,
filter_expr=Addresses.get_smart_query(list_options.query),
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
return AlchemyJsonResponse(
completed=True,
message="List Address records",
result=records,
)
class AddressCreateEventMethods(MethodToEvent):
event_type = "CREATE"
event_description = ""
event_category = ""
__event_keys__ = {
"ffdc445f-da10-4ce4-9531-d2bdb9a198ae": "create_address",
}
__event_validation__ = {
"ffdc445f-da10-4ce4-9531-d2bdb9a198ae": InsertAddress,
}
@classmethod
def create_address(cls, data: InsertAddress, token_dict):
post_code = AddressPostcode.find_one(uu_id=data.post_code_uu_id)
def create_address(
cls,
data: InsertAddress,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
post_code = AddressPostcode.filter_one(
AddressPostcode.uu_id == data.post_code_uu_id,
).data
if not post_code:
raise HTTPException(
status_code=404,
@@ -89,17 +129,12 @@ class AddressCreateEventMethods(MethodToEvent):
data_dict = data.excluded_dump()
data_dict["street_id"] = post_code.street_id
data_dict["street_uu_id"] = str(post_code.street_uu_id)
del data_dict["post_code_uu_id"]
address = Addresses.find_or_create(**data_dict)
if not address.is_found:
RelationshipEmployee2PostCode.find_or_create(
employee_id=token_dict.selected_company.employee_id,
member_id=post_code.id,
company_id=token_dict.selected_company.company_id,
is_confirmed=True,
)
Addresses.save()
address.save()
address.update(is_confirmed=True)
address.save()
return JSONResponse(
content={
"completed": True,
@@ -113,13 +148,23 @@ class AddressCreateEventMethods(MethodToEvent):
class AddressSearchEventMethods(MethodToEvent):
event_type = "SEARCH"
event_description = ""
event_category = ""
__event_keys__ = {
"e0ac1269-e9a7-4806-9962-219ac224b0d0": "search_address",
}
__event_validation__ = {
"e0ac1269-e9a7-4806-9962-219ac224b0d0": SearchAddress,
}
@classmethod
def search_address(cls, data: SearchAddress, token_dict):
import databases as database_sql_models
def search_address(
cls,
data: SearchAddress,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
import databases.sql_models
from time import perf_counter
st = perf_counter()
@@ -136,7 +181,7 @@ class AddressSearchEventMethods(MethodToEvent):
filter_list["order_field"] = "uu_id"
else:
filter_table = getattr(
database_sql_models, str(filter_list.get("order_field")).split(".")[0]
databases.sql_models, str(filter_list.get("order_field")).split(".")[0]
)
filter_list["order_field"] = str(filter_list.get("order_field")).split(".")[
1
@@ -181,50 +226,76 @@ class AddressSearchEventMethods(MethodToEvent):
class AddressUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
event_description = ""
event_category = ""
__event_keys__ = {
"1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27": "update_address",
}
__event_validation__ = {
"1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27": UpdateAddress,
}
@classmethod
def update_address(cls, address_uu_id: str, data: InsertAddress, token_dict):
address = Addresses.find_one_or_abort(uu_id=address_uu_id)
post_code = RelationshipEmployee2PostCode.postcode.find_one(
member_id=address.post_code_id
)
if not post_code:
raise HTTPException(
status_code=404,
detail="Post code not found. User can not update address without post code.",
def update_address(
cls,
address_uu_id: str,
data: UpdateAddress,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
address = Addresses.filter_one(
Addresses.uu_id == address_uu_id,
).data
if not address:
raise HTTPException(
status_code=404,
detail=f"Address not found. User can not update with given address uuid : {address_uu_id}",
)
data_dict = data.excluded_dump()
updated_address = address.update(**data_dict)
updated_address.save()
return JSONResponse(
content={
"completed": True,
"message": "Update Address record",
"data": updated_address.get_dict(),
},
status_code=200,
)
elif isinstance(token_dict, OccupantTokenObject):
raise HTTPException(
status_code=403,
detail="Occupant can not update address.",
)
data_dict = data.excluded_dump()
data_dict["post_code_id"] = post_code.id
del data_dict["post_code_uu_id"]
updated_address = address.update(**data_dict)
updated_address.save()
return JSONResponse(
content={
"completed": True,
"message": "Update Address record",
"data": updated_address.get_dict(),
},
status_code=200,
)
class AddressPatchEventMethods(MethodToEvent):
event_type = "PATCH"
event_description = ""
event_category = ""
__event_keys__ = {
"b0e55a7e-af81-468c-b46c-a6b3a6b68d5d": "patch_address",
}
__event_validation__ = {
"b0e55a7e-af81-468c-b46c-a6b3a6b68d5d": None,
}
@classmethod
def patch_address(cls, address_uu_id: str, data: InsertAddress, token_dict):
address = Addresses.find_one_or_abort(uu_id=address_uu_id)
def patch_address(
cls,
address_uu_id: str,
data: InsertAddress,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
address = Addresses.filter_one(
Addresses.uu_id == address_uu_id,
).data
post_code = RelationshipEmployee2PostCode.filter_one(
RelationshipEmployee2PostCode.member_id==address.post_code_id
RelationshipEmployee2PostCode.member_id == address.post_code_id,
)
if not post_code:
raise HTTPException(
@@ -250,14 +321,26 @@ class AddressPatchEventMethods(MethodToEvent):
class AddressPostCodeCreateEventMethods(MethodToEvent):
event_type = "CREATE"
event_description = ""
event_category = ""
__event_keys__ = {
"6f1406ac-577d-4f2c-8077-71fff2252c5f": "create_post_code_address",
}
__event_validation__ = {
"6f1406ac-577d-4f2c-8077-71fff2252c5f": InsertPostCode,
}
@classmethod
def create_post_code_address(cls, data: InsertPostCode, token_dict):
def create_post_code_address(
cls,
data: InsertPostCode,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
data_dump = data.excluded_dump()
street = AddressStreet.find_one(uu_id=data.street_uu_id)
street = AddressStreet.filter_one(
AddressStreet.uu_id == data.street_uu_id,
).data
if not street:
raise HTTPException(
status_code=404,
@@ -265,17 +348,19 @@ class AddressPostCodeCreateEventMethods(MethodToEvent):
)
data_dump["street_id"] = street.id
data_dump["postcode"] = data.post_code
del data_dump["street_uu_id"], data_dump["post_code"]
del data_dump["post_code"]
post_code = AddressPostcode.find_or_create(**data_dump)
if not post_code.is_found:
AddressPostcode.__many__table__.find_or_create(
member_id=post_code.id,
employee_id=token_dict.selected_company.employee_id,
company_id=token_dict.selected_company.company_id,
is_confirmed=True,
)
AddressStreet.save()
relation_table = AddressPostcode.__many__table__.find_or_create(
member_id=post_code.id,
employee_id=token_dict.selected_company.employee_id,
company_id=token_dict.selected_company.company_id,
)
post_code.save()
post_code.update(is_confirmed=True)
post_code.save()
relation_table.update(is_confirmed=True)
relation_table.save()
return JSONResponse(
content={
"completed": True,
@@ -289,46 +374,84 @@ class AddressPostCodeCreateEventMethods(MethodToEvent):
class AddressPostCodeUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
event_description = ""
event_category = ""
__event_keys__ = {
"df18e489-a63c-477f-984c-aa52d30640ad": "update_post_code_address",
}
__event_validation__ = {
"df18e489-a63c-477f-984c-aa52d30640ad": UpdatePostCode,
}
@classmethod
def update_post_code_address(
cls, post_code_uu_id: str, data: InsertPostCode, token_dict
cls,
post_code_uu_id: str,
data: UpdatePostCode,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
post_code = AddressPostcode.find_one_or_abort(uu_id=post_code_uu_id)
street = AddressStreet.find_one(uu_id=data.street_uu_id)
if not street:
raise HTTPException(
status_code=404,
detail="Street not found. User can not update post code without street.",
if isinstance(token_dict, EmployeeTokenObject):
AddressPostcode.pre_query = AddressPostcode.select_action(
employee_id=token_dict.selected_company.employee_id,
)
post_code = AddressPostcode.filter_one(
AddressPostcode.uu_id == post_code_uu_id,
).data
if not post_code:
raise HTTPException(
status_code=404,
detail="Street not found. User can not update post code without street.",
)
updated_post_code = post_code.update(**data.excluded_dump())
updated_post_code.save()
data_dict = data.excluded_dump()
updated_post_code = post_code.update(**data_dict)
updated_post_code.save()
return JSONResponse(
content={
"completed": True,
"message": "Update Post Code record",
"data": updated_post_code.get_dict(),
},
status_code=200,
)
elif isinstance(token_dict, OccupantTokenObject):
raise HTTPException(
status_code=403,
detail="Occupant can not update post code.",
)
return JSONResponse(
content={
"completed": True,
"message": "Update Post Code record",
"data": updated_post_code.get_dict(),
"data": {},
},
status_code=200,
status_code=404,
)
class AddressPostCodeListEventMethods(MethodToEvent):
event_type = "SELECT"
event_description = ""
event_category = ""
__event_keys__ = {
"88d37b78-1ac4-4513-9d25-090ac3a24f31": "list_post_code_address",
}
__event_validation__ = {
"88d37b78-1ac4-4513-9d25-090ac3a24f31": AddressPostCodeResponse,
}
@classmethod
def list_post_code_address(cls, list_options: ListOptions, token_dict):
post_code_list = AddressPostcode.__many__table__.filter_active(
def list_post_code_address(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
post_code_list = AddressPostcode.__many__table__.filter_all(
AddressPostcode.__many__table__.company_id
== token_dict.selected_company.company_id
== token_dict.selected_company.company_id,
).data
if not post_code_list:
raise HTTPException(
@@ -336,17 +459,17 @@ class AddressPostCodeListEventMethods(MethodToEvent):
detail="User has no post code registered or not yet any post code created.",
)
AddressPostcode.pre_query = AddressPostcode.filter_active(
AddressPostcode.pre_query = AddressPostcode.filter_all(
AddressPostcode.id.in_(
[post_code.member_id for post_code in post_code_list]
)
),
).query
AddressPostcode.filter_attr = list_options
records = AddressPostcode.filter_active(
*Addresses.get_smart_query(list_options.query)
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
records = AddressPostcode.filter_all().data
return AlchemyJsonResponse(
completed=True,
message="List Address records",
result=records,
)

View File

@@ -1,6 +1,9 @@
import datetime
import json
import typing
from typing import Union
import arrow
from fastapi import status
from fastapi.requests import Request
from fastapi.exceptions import HTTPException
@@ -15,13 +18,13 @@ from databases import (
BuildLivingSpace,
BuildParts,
Build,
RelationshipEmployee2PostCode,
Duty,
Event2Occupant,
Event2Employee,
Users,
UsersTokens,
OccupantTypes,
RelationshipEmployee2Build,
)
from api_services import (
@@ -35,10 +38,16 @@ from api_services import (
change_your_password_template,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_library.date_time_actions.date_functions import DateTimeLocal
from api_configs import ApiStatic, Auth
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects import (
OccupantToken,
CompanyToken,
EmployeeTokenObject,
OccupantTokenObject,
)
from api_library.date_time_actions.date_functions import system_arrow
from databases.no_sql_models.login_handlers import load_user_with_erp_details
from api_validations.validations_request import (
@@ -56,16 +65,21 @@ from api_validations.validations_request import (
class AuthenticationLoginEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Login via domain and access key : [email] | [phone]"
event_category = "AUTHENTICATION"
__event_keys__ = {
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
}
__event_validation__ = {
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
}
@classmethod
def authentication_login_with_domain_and_creds(
cls,
data: Login,
request,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
access_dict = Users.login_user_with_credentials(data=data, request=request)
found_user = access_dict.get("user", None)
@@ -89,23 +103,28 @@ class AuthenticationLoginEventMethods(MethodToEvent):
class AuthenticationSelectEventMethods(MethodToEvent):
event_type = "SELECT"
event_type = "LOGIN"
event_description = "Select Employee Duty or Occupant Type"
event_category = "AUTHENTICATION"
__event_keys__ = {
"cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
}
__event_validation__ = {
"cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
}
@classmethod
def authentication_select_company_or_occupant_type(
cls,
request: Request,
data: typing.Union[EmployeeSelection, OccupantSelection],
token_dict: dict = None,
data: Union[EmployeeSelection, OccupantSelection],
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
from api_objects import OccupantToken, CompanyToken
token_user = get_object_via_access_key(request=request)
if token_user.user_type == 1:
if data.company_uu_id not in token_user.companies_uu_id_list:
if isinstance(token_dict, EmployeeTokenObject):
if data.company_uu_id not in token_dict.companies_uu_id_list:
return JSONResponse(
content={
"completed": False,
@@ -113,41 +132,49 @@ class AuthenticationSelectEventMethods(MethodToEvent):
},
status_code=status.HTTP_401_UNAUTHORIZED,
)
if selected_company := Companies.find_one(uu_id=data.company_uu_id):
if selected_company := Companies.filter_one(
Companies.uu_id == data.company_uu_id,
).data:
department_ids = [
department.id
for department in Departments.filter_by_active(
company_id=selected_company.id
for department in Departments.filter_all(
Departments.company_id == selected_company.id,
).data
]
duties_ids = [
duties.id
for duties in Duties.filter_active(
for duties in Duties.filter_all(
Duties.company_id == selected_company.id,
Duties.department_id.in_(department_ids),
).data
]
staff_ids = [
staff.id
for staff in Staff.filter_active(
Staff.duties_id.in_(duties_ids)
for staff in Staff.filter_all(
Staff.duties_id.in_(duties_ids),
).data
]
employee = Employees.filter_active(
Employees.people_id == token_user.person_id,
employee = Employees.filter_one(
Employees.people_id == token_dict.person_id,
Employees.staff_id.in_(staff_ids),
).data[0]
reachable_event_list_id, reachable_event_list_uu_id = (
Event2Employee.get_event_id_by_employee_id(employee_id=employee.id)
)
staff = Staff.find_one(id=employee.staff_id)
duties = Duties.find_one(id=staff.duties_id)
department = Departments.find_one(id=duties.department_id)
bulk_id = Duty.find_one(duty_code="BULK")
bulk_duty_id = Duties.find_one(
company_id=selected_company.id, duties_id=bulk_id.id
).data
reachable_event_list_id = Event2Employee.get_event_id_by_employee_id(
employee_id=employee.id
)
staff = Staff.filter_one(
Staff.id == employee.staff_id,
).data
duties = Duties.filter_one(
Duties.id == staff.duties_id,
).data
department = Departments.filter_one(
Departments.id == duties.department_id,
).data
bulk_id = Duty.filter_by_one(system=True, duty_code="BULK").data
bulk_duty_id = Duties.filter_by_one(
company_id=selected_company.id,
duties_id=bulk_id.id,
**Duties.valid_record_dict,
).data
update_selected_to_redis(
request=request,
add_payload=CompanyToken(
@@ -163,7 +190,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
employee_id=employee.id,
employee_uu_id=employee.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
),
)
return JSONResponse(
@@ -173,29 +199,41 @@ class AuthenticationSelectEventMethods(MethodToEvent):
},
status_code=status.HTTP_200_OK,
)
elif token_user.user_type == 2:
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
elif isinstance(token_dict, OccupantTokenObject):
occupant_type = OccupantTypes.filter_by_one(
system=True, uu_id=data.occupant_uu_id
).data
if not occupant_type:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Occupant Type is not found",
)
build_part = BuildParts.find_one(uu_id=data.build_part_uu_id)
build_part = BuildParts.filter_by_one(
system=True, uu_id=data.build_part_uu_id
).data
if not build_part:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Build Part is not found",
)
build = Build.find_one(id=build_part.build_id)
related_company = RelationshipEmployee2Build.find_one(member_id=build.id)
company_related = Companies.find_one(id=related_company.company_id)
responsible_employee = Employees.find_one(id=related_company.employee_id)
if selected_occupant_type := BuildLivingSpace.find_one(
occupant_type=occupant_type.id,
person_id=token_user.person_id,
build_parts_id=build_part.id,
):
reachable_event_list_id, reachable_event_list_uu_id = (
build = Build.filter_one(
Build.id == build_part.build_id,
).data
related_company = RelationshipEmployee2Build.filter_one(
RelationshipEmployee2Build.member_id == build.id,
).data
company_related = Companies.filter_one(
Companies.id == related_company.company_id,
).data
responsible_employee = Employees.filter_one(
Employees.id == related_company.employee_id,
).data
if selected_occupant_type := BuildLivingSpace.filter_one(
BuildLivingSpace.occupant_type == occupant_type.id,
BuildLivingSpace.person_id == token_dict.person_id,
BuildLivingSpace.build_parts_id == build_part.id,
).data:
reachable_event_list_id = (
Event2Occupant.get_event_id_by_build_living_space_id(
build_living_space_id=selected_occupant_type.id
)
@@ -217,7 +255,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
responsible_company_id=company_related.id,
responsible_company_uuid=company_related.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
),
)
return JSONResponse(
@@ -235,14 +272,21 @@ class AuthenticationSelectEventMethods(MethodToEvent):
class AuthenticationCheckTokenEventMethods(MethodToEvent):
event_type = "CHECK"
event_type = "LOGIN"
event_description = "Check Token is valid for user"
event_category = "AUTHENTICATION"
__event_keys__ = {
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
}
__event_validation__ = {
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
}
@classmethod
def authentication_login_with_domain_and_creds(
cls, request, token_dict: dict = None
def authentication_check_token_is_valid(
cls,
request,
):
if get_object_via_access_key(request=request):
return JSONResponse(
@@ -257,21 +301,35 @@ class AuthenticationCheckTokenEventMethods(MethodToEvent):
class AuthenticationRefreshEventMethods(MethodToEvent):
event_type = "REFRESH"
event_type = "LOGIN"
event_description = (
"Refresher Token for refreshing access token without credentials"
)
event_category = "AUTHENTICATION"
__event_keys__ = {
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
}
__event_validation__ = {
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
}
@classmethod
def authentication_refresh_user_info(cls, request, token_dict: dict = None):
def authentication_refresh_user_info(
cls,
request,
token_dict: typing.Union[EmployeeSelection, OccupantSelection],
):
access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
if token_user := get_object_via_access_key(request=request):
if found_user := Users.find_one(uu_id=token_user.get("uu_id")):
user_token = UsersTokens.find_one(
domain=found_user.domain_name,
user_id=found_user.id,
token_type="RememberMe",
)
if found_user := Users.filter_one(
Users.uu_id == token_user.get("uu_id")
).data:
user_token = UsersTokens.filter_one(
UsersTokens.domain == found_user.domain_name,
UsersTokens.user_id == found_user.id,
UsersTokens.token_type == "RememberMe",
).data
access_dict = {
"access_token": access_token,
"refresh_token": getattr(user_token, "token", None),
@@ -292,18 +350,25 @@ class AuthenticationRefreshEventMethods(MethodToEvent):
class AuthenticationChangePasswordEventMethods(MethodToEvent):
event_type = "UPDATE"
event_type = "LOGIN"
event_description = "Change password with access token implemented on request headers without password reset token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
}
__event_validation__ = {
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
}
@classmethod
def authentication_change_password(
cls, request, data: ChangePassword, token_dict: dict = None
cls,
data: ChangePassword,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
token_user = get_object_via_access_key(request=request)
if token_user.user_type == 1:
if found_user := Users.find_one(uu_id=token_user.uu_id):
if isinstance(token_dict, EmployeeTokenObject):
if found_user := Users.filter_one(Users.uu_id == token_dict.uu_id).data:
if found_user.check_password(data.old_password):
found_user.set_password(data.new_password)
return JSONResponse(
@@ -328,23 +393,29 @@ class AuthenticationChangePasswordEventMethods(MethodToEvent):
class AuthenticationCreatePasswordEventMethods(MethodToEvent):
event_type = "CREATE"
event_type = "LOGIN"
event_description = "Create password with password reset token requested via email"
event_category = "AUTHENTICATION"
__event_keys__ = {
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
}
__event_validation__ = {
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
}
@classmethod
def authentication_create_password(
cls, request, data: CreatePassword, token_dict: dict = None
):
def authentication_create_password(cls, data: CreatePassword):
if not data.re_password == data.password:
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
)
if found_user := Users.find_one(password_token=data.password_token):
found_user.create_password(password=data.password)
found_user.password_token = None
if found_user := Users.filter_one(
Users.password_token == data.password_token
).data:
found_user.create_password(found_user=found_user, password=data.password)
found_user.password_token = ""
found_user.save()
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, your password has been changed.",
@@ -375,55 +446,45 @@ class AuthenticationCreatePasswordEventMethods(MethodToEvent):
class AuthenticationDisconnectUserEventMethods(MethodToEvent):
event_type = "UPDATE"
event_type = "LOGIN"
event_description = "Disconnect all sessions of user in access token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
}
__event_validation__ = {
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
}
@classmethod
def authentication_disconnect_user(
cls, request: Request, data: Logout, token_dict: dict = None
cls, data: Logout, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
if token_user := get_object_via_access_key(request=request):
found_user = Users.find_one(uu_id=token_user.get("uu_id"))
if not found_user:
return JSONResponse(
content={
"completed": False,
"message": "Invalid data",
"data": None,
},
status_code=status.HTTP_202_ACCEPTED,
found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
if not found_user:
return JSONResponse(
content={
"completed": False,
"message": "Invalid data",
"data": None,
},
status_code=status.HTTP_202_ACCEPTED,
)
if already_tokens := get_object_via_user_uu_id(user_id=str(found_user.uu_id)):
for key, token_user in already_tokens.items():
redis_cli.delete(key)
selected_user = Users.filter_one(
Users.uu_id == token_user.get("uu_id"),
).data
selected_user.remove_refresher_token(
domain=data.domain, disconnect=True
)
if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id):
for key in already_tokens:
token_user = json.loads(redis_cli.get(key) or {})
redis_cli.delete(key)
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
selected_user.remove_refresher_token(
domain=data.domain, disconnect=True
)
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
return JSONResponse(
content={
"completed": True,
"message": "All sessions are disconnected",
"data": token_user,
"data": selected_user.get_dict(),
},
status_code=status.HTTP_200_OK,
)
@@ -434,10 +495,17 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
class AuthenticationLogoutEventMethods(MethodToEvent):
event_type = "UPDATE"
event_type = "LOGIN"
event_description = "Logout only single session of user which domain is provided"
event_category = "AUTHENTICATION"
__event_keys__ = {
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
}
__event_validation__ = {
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
}
@classmethod
def authentication_logout_user(
@@ -449,23 +517,11 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
token_user = json.loads(redis_cli.get(key) or {})
if token_user.get("domain") == data.domain:
redis_cli.delete(key)
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
selected_user = Users.filter_one(
Users.uu_id == token_user.get("uu_id"),
).data
selected_user.remove_refresher_token(domain=data.domain)
# UserLogger.log_error(
# str(
# dict(
# user_id=selected_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
return JSONResponse(
content={
"completed": True,
@@ -486,24 +542,34 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
class AuthenticationRefreshTokenEventMethods(MethodToEvent):
event_type = "UPDATE"
event_type = "LOGIN"
event_description = "Refresh access token with refresher token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
}
__event_validation__ = {
"c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
}
@classmethod
def authentication_refresher_token(
cls, request: Request, data: Remember, token_dict: dict = None
):
token_refresher = UsersTokens.find_one(
token=data.refresh_token, domain=data.domain
)
token_refresher = UsersTokens.filter_by_one(
token=data.refresh_token,
domain=data.domain,
**UsersTokens.valid_record_dict,
).data
if not token_refresher:
return JSONResponse(
content={"completed": False, "message": "Invalid data", "data": {}},
status_code=status.HTTP_202_ACCEPTED,
)
if found_user := Users.find_one(id=token_refresher.user_id):
if found_user := Users.filter_one(
Users.id == token_refresher.user_id,
).data:
found_user: Users = found_user
access_key = save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain
@@ -513,22 +579,7 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
found_user.last_remote_addr = getattr(
request, "remote_addr", None
) or request.headers.get("X-Forwarded-For", None)
found_user.last_seen = str(DateTimeLocal.now())
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key="via_refresher",
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
found_user.last_seen = str(system_arrow.now())
return JSONResponse(
content={
"completed": True,
@@ -551,14 +602,22 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
class AuthenticationForgotPasswordEventMethods(MethodToEvent):
event_type = "SELECT"
event_type = "LOGIN"
event_description = "Send an email to user for a valid password reset token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
}
__event_validation__ = {
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
}
@classmethod
def authentication_forgot_password(
cls, request: Request, data: Forgot, token_dict: dict = None
cls,
request: Request,
data: Forgot,
):
found_user: Users = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
@@ -566,21 +625,6 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
forgot_key = save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain
)
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=data.access_key,
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=str(DateTimeLocal.now()),
# is_login=False,
# )
# )
# )
forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key)
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, your forgot password link has been sent.",
@@ -593,9 +637,8 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
raise HTTPException(
status_code=400, detail="Email can not be sent. Try again later"
)
found_user.password_token = forgot_key
found_user.password_token_is_valid = str(DateTimeLocal.shift(days=1))
found_user.password_token_is_valid = str(system_arrow.shift(days=1))
found_user.save()
return JSONResponse(
@@ -608,42 +651,96 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
)
class AuthenticationResetPasswordEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"af9e121e-24bb-44ac-a616-471d5754360e": "authentication_reset_password",
}
@classmethod
def authentication_reset_password(cls, data: Forgot):
from sqlalchemy import or_
found_user = Users.query.filter(
or_(
Users.email == str(data.access_key).lower(),
Users.phone_number == str(data.access_key).replace(" ", ""),
),
).first()
if not found_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Given access key or domain is not matching with the any user record.",
)
reset_password_token = found_user.reset_password_token(found_user=found_user)
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, a password reset request has been received.",
receivers=[str(found_user.email)],
html=change_your_password_template(
user_name=found_user.user_tag,
forgot_link=ApiStatic.forgot_link(forgot_key=reset_password_token),
),
)
if not send_email_completed:
raise found_user.raise_http_exception(
status_code=400, message="Email can not be sent. Try again later"
)
return JSONResponse(
content={
"completed": True,
"message": "Password change link is sent to your email or phone",
"data": found_user.get_dict(),
},
status_code=status.HTTP_200_OK,
)
class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
event_type = "SELECT"
event_type = "LOGIN"
event_description = "Download avatar icon and profile info of user"
event_category = "AUTHENTICATION"
__event_keys__ = {
"c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
}
__event_validation__ = {
"c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
}
@classmethod
def authentication_download_avatar(
cls, request: Request, data: Forgot, token_dict: dict = None
cls, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
found_user = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
)
return JSONResponse(
content={
"completed": True,
"message": "Avatar and profile is shared via user credentials",
"data": {
"last_seen": str(found_user.last_seen),
"avatar": found_user.avatar,
"remember_me": found_user.remember_me,
"expiry_ends": str(found_user.expiry_ends),
"expired_str": str(
DateTimeLocal.now()
- DateTimeLocal.get(str(found_user.expiry_ends))
),
"expired_int": int(
(
DateTimeLocal.now()
- DateTimeLocal.get(str(found_user.expiry_ends))
).days
),
if found_user := Users.filter_one(Users.id == token_dict.user_id).data:
expired_starts = str(
system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
)
expired_int = (
system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
).days
return JSONResponse(
content={
"completed": True,
"message": "Avatar and profile is shared via user credentials",
"data": {
"lang": token_dict.lang,
"full_name": found_user.person.full_name,
"avatar": found_user.avatar,
"remember_me": found_user.remember_me,
"expiry_ends": str(found_user.expiry_ends),
"expired_str": expired_starts,
"expired_int": int(expired_int),
},
},
},
status_code=status.HTTP_200_OK,
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={"completed": False, "message": "Invalid data", "data": {}},
status_code=status.HTTP_202_ACCEPTED,
)
@@ -680,3 +777,68 @@ AuthenticationForgotPasswordEventMethod = AuthenticationForgotPasswordEventMetho
AuthenticationDownloadAvatarEventMethod = AuthenticationDownloadAvatarEventMethods(
action=ActionsSchema(endpoint="/authentication/avatar")
)
AuthenticationResetPasswordEventMethod = AuthenticationResetPasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/reset_password")
)
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=data.access_key,
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=str(DateTimeLocal.now()),
# is_login=False,
# )
# )
# )
# UserLogger.log_error(
# str(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key="via_refresher",
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )
# UserLogger.log_error(
# str(
# dict(
# user_id=selected_user.id,
# domain=data.domain,
# access_key=token_user.get("access_input"),
# agent=request.headers.get("User-Agent", None),
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=request.headers.get("Origin", None),
# login_date=datetime.datetime.utcnow().__str__(),
# is_login=False,
# )
# )
# )

View File

@@ -1,4 +1,5 @@
import typing
from typing import Union
from fastapi import status, HTTPException
from fastapi.responses import JSONResponse
@@ -17,11 +18,10 @@ from api_validations.validations_request import (
UpdateBuild,
PatchRecord,
ListOptions,
)
from api_validations.validations_response import ListBuildingResponse
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
@@ -29,9 +29,15 @@ from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObj
class BuildListEventMethods(MethodToEvent):
event_type = "SELECT"
event_description = ""
event_category = ""
__event_keys__ = {
"68b3b5ed-b74c-4a27-820f-3959214e94e9": "build_list",
}
__event_validation__ = {
"68b3b5ed-b74c-4a27-820f-3959214e94e9": ListBuildingResponse,
}
@classmethod
def build_list(
@@ -40,29 +46,36 @@ class BuildListEventMethods(MethodToEvent):
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
Build.pre_query = Build.filter_active(
Build.id == token_dict.selected_occupant.build_id
Build.pre_query = Build.filter_all(
Build.id == token_dict.selected_occupant.build_id,
).query
elif isinstance(token_dict, EmployeeTokenObject):
Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
Build.filter_attr = list_options
records = Build.filter_active(
*Build.get_smart_query(smart_query=list_options.query)
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
records = Build.filter_all()
return AlchemyJsonResponse(
completed=True,
message="Building Records are listed",
result=records,
response_model=ListBuildingResponse,
)
class BuildCreateEventMethods(MethodToEvent):
event_type = "CREATE"
event_description = ""
event_category = ""
__event_keys__ = {
"a2271854-6b90-43da-a440-a62b70d90528": "build_create",
"b67ee709-0992-4604-9f90-fb1da10d5cf9": "create_building_employee",
}
__event_validation__ = {
"a2271854-6b90-43da-a440-a62b70d90528": InsertBuild,
"b67ee709-0992-4604-9f90-fb1da10d5cf9": InsertBuild,
}
@classmethod
def build_create(cls, data: InsertBuild, token_dict: EmployeeTokenObject):
@@ -79,46 +92,52 @@ class BuildCreateEventMethods(MethodToEvent):
)
created_build = Build.create_action(data=data, token=token_dict)
if not created_build.is_found:
build_type = BuildTypes.find_one(type_code="APT_YNT")
if not build_type:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Build type APT_YNT is not found. Please contact with your system administrator.",
)
api_enum = ApiEnumDropdown.find_one(enum_class="Directions", key="NN")
if not api_enum:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Api Enum NN is not found. Please contact with your system administrator.",
)
build_parts = dict(
address_gov_code=f"{data.gov_address_code}-M",
build_id=int(created_build.id),
build_uu_id=str(created_build.uu_id),
part_no="0",
part_type_id=int(build_type.id),
part_type_uu_id=str(build_type.uu_id),
part_direction_id=int(api_enum.id),
part_direction_uu_id=str(api_enum.uu_id),
part_code="MAN-ROOM",
human_livable=False,
is_confirmed=True,
build_type = BuildTypes.filter_by_one(
**BuildTypes.valid_record_dict, type_code="APT_YNT"
).data
if not build_type:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Build type APT_YNT is not found. Please contact with your system administrator.",
)
man_build_part = BuildParts.find_or_create(**build_parts)
if not man_build_part.is_found:
created_build.update(management_room_id=man_build_part.id)
return JSONResponse(
content={
"completed": True,
"message": "Create Build record completed. This build is assigned to you.",
"data": created_build.get_dict(),
},
status_code=status.HTTP_200_OK,
api_enum = ApiEnumDropdown.filter_by_one(enum_class="Directions", key="NN").data
if not api_enum:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Api Enum NN is not found. Please contact with your system administrator.",
)
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE,
detail=f"Build record create not successful for Employee UUID : {token_dict.selected_company.employee_uu_id}",
build_parts = dict(
address_gov_code=f"{data.gov_address_code}-M",
build_id=int(created_build.id),
build_uu_id=str(created_build.uu_id),
part_no="0",
part_type_id=int(build_type.id),
part_type_uu_id=str(build_type.uu_id),
part_direction_id=int(api_enum.id),
part_direction_uu_id=str(api_enum.uu_id),
part_code="MAN-ROOM",
human_livable=False,
)
man_build_part = BuildParts.find_or_create(**build_parts)
created_build.save()
created_build.update(management_room_id=man_build_part.id)
created_build.save()
man_build_part.update(is_confirmed=True)
man_build_part.save()
# created_build_relation = RelationshipEmployee2Build.find_or_create(
# company_id=token_dict.selected_company.company_id,
# member_id=created_build.id,
# employee_id=token_dict.selected_company.employee_id,
# )
# created_build_relation.update(is_confirmed=True)
# created_build_relation.save()
return JSONResponse(
content={
"completed": True,
"message": "Create Build record completed. This build is assigned to you.",
"data": created_build.get_dict(),
},
status_code=status.HTTP_200_OK,
)
@classmethod
@@ -127,8 +146,8 @@ class BuildCreateEventMethods(MethodToEvent):
):
records = Addresses.list_via_employee(
token_dict=token_dict, filter_expr=[Addresses.uu_id == data.address_uu_id]
)
if not records.data:
).data
if not records:
raise HTTPException(
status_code=404,
detail=f"This address {data.address_uu_id} is not found in the user's address list.",
@@ -147,48 +166,77 @@ class BuildCreateEventMethods(MethodToEvent):
)
created_build = Build.create_action(data=data, token=token_dict)
if not created_build.is_found:
RelationshipEmployee2Build.find_or_create(
company_id=token_dict.selected_company.company_id,
member_id=created_build.id,
employee_id=token_dict.selected_company.employee_id,
is_confirmed=True,
)
return JSONResponse(
content={
"completed": True,
"message": "Create Build record completed. This build is assigned to you.",
"data": created_build.get_dict(),
},
status_code=status.HTTP_200_OK,
)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"Build record create not successful for {token_dict.selected_company.employee_uu_id}",
created_build_relation = RelationshipEmployee2Build.find_or_create(
company_id=token_dict.selected_company.company_id,
member_id=created_build.id,
employee_id=token_dict.selected_company.employee_id,
)
created_build.save()
return JSONResponse(
content={
"completed": True,
"message": "Create Build record completed. This build is assigned to you.",
"data": created_build.get_dict(),
},
status_code=status.HTTP_200_OK,
)
class BuildUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
event_description = ""
event_category = ""
__class_key__ = ""
__event_keys__ = {
"5ad38a66-1189-451e-babb-77de2d63d757": "build_update",
}
__event_validation__ = {
"5ad38a66-1189-451e-babb-77de2d63d757": UpdateBuild,
}
@classmethod
def build_update(cls, build_uu_id: str, data: UpdateBuild, token_dict):
Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
if Build.filter_active(Build.person_id == token_dict.person_id):
if updated_build := Build.update_action(
def build_update(
cls,
build_uu_id: str,
data: UpdateBuild,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
updated_build = Build.update_action(
data=data, token=token_dict, build_uu_id=build_uu_id
):
)
Build.save()
return JSONResponse(
content={
"completed": True,
"message": "Update Build record",
"data": updated_build.get_dict(),
},
status_code=status.HTTP_200_OK,
)
elif isinstance(token_dict, EmployeeTokenObject):
find_one_build = Build.filter_one(
Build.uu_id == build_uu_id,
).data
access_authorized_build = Build.select_action(
employee_id=token_dict.selected_company.employee_id,
filter_expr=[Build.id == find_one_build.id],
)
if access_authorized_build.count:
updated_build = Build.update_action(
data=data, token=token_dict, build_uu_id=build_uu_id
)
return JSONResponse(
content={
"completed": True,
"message": "Update Build record",
"data": updated_build,
"data": updated_build.get_dict(),
},
status_code=status.HTTP_200_OK,
)
@@ -201,13 +249,21 @@ class BuildUpdateEventMethods(MethodToEvent):
class BuildPatchEventMethods(MethodToEvent):
event_type = "PATCH"
event_description = ""
event_category = ""
__event_keys__ = {
"e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch",
}
__event_validation__ = {
"e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch",
}
@classmethod
def build_patch(cls, build_uu_id: str, data: PatchRecord, token_dict):
find_one_build = Build.find_one_or_abort(uu_id=build_uu_id)
find_one_build = Build.filter_one(
Build.uu_id == build_uu_id,
)
access_authorized_build = Build.select_action(
employee_id=token_dict.selected_company.employee_id,
filter_expr=[Build.id == find_one_build.id],

View File

@@ -1,5 +1,176 @@
import typing
from databases import (
Build,
BuildArea,
)
from api_validations.validations_request import (
InsertBuildArea,
UpdateBuildArea,
ListOptions,
)
from api_validations.core_response import AlchemyJsonResponse
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
class BuildingBuildAreaEvents(MethodToEvent): ...
class BuildAreaListEventMethods(MethodToEvent):
event_type = "SELECT"
__event_keys__ = {
"0bb51845-65a2-4340-8872-a3b5aad95468": "build_area_list",
}
__event_validation__ = {
"0bb51845-65a2-4340-8872-a3b5aad95468": None,
}
@classmethod
def build_area_list(
cls,
list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
build_ids = Build.filter_all(
Build.id == token_dict.selected_occupant.build_id,
).data
BuildArea.pre_query = BuildArea.filter_all(
BuildArea.build_id.in_([build.id for build in build_ids]),
).query
elif isinstance(token_dict, EmployeeTokenObject):
build_ids = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
BuildArea.pre_query = BuildArea.filter_all(
BuildArea.build_id.in_([build.id for build in build_ids]),
).query
BuildArea.filter_attr = list_options
records = BuildArea.filter_all()
return AlchemyJsonResponse(
completed=True, message="List of Build Area", result=records
)
class BuildAreaCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"a10571fa-ac1d-4546-9272-cacb911d8004": "build_area_create",
}
__event_validation__ = {
"a10571fa-ac1d-4546-9272-cacb911d8004": InsertBuildArea,
}
@classmethod
def build_area_create(
cls,
data: InsertBuildArea,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
data_dict = data.excluded_dump()
selected_build = None
if isinstance(token_dict, OccupantTokenObject):
if not token_dict.selected_occupant.build_uuid == data.build_uu_id:
BuildArea.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Occupant can not create build area for {data.build_uu_id}",
data={
"build_uu_id": data.build_uu_id,
},
)
selected_build = Build.filter_by_one(
system=True, uu_id=data.build_uu_id
).data
elif isinstance(token_dict, EmployeeTokenObject):
build_ids = Build.select_action(
employee_id=token_dict.selected_company.employee_id
).all()
if not str(data.build_uu_id) in [str(build.uu_id) for build in build_ids]:
BuildArea.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Employee can not create build area for {data.build_uu_id}",
data={
"build_uu_id": data.build_uu_id,
},
)
selected_build = Build.filter_by_one(
system=True, uu_id=data.build_uu_id
).data
data_dict["build_id"] = selected_build.id
data_dict["build_uu_id"] = str(selected_build.uu_id)
created_build_part = BuildArea.find_or_create(**data_dict)
created_build_part.save()
created_build_part.update(is_confirmed=True)
created_build_part.save()
return AlchemyJsonResponse(
completed=True,
message="Created Build Area",
result=created_build_part.get_dict(),
)
class BuildAreaUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"58178738-7489-4f8f-954e-5c8f083c1845": "build_area_update",
}
__event_validation__ = {
"58178738-7489-4f8f-954e-5c8f083c1845": UpdateBuildArea,
}
@classmethod
def build_area_update(
cls,
build_uu_id: str,
data: UpdateBuildArea,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
return AlchemyJsonResponse(
completed=False,
message="Update Build record",
result=None,
)
class BuildAreaPatchEventMethods(MethodToEvent):
event_type = "PATCH"
__event_keys__ = {
"d6bd8a5f-fa76-49da-b82e-4a95f1bcce39": "build_area_patch",
}
__event_validation__ = {
"d6bd8a5f-fa76-49da-b82e-4a95f1bcce39": None,
}
@classmethod
def build_area_patch(
cls,
build_uu_id: str,
data,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
return AlchemyJsonResponse(
completed=False,
message="Patch Build record",
result=None,
)
BuildAreaListEventMethod = BuildAreaListEventMethods(
action=ActionsSchema(endpoint="/building/area/list")
)
BuildAreaCreateEventMethod = BuildAreaCreateEventMethods(
action=ActionsSchema(endpoint="/building/area/create")
)
BuildAreaUpdateEventMethod = BuildAreaUpdateEventMethods(
action=ActionsSchema(endpoint="/building/area/update")
)
BuildAreaPatchEventMethod = BuildAreaPatchEventMethods(
action=ActionsSchema(endpoint="/building/area/patch")
)

View File

@@ -1,16 +1,20 @@
from typing import Union
from fastapi.responses import JSONResponse
from fastapi import status
from api_validations.validations_response.parts import BuildPartsListResponse
from databases import (
Build,
BuildParts,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from api_validations.validations_request import (
InsertBuildParts,
UpdateBuildParts,
ListOptions,
)
@@ -21,21 +25,32 @@ class BuildingBuildPartsListEventMethods(MethodToEvent):
__event_keys__ = {
"b860e37a-e19b-4c45-9543-461241f7587c": "building_build_parts_list"
}
__event_validation__ = {
"b860e37a-e19b-4c45-9543-461241f7587c": BuildPartsListResponse
}
@classmethod
def building_build_parts_list(cls, list_options: ListOptions, token_dict):
def building_build_parts_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
build_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id,
)
build_list_ids = [build.id for build in build_list_query.all()]
BuildParts.pre_query = BuildParts.query.filter(
BuildParts.build_id.in_(build_list_ids)
)
records = BuildParts.filter_active(
*BuildParts.get_smart_query(list_options.query)
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
BuildParts.pre_query = BuildParts.filter_all(
BuildParts.build_id.in_(build_list_ids),
).query
BuildParts.filter_attr = list_options
records = BuildParts.filter_all()
return AlchemyJsonResponse(
completed=True,
message="Building Parts Records are listed",
result=records,
cls_object=BuildParts,
response_model=BuildPartsListResponse,
filter_attributes=list_options,
)
@@ -45,19 +60,17 @@ class BuildingBuildPartsCreateEventMethods(MethodToEvent):
__event_keys__ = {
"fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": "building_build_parts_create"
}
__event_validation__ = {"fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": InsertBuildParts}
@classmethod
def building_build_parts_create(cls, data: InsertBuildParts, token_dict: dict):
def building_build_parts_create(
cls,
data: InsertBuildParts,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
created_build = BuildParts.create_action(data=data, token=token_dict)
if not created_build:
return JSONResponse(
content={
"completed": False,
"message": "Create Build Parts is not completed",
"data": {},
},
status_code=status.HTTP_406_NOT_ACCEPTABLE,
)
created_build.save()
created_build.update(is_confirmed=True)
created_build.save()
return JSONResponse(
content={
@@ -75,24 +88,21 @@ class BuildingBuildPartsUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"58fdf95e-2110-4ed6-9c26-95f4be87eaee": "building_build_parts_update"
}
__event_validation__ = {"58fdf95e-2110-4ed6-9c26-95f4be87eaee": UpdateBuildParts}
@classmethod
def building_build_parts_update(cls, data: InsertBuildParts, token_dict: dict):
if updated_build := BuildParts.update_action(data=data, token=token_dict):
updated_build.save()
return JSONResponse(
content={
"completed": True,
"message": "Update Build Parts record",
"data": updated_build,
},
status_code=status.HTTP_200_OK,
)
def building_build_parts_update(
cls,
data: UpdateBuildParts,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
updated_build = BuildParts.update_action(data=data, token=token_dict)
updated_build.save()
return JSONResponse(
content={
"completed": True,
"message": "Update Build Parts record",
"data": {},
"data": updated_build,
},
status_code=status.HTTP_200_OK,
)
@@ -104,10 +114,13 @@ class BuildingBuildPartsPatchEventMethods(MethodToEvent):
__event_keys__ = {
"87a15ade-3474-4206-b574-bbf8580cbb14": "building_build_parts_patch"
}
__event_validation__ = {"87a15ade-3474-4206-b574-bbf8580cbb14": None}
@classmethod
def building_build_parts_patch(cls, data, token_dict):
find_one_build = BuildParts.find_one(uu_id=data.uu_id)
find_one_build = BuildParts.filter_one(
BuildParts.uu_id == data.uu_id,
).data
access_authorized_build = BuildParts.select_action(
duty_id=token_dict.selected_company.duty_id,
filter_expr=[BuildParts.id == find_one_build.id],

View File

@@ -1,5 +1,175 @@
import typing
from databases import (
Build,
BuildSites,
)
from api_validations.validations_request import (
InsertBuildArea,
UpdateBuildArea,
ListOptions,
)
from api_validations.core_response import AlchemyJsonResponse
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from databases.sql_models.identity.identity import Addresses
class BuildingBuildSitesEvents(MethodToEvent): ...
class BuildSitesListEventMethods(MethodToEvent):
event_type = "SELECT"
__event_keys__ = {
"6798414c-6c7d-47f0-9d8b-6935a0f51c2e": "build_sites_list",
}
__event_validation__ = {
"6798414c-6c7d-47f0-9d8b-6935a0f51c2e": None,
}
@classmethod
def build_sites_list(
cls,
list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
occupants_build = Build.filter_one(
Build.id == token_dict.selected_occupant.build_id,
).data
BuildSites.pre_query = BuildSites.filter_all(
BuildSites.address_id == occupants_build.address_id,
).query
elif isinstance(token_dict, EmployeeTokenObject):
employees_build = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
employees_build_list = [build.address_id for build in employees_build.all()]
if not employees_build_list:
BuildSites.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message="Employee has no build sites registered",
data={},
)
BuildSites.pre_query = BuildSites.filter_all(
BuildSites.address_id.in_(employees_build_list)
).query
BuildSites.filter_attr = list_options
records = BuildSites.filter_all()
return AlchemyJsonResponse(
completed=True, message="Update Build record", result=records
)
class BuildSitesCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"57edc8bf-8f29-4e75-b5e1-9ca0139a3fda": "build_sites_create",
}
__event_validation__ = {
"57edc8bf-8f29-4e75-b5e1-9ca0139a3fda": InsertBuildArea,
}
@classmethod
def build_area_create(
cls,
data: InsertBuildArea,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, OccupantTokenObject):
if not token_dict.selected_occupant.build_uuid == data.build_uu_id:
BuildSites.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Occupant can not create build sites for {data.build_uu_id}",
data={
"build_uu_id": data.build_uu_id,
},
)
elif isinstance(token_dict, EmployeeTokenObject):
build_ids = Build.select_action(
employee_id=token_dict.selected_company.employee_id
).all()
if not str(data.build_uu_id) in [str(build.uu_id) for build in build_ids]:
BuildSites.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Employee can not create build sites for {data.build_uu_id}",
data={
"build_uu_id": data.build_uu_id,
},
)
data_dict = data.excluded_dump()
created_build_part = BuildSites.find_or_create(**data_dict)
created_build_part.save()
created_build_part.update(is_confirmed=True)
created_build_part.save()
return AlchemyJsonResponse(
completed=True,
message="Update Build record",
result=created_build_part,
)
class BuildSitesUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"b18e8e37-a62b-4a84-9972-ba17121ed393": "build_sites_update",
}
__event_validation__ = {
"b18e8e37-a62b-4a84-9972-ba17121ed393": UpdateBuildArea,
}
@classmethod
def build_area_update(
cls,
build_uu_id: str,
data: UpdateBuildArea,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
return AlchemyJsonResponse(
completed=False,
message="Update Build record",
result=None,
)
class BuildSitesPatchEventMethods(MethodToEvent):
event_type = "PATCH"
__event_keys__ = {
"39ba1d78-ff0d-4ec7-a363-b457cbf199a0": "build_sites_patch",
}
__event_validation__ = {
"39ba1d78-ff0d-4ec7-a363-b457cbf199a0": None,
}
@classmethod
def build_area_patch(
cls,
build_uu_id: str,
data,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
return AlchemyJsonResponse(
completed=False,
message="Patch Build record",
result=None,
)
BuildSitesListEventMethod = BuildSitesListEventMethods(
action=ActionsSchema(endpoint="/building/sites/list")
)
BuildSitesCreateEventMethod = BuildSitesCreateEventMethods(
action=ActionsSchema(endpoint="/building/sites/create")
)
BuildSitesUpdateEventMethod = BuildSitesUpdateEventMethods(
action=ActionsSchema(endpoint="/building/sites/update")
)
BuildSitesPatchEventMethod = BuildSitesPatchEventMethods(
action=ActionsSchema(endpoint="/building/sites/patch")
)

View File

@@ -1,5 +1,48 @@
from typing import Union
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse
from api_validations.validations_request import (
ListOptions,
)
from databases.sql_models.building.build import BuildTypes
class BuildingBuildTypesEvents(MethodToEvent): ...
class BuildTypesListEventMethods(MethodToEvent):
event_type = "SELECT"
__event_keys__ = {
"5344d03c-fc47-43ec-8c44-6c2acd7e5d9f": "build_types_list",
}
__event_validation__ = {"5344d03c-fc47-43ec-8c44-6c2acd7e5d9f": None}
@classmethod
def build_types_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
from fastapi.exceptions import HTTPException
if isinstance(token_dict, EmployeeTokenObject):
BuildTypes.filter_attr = list_options
results = BuildTypes.filter_all()
return AlchemyJsonResponse(
completed=True,
result=results,
message="Build Types are listed successfully",
)
elif isinstance(token_dict, OccupantTokenObject):
raise HTTPException(
status_code=403, detail="You are not authorized to access this endpoint"
)
else:
raise HTTPException(
status_code=403, detail="You are not authorized to access this endpoint"
)
BuildTypesListEventMethod = BuildTypesListEventMethods(
action=ActionsSchema(endpoint="/building/types/list")
)

View File

@@ -1,9 +1,11 @@
import typing
from typing import Union
from fastapi import status, HTTPException
from api_events.events.events.events_bind_modules import ModulesBindOccupantEventMethods
from api_events.events.events.events_bind_services import (
ServiceBindOccupantEventMethods,
)
from databases import (
Modules,
BuildParts,
Build,
BuildLivingSpace,
@@ -12,115 +14,159 @@ from databases import (
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from api_validations.validations_request import (
InsertBuildLivingSpace,
UpdateBuildLivingSpace,
ListOptions,
)
from databases.sql_models.event.event import Modules
from api_validations.validations_response.living_space import LivingSpaceListResponse
from databases.sql_models.event.event import Services
class BuildingLivingSpacesPartsListEventMethods(MethodToEvent):
class BuildingLivingSpacesListEventMethods(MethodToEvent):
event_type = "SELECT"
event_description = ""
event_category = ""
__event_keys__ = {
"8fd04d94-68fb-4a07-9549-8b47aee3a870": "building_build_parts_list",
"2f3041a9-6184-44c2-ac38-8ea934297ed1": "building_build_parts_list_with_expired",
"36961d8a-cefa-46cc-9f7c-9d841d6351b6": "building_live_space_list",
}
__event_validation__ = {
"36961d8a-cefa-46cc-9f7c-9d841d6351b6": LivingSpaceListResponse
}
@classmethod
def building_build_parts_list(cls, list_options: ListOptions, token_dict):
build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
Build.filter_attr = list_options
build_part_id_list_query = BuildParts.filter_active(
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
)
list_options.query.pop("expiry_starts", None)
list_options.query.pop("expiry_ends", None)
records = BuildLivingSpace.filter_active(
BuildLivingSpace.build_parts_id.in_(
[build_part.id for build_part in build_part_id_list_query.data]
),
*BuildLivingSpace.get_smart_query(smart_query=list_options.query),
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
)
@classmethod
def building_build_parts_list_with_expired(
cls, list_options: ListOptions, token_dict
def building_live_space_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
Build.filter_attr = list_options
build_part_id_list_query = BuildParts.filter_active(
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
)
records = BuildLivingSpace.filter_active(
BuildLivingSpace.build_parts_id.in_(
[build_part.id for build_part in build_part_id_list_query.data]
),
*BuildLivingSpace.get_smart_query(smart_query=list_options.query),
expired=False,
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
records, Build.filter_attr = [], None
if isinstance(token_dict, OccupantTokenObject):
occupants_build_id = Build.filter_one(
Build.id == token_dict.selected_occupant.build_id,
).data
if not occupants_build_id:
Build.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Occupant has no build registered in the system. Contact with your company.",
data={},
)
occupants_build_parts = BuildParts.filter_all(
BuildParts.build_id.in_(occupants_build_id.id),
).data
if not occupants_build_parts:
Build.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Occupant has no build parts registered in the system. Contact with your company.",
data={},
)
BuildLivingSpace.pre_query = BuildLivingSpace.filter_all(
BuildLivingSpace.build_parts_id.in_(
[build_part.id for build_part in occupants_build_parts]
),
).query
BuildLivingSpace.filter_attr = list_options
records = BuildLivingSpace.filter_all()
elif isinstance(token_dict, EmployeeTokenObject):
build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
if not build_id_list_query:
Build.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Employee has no build registered in the system. Contact with your supervisor.",
data={},
)
build_part_id_list_query = BuildParts.filter_all(
BuildParts.build_id.in_(
[build.id for build in build_id_list_query.all()]
),
).data
if not build_part_id_list_query:
Build.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"Employee has no build parts registered in the system. Contact with your supervisor.",
data={},
)
BuildLivingSpace.pre_query = BuildLivingSpace.filter_all(
BuildLivingSpace.build_parts_id.in_(
[build_part.id for build_part in build_part_id_list_query]
),
).query
BuildLivingSpace.filter_attr = list_options
records = BuildLivingSpace.filter_all()
return AlchemyJsonResponse(
completed=True,
message="Building Living Spaces are listed successfully",
result=records,
response_model=LivingSpaceListResponse,
cls_object=BuildLivingSpace,
filter_attributes=list_options,
)
class BuildingLivingSpacesPartsCreateEventMethods(MethodToEvent):
class BuildingLivingSpacesCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"b78ca45c-b9f4-41f6-9ddb-2c6f2faa2570": "building_live_space_create"
"46d90119-3b23-4784-8053-fe11da4a3584": "building_live_space_create"
}
__event_validation__ = {
"46d90119-3b23-4784-8053-fe11da4a3584": InsertBuildLivingSpace
}
@classmethod
def building_live_space_create(
cls,
data: InsertBuildLivingSpace,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
from api_library.date_time_actions.date_functions import system_arrow
from sqlalchemy.sql import select
data_dict = data.dump()
data_dict = data.excluded_dump()
build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
build_part = BuildParts.filter_one(
BuildParts.uu_id == data.build_parts_uu_id,
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
)
if not build_part.data:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
).data
if not build_part:
BuildLivingSpace.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
data={
"build_parts_uu_id": data.build_parts_uu_id,
},
)
build_part = build_part.data
life_person = People.find_one(uu_id=data.person_uu_id or "")
life_person = People.filter_one(
People.uu_id == data.person_uu_id,
).data
if not life_person:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail=f"{data.life_person_uu_id} - Living Person is not found in database. "
f"Check build live person uu_id",
BuildLivingSpace.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message=f"{data.person_uu_id} - Living Person is not found in database.",
data={
"person_uu_id": data.person_uu_id,
},
)
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_type_uu_id)
occupant_type = OccupantTypes.filter_by_one(uu_id=data.occupant_type_uu_id).data
if not occupant_type:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail=f"{data.occupant_type_uu_id} - Occupant Type is not found in database. "
f"Check occupant type uu_id",
BuildLivingSpace.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message=f"{data.occupant_type_uu_id} - Occupant Type is not found in database. Check occupant type uu_id",
data={
"occupant_type_uu_id": data.occupant_type_uu_id,
},
)
data_dict["occupant_type"] = occupant_type.id
@@ -130,119 +176,132 @@ class BuildingLivingSpacesPartsCreateEventMethods(MethodToEvent):
data_dict["person_id"] = life_person.id
data_dict["person_uu_id"] = str(life_person.uu_id)
living_space_id = BuildLivingSpace.session.execute(
select(BuildLivingSpace.id)
.where(
*[
BuildLivingSpace.build_parts_id == build_part.id,
BuildLivingSpace.person_id == life_person.id,
BuildLivingSpace.occupant_type == occupant_type.id,
BuildLivingSpace.active == True,
BuildLivingSpace.is_confirmed == True,
str(system_arrow.now()) < BuildLivingSpace.expiry_ends,
str(system_arrow.now()) >= BuildLivingSpace.expiry_starts,
]
)
.order_by(BuildLivingSpace.expiry_starts.desc())
).first()
living_space_id = BuildLivingSpace.select_only(
BuildLivingSpace.build_parts_id == build_part.id,
BuildLivingSpace.person_id == life_person.id,
BuildLivingSpace.occupant_type == occupant_type.id,
select_args=[BuildLivingSpace.id],
order_by=BuildLivingSpace.expiry_starts.desc(),
limit=1,
).data
last_living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id==living_space_id[0] if living_space_id else None
)
data_dict["expiry_starts"] = str(system_arrow.now())
BuildLivingSpace.id == living_space_id[0] if living_space_id else None,
).data
created_living_space = BuildLivingSpace.create_action(
data=data_dict, token_dict=token_dict
)
if last_living_space:
if last_living_space.expiry_ends > system_arrow.now():
last_living_space.expiry_ends = str(system_arrow.shift(minutes=-10))
dt = system_arrow.get(last_living_space.expiry_ends)
if dt > system_arrow.now():
minute_df = int(dt.time().minute) - 10
last_living_space.expiry_ends = str(
dt.replace(
minute=60 - abs(minute_df) if minute_df < 0 else minute_df
)
)
last_living_space.save()
user_module = Modules.filter_one(Modules.module_code == "USR-PUB")
ModulesBindOccupantEventMethods.modules_bind_occupant_system(
build_living_space_id=created_living_space.id,
modules_id=user_module.id,
created_living_space.save_and_confirm()
occupants_service = Services.retrieve_service_via_occupant_code(
occupant_code=occupant_type.occupant_code
)
ServiceBindOccupantEventMethods.bind_services_occupant_system(
build_living_space_id=created_living_space.id,
service_id=occupants_service.id,
)
created_living_space.save()
return created_living_space
class BuildingLivingSpacesPartsUpdateEventMethods(MethodToEvent):
class BuildingLivingSpacesUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"70b4666f-4ceb-46ec-b89e-24be8712f0e7": "building_live_space_update",
"c786e15c-c03e-4e8f-936c-7e5e5ec9bbcc": "building_live_space_update",
}
__event_validation__ = {
"c786e15c-c03e-4e8f-936c-7e5e5ec9bbcc": UpdateBuildLivingSpace
}
@classmethod
def building_live_space_update(cls, build_uu_id: str, data, token_dict):
def building_live_space_update(
cls,
build_uu_id: str,
data: UpdateBuildLivingSpace,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
from api_library.date_time_actions.date_functions import system_arrow
from sqlalchemy.sql import select
data_dict = data.dump()
build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
build_part = BuildParts.filter_active(
BuildParts.uu_id == data.build_parts_uu_id,
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
)
if not build_part.get(1):
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
if isinstance(token_dict, OccupantTokenObject):
data_dict = data.dump()
build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
build_part = build_part.get(1)
build_part = BuildParts.filter_one(
BuildParts.uu_id == data.build_parts_uu_id,
BuildParts.build_id.in_(
[build.id for build in build_id_list_query.all()]
),
).data
if not build_part:
BuildLivingSpace.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"{data.life_person_uu_id} - Living Person is not found in database.",
data={
"person_uu_id": data.life_person_uu_id,
},
)
life_person = People.filter_one(
People.uu_id == data.life_person_uu_id or ""
).data
if not life_person:
BuildLivingSpace.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"{data.life_person_uu_id} - Living Person is not found in database.",
data={
"person_uu_id": data.life_person_uu_id,
},
)
life_person = People.find_one(uu_id=data.life_person_uu_id or "")
if not life_person:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail=f"{data.life_person_uu_id} - Living Person is not found in database. "
f"Check build live person uu_id",
)
living_space_id = BuildLivingSpace.select_only(
*BuildLivingSpace.valid_record_args(BuildLivingSpace),
select_args=[BuildLivingSpace.id],
order_by=BuildLivingSpace.expiry_starts.desc(),
limit=1,
).get(1)
living_spaces = select(BuildLivingSpace.id).order_by(
BuildLivingSpace.expiry_starts.desc()
)
living_space_id = BuildLivingSpace.session.execute(living_spaces).first()
last_living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id==getattr(living_space_id[0], "id", None) if living_space_id else None
)
last_living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == living_space_id if living_space_id else None,
).data
data_dict["expiry_starts"] = str(system_arrow.now())
data_dict["is_tenant_live"] = bool(data.is_tenant_live)
data_dict["build_parts_id"] = build_part.id
if data_dict["is_tenant_live"]:
owner_person = getattr(last_living_space, "owner_person_id", None)
if not owner_person:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail=dict(
data_dict["expiry_starts"] = str(system_arrow.now())
data_dict["is_tenant_live"] = bool(data.is_tenant_live)
data_dict["build_parts_id"] = build_part.id
if data_dict["is_tenant_live"]:
owner_person = getattr(last_living_space, "owner_person_id", None)
if not owner_person:
BuildLivingSpace.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message="Owner person of build part is not defined. Please register owner of part first.",
data=build_part.get_dict(),
),
)
data_dict["life_person_id"] = life_person.id
data_dict["owner_person_id"] = owner_person
else:
data_dict["life_person_id"] = life_person.id
data_dict["owner_person_id"] = life_person.id
del data_dict["build_parts_uu_id"], data_dict["life_person_uu_id"]
)
data_dict["life_person_id"] = life_person.id
data_dict["owner_person_id"] = owner_person
else:
data_dict["life_person_id"] = life_person.id
data_dict["owner_person_id"] = life_person.id
del data_dict["build_parts_uu_id"], data_dict["life_person_uu_id"]
BuildingLivingSpacesPartsListEventMethod = BuildingLivingSpacesPartsListEventMethods(
BuildingLivingSpacesListEventMethod = BuildingLivingSpacesListEventMethods(
action=ActionsSchema(endpoint="/building/living_space/list")
)
BuildingLivingSpacesPartsCreateEventMethod = (
BuildingLivingSpacesPartsCreateEventMethods(
action=ActionsSchema(endpoint="/building/living_space/create")
)
BuildingLivingSpacesCreateEventMethod = BuildingLivingSpacesCreateEventMethods(
action=ActionsSchema(endpoint="/building/living_space/create")
)
BuildingLivingSpacesPartsUpdateEventMethod = (
BuildingLivingSpacesPartsUpdateEventMethods(
action=ActionsSchema(endpoint="/building/living_space/update")
)
BuildingLivingSpacesUpdateEventMethod = BuildingLivingSpacesUpdateEventMethods(
action=ActionsSchema(endpoint="/building/living_space/update")
)

View File

@@ -14,7 +14,7 @@ from api_validations.validations_request import (
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class CompanyListEventMethods(MethodToEvent):
@@ -23,6 +23,7 @@ class CompanyListEventMethods(MethodToEvent):
__event_keys__ = {
"f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": "company_list",
}
__event_validation__ = {"f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": None}
@classmethod
def company_list(
@@ -38,15 +39,15 @@ class CompanyListEventMethods(MethodToEvent):
]
)
elif isinstance(token_dict, OccupantTokenObject):
Companies.pre_query = Companies.filter_active(
Companies.pre_query = Companies.filter_all(
Companies.id == token_dict.selected_occupant.responsible_company_id
).query
Companies.filter_attr = list_options
records = Companies.filter_active(
*Companies.get_smart_query(list_options.query)
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
records = Companies.filter_all()
return AlchemyJsonResponse(
completed=True,
message="Building Living Spaces are listed successfully",
result=records,
)
@@ -56,29 +57,24 @@ class CompanyCreateEventMethods(MethodToEvent):
__event_keys__ = {
"76f11a08-5f4a-4e1f-961f-aaef21699acd": "company_create",
}
__event_validation__ = {"76f11a08-5f4a-4e1f-961f-aaef21699acd": InsertCompany}
@classmethod
def company_create(cls, data: InsertCompany, token_dict):
created_company = Companies.create_action(
data=data, token=token_dict.companies_list
def company_create(
cls,
data: InsertCompany,
token_dict: EmployeeTokenObject,
):
created_company = Companies.create_action(data=data, token=token_dict)
created_company.update(
related_company=token_dict.selected_company.company_uu_id
)
created_company.related_company = token_dict.get("company_uu_id")
created_company.flush()
created_company.save()
return JSONResponse(
content={
"completed": True,
"message": "Create Company record",
"data": created_company.get_dict(),
"password_token": {
"password_token": created_company.password_token,
"password_expires_day": str(created_company.password_expires_day),
"password_expiry_begins": str(
created_company.password_expiry_begins
),
"hash_password": created_company.hash_password,
"related_company": created_company.related_company,
},
},
status_code=status.HTTP_200_OK,
)
@@ -90,28 +86,41 @@ class CompanyUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"41ea7f29-006a-4310-b5c4-b2a0e1a504bd": "company_update",
}
__event_validation__ = {
"41ea7f29-006a-4310-b5c4-b2a0e1a504bd": UpdateCompany,
}
@classmethod
def company_update(cls, company_uu_id: str, data: UpdateCompany, token_dict):
find_one_company = Companies.filter_one(Companies.uu_id==company_uu_id)
access_authorized_company = Companies.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
filter_expr=[Companies.id == token_dict.get("")],
def company_update(
cls, company_uu_id: str, data: UpdateCompany, token_dict: EmployeeTokenObject
):
Companies.pre_query = Companies.select_action(
duty_id_list=[
token_dict.selected_company.bulk_duties_id,
token_dict.selected_company.duty_id,
],
)
if access_authorized_company.count:
updated_company = find_one_company.data.update(**data.excluded_dump())
Companies.save()
find_one_company = Companies.filter_one(
Companies.uu_id == company_uu_id,
).data
if not find_one_company:
return JSONResponse(
content={
"completed": True,
"message": "Update Company record",
"data": updated_company,
"data": {},
},
status_code=status.HTTP_200_OK,
status_code=200,
)
updated_company = find_one_company.update(**data.excluded_dump())
Companies.save()
return JSONResponse(
content={"completed": True, "message": "Update Company record", "data": {}},
status_code=status.HTTP_200_OK,
content={
"completed": True,
"message": "Update Company record",
"data": updated_company,
},
status_code=200,
)
@@ -121,13 +130,20 @@ class CompanyPatchEventMethods(MethodToEvent):
__event_keys__ = {
"6320d696-1fd1-49f9-860a-8f22e5b8a68d": "company_patch",
}
__event_validation__ = {"6320d696-1fd1-49f9-860a-8f22e5b8a68d": None}
@classmethod
def company_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
find_one_company = Companies.find_one_or_abort(uu_id=company_uu_id)
def company_patch(
cls, company_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
):
find_one_company = Companies.filter_one(
Companies.uu_id == company_uu_id,
).data
access_authorized_company = Companies.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
filter_expr=[Companies.id == find_one_company.id],
duty_id_list=[
token_dict.selected_company.bulk_duties_id,
token_dict.selected_company.duty_id,
],
)
if access_authorized_company.count:
action = data.excluded_dump()

View File

@@ -1,4 +1,4 @@
from typing import Optional, Union
from typing import Optional
from fastapi import status
from fastapi.responses import JSONResponse
@@ -12,8 +12,8 @@ from api_validations.validations_request import (
from databases import Departments
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_objects.auth.token_objects import EmployeeTokenObject
from api_validations.core_response import AlchemyJsonResponse
class DepartmentListEventMethods(MethodToEvent):
@@ -22,18 +22,22 @@ class DepartmentListEventMethods(MethodToEvent):
__event_keys__ = {
"2cb90331-c1b4-4923-8314-8111326b621a": "department_list",
}
__event_validation__ = {"2cb90331-c1b4-4923-8314-8111326b621a": None}
@classmethod
def department_list(
cls, list_options: ListOptions, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
list_options: ListOptions,
token_dict: EmployeeTokenObject,
):
Departments.filter_attr = list_options
records = Departments.filter_active(
*Departments.get_smart_query(smart_query=list_options.query),
Departments.company_id == token_dict.selected_company.company_id
records = Departments.filter_all(
Departments.company_id == token_dict.selected_company.company_id,
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
return AlchemyJsonResponse(
completed=True,
message="Departments are listed successfully",
result=records,
)
@@ -52,9 +56,14 @@ class DepartmentCreateEventMethods(MethodToEvent):
__event_keys__ = {
"d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": "super_user_department_create",
}
__event_validation__ = {"d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": DepartmentsPydantic}
@classmethod
def super_user_department_create(cls, data: DepartmentsPydantic, token_dict):
def super_user_department_create(
cls,
data: DepartmentsPydantic,
token_dict: EmployeeTokenObject,
):
data_dict = data.excluded_dump()
data_dict["company_id"] = token_dict.selected_company.company_id
data_dict["company_uu_id"] = token_dict.selected_company.company_uu_id
@@ -76,12 +85,16 @@ class DepartmentUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"4172706f-06c9-4c38-9ac8-59085a72f80a": "department_update",
}
__event_validation__ = {"4172706f-06c9-4c38-9ac8-59085a72f80a": DepartmentsPydantic}
@classmethod
def department_update(
cls, company_uu_id: str, data: DepartmentsPydantic, token_dict
cls,
company_uu_id: str,
data: DepartmentsPydantic,
token_dict: EmployeeTokenObject,
):
find_one_company = Departments.filter_one(Departments.uu_id==company_uu_id)
find_one_company = Departments.filter_one(Departments.uu_id == company_uu_id)
access_authorized_company = Departments.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
filter_expr=[Departments.id == token_dict.get("")],
@@ -110,9 +123,12 @@ class DepartmentPatchEventMethods(MethodToEvent):
__event_keys__ = {
"1e272e4f-6c1e-418b-91a7-be8b06c875da": "department_patch",
}
__event_validation__ = {"1e272e4f-6c1e-418b-91a7-be8b06c875da": None}
@classmethod
def department_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
def department_patch(
cls, company_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
):
find_one_company = Departments.find_one_or_abort(uu_id=company_uu_id)
access_authorized_company = Departments.select_action(
duty_id=getattr(token_dict, "duty_id", 5),

View File

@@ -1,8 +1,7 @@
from typing import Union
from fastapi import status
from fastapi.responses import JSONResponse
from api_validations.core_response import AlchemyJsonResponse
from api_validations.validations_request import (
InsertDuties,
UpdateDuties,
@@ -14,8 +13,7 @@ from api_validations.validations_request import (
from databases import Departments, Duty, Duties
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_objects.auth.token_objects import EmployeeTokenObject
class DutiesListEventMethods(MethodToEvent):
@@ -24,21 +22,23 @@ class DutiesListEventMethods(MethodToEvent):
__event_keys__ = {
"44b72beb-53a8-407b-a12a-76e74b65794d": "duties_list",
}
__event_validation__ = {"44b72beb-53a8-407b-a12a-76e74b65794d": None}
@classmethod
def duties_list(
cls, list_options: ListOptions, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
list_options: ListOptions,
token_dict: EmployeeTokenObject,
):
Duties.filter_attr = list_options
records = Duties.filter_all(
*Duties.get_smart_query(smart_query=list_options.query),
Duties.company_id == token_dict.selected_company.company_id
Duties.company_id == token_dict.selected_company.company_id,
)
return AlchemyJsonResponse(
completed=True,
result=records,
message="List of Duties records",
)
return {
"completed": True if records.count else False,
"status": "success",
"data": records.get_dict(),
}
class DutiesGetByUUIDEventMethods(MethodToEvent):
@@ -47,13 +47,16 @@ class DutiesGetByUUIDEventMethods(MethodToEvent):
__event_keys__ = {
"30c54cce-3303-4d36-959a-b64e383ae177": "duties_get_by_uuid",
}
__event_validation__ = {"30c54cce-3303-4d36-959a-b64e383ae177": SelectDuties}
@classmethod
def duties_get_by_uuid(
cls, data: SelectDuties, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: SelectDuties,
token_dict: EmployeeTokenObject,
):
duty = Duty.filter_one(Duty.uu_id==data.duty_uu_id).data
duty = Duty.filter_one(Duty.uu_id == data.duty_uu_id).data
if not duty:
return JSONResponse(
content={
@@ -64,7 +67,7 @@ class DutiesGetByUUIDEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
records = Duties.filter_active(
records = Duties.filter_all(
Duties.duties_id == duty.id,
Duties.company_id == token_dict.selected_company.company_id,
)
@@ -90,13 +93,16 @@ class DutiesCreateEventMethods(MethodToEvent):
__event_keys__ = {
"3524ae42-0825-4af7-be85-7c890a4f65d3": "duties_create",
}
__event_validation__ = {"3524ae42-0825-4af7-be85-7c890a4f65d3": InsertDuties}
@classmethod
def duties_create(
cls, data: InsertDuties, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: InsertDuties,
token_dict: EmployeeTokenObject,
):
duty = Duty.filter_one(Duty.uu_id==data.duties_uu_id).data
department = Departments.filter_one(Duty.uu_id==data.department_uu_id).data
duty = Duty.filter_one(Duty.uu_id == data.duties_uu_id).data
department = Departments.filter_one(Duty.uu_id == data.department_uu_id).data
created_duties = Duties.find_or_create(
company_id=token_dict.selected_company.company_id,
@@ -137,9 +143,15 @@ class DutiesUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"3fc77829-f1ee-4511-a2ca-582daa03125b": "duties_update",
}
__event_validation__ = {"3fc77829-f1ee-4511-a2ca-582daa03125b": UpdateDuties}
@classmethod
def duties_update(cls, duties_uu_id: str, data: UpdateDuties, token_dict):
def duties_update(
cls,
duties_uu_id: str,
data: UpdateDuties,
token_dict: EmployeeTokenObject,
):
find_one_duties = Duties.find_one_or_abort(uu_id=duties_uu_id)
access_authorized_duties = Duties.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
@@ -167,9 +179,15 @@ class DutiesPatchEventMethods(MethodToEvent):
__event_keys__ = {
"ca81c6d1-975a-4288-a27b-1069aea84afe": "duties_patch",
}
__event_validation__ = {"ca81c6d1-975a-4288-a27b-1069aea84afe": None}
@classmethod
def duties_patch(cls, duties_uu_id: str, data: PatchRecord, token_dict):
def duties_patch(
cls,
duties_uu_id: str,
data: PatchRecord,
token_dict: EmployeeTokenObject,
):
find_one_duties = Duties.find_one_or_abort(uu_id=duties_uu_id)
access_authorized_duties = Duties.select_action(
duty_id=getattr(token_dict, "duty_id", 5),

View File

@@ -1,17 +1,17 @@
from typing import Union
from fastapi import status
from fastapi.responses import JSONResponse
from api_validations.validations_request import (
InsertCompanyDuty, PatchRecord, ListOptions
InsertCompanyDuty,
PatchRecord,
ListOptions,
)
from databases import Duty
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class DutyListEventMethods(MethodToEvent):
@@ -20,16 +20,20 @@ class DutyListEventMethods(MethodToEvent):
__event_keys__ = {
"23231c7d-4ff2-4b39-b71b-ea350d31fadf": "duty_list",
}
__event_validation__ = {"23231c7d-4ff2-4b39-b71b-ea350d31fadf": None}
@classmethod
def duty_list(
cls, list_options: ListOptions, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
list_options: ListOptions,
token_dict: EmployeeTokenObject,
):
records = Duty.filter_active(
*Duty.get_smart_query(list_options.query),
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
Duty.filter_attr = list_options
records = Duty.filter_all(system=True)
return AlchemyJsonResponse(
completed=True,
message="Duty list is brought successfully",
result=records,
)
@@ -39,10 +43,13 @@ class DutyCreateEventMethods(MethodToEvent):
__event_keys__ = {
"c6ea200e-fa17-4393-b390-37f5337c9c65": "duty_create",
}
__event_validation__ = {"c6ea200e-fa17-4393-b390-37f5337c9c65": InsertCompanyDuty}
@classmethod
def duty_create(
cls, data: InsertCompanyDuty, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: InsertCompanyDuty,
token_dict: EmployeeTokenObject,
):
created_duty = Duty.find_or_create(**data.excluded_dump())
Duty.save()
@@ -62,9 +69,15 @@ class DutyUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"ad952647-bcf8-482d-9e05-b2ee8086483f": "duty_update",
}
__event_validation__ = {"ad952647-bcf8-482d-9e05-b2ee8086483f": None}
@classmethod
def duty_update(cls, company_uu_id: str, data, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]):
def duty_update(
cls,
company_uu_id: str,
data,
token_dict: EmployeeTokenObject,
):
find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
access_authorized_company = Duty.select_action(
duty_id=getattr(token_dict, "duty_id", 5), # ?
@@ -94,9 +107,15 @@ class DutyPatchEventMethods(MethodToEvent):
__event_keys__ = {
"d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": "duty_patch",
}
__event_validation__ = {"d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": None}
@classmethod
def duty_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
def duty_patch(
cls,
company_uu_id: str,
data: PatchRecord,
token_dict: EmployeeTokenObject,
):
find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
access_authorized_company = Duty.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
@@ -104,9 +123,15 @@ class DutyPatchEventMethods(MethodToEvent):
)
if access_authorized_company.count:
action = data.excluded_dump()
find_one_company.active = bool(action.get("active", find_one_company.active))
find_one_company.is_confirmed = bool(action.get("confirm", find_one_company.is_confirmed))
find_one_company.deleted = bool(action.get("delete", find_one_company.deleted))
find_one_company.active = bool(
action.get("active", find_one_company.active)
)
find_one_company.is_confirmed = bool(
action.get("confirm", find_one_company.is_confirmed)
)
find_one_company.deleted = bool(
action.get("delete", find_one_company.deleted)
)
find_one_company.save()
return JSONResponse(
content={

View File

@@ -1,9 +1,7 @@
from datetime import datetime
from typing import Union
from fastapi import status, HTTPException
from fastapi.responses import JSONResponse
from api_library.date_time_actions.date_functions import system_arrow
from api_validations.validations_request import (
InsertEmployees,
BindEmployees2People,
@@ -15,7 +13,7 @@ from databases import Employees, Staff, People, EmployeeHistory
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class EmployeeListEventMethods(MethodToEvent):
@@ -24,18 +22,25 @@ class EmployeeListEventMethods(MethodToEvent):
__event_keys__ = {
"cb677c92-6b05-4122-af5c-12766fae8095": "employee_list",
}
__event_validation__ = {"cb677c92-6b05-4122-af5c-12766fae8095": None}
@classmethod
def employee_list(
cls, list_options: ListOptions, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
list_options: ListOptions,
token_dict: EmployeeTokenObject,
):
employees_staff = Staff.filter_all(
Staff.duties_id.in_(token_dict.duty_id_list),
).data
Employees.filter_attr = list_options
records = Employees.filter_active(
*Employees.get_smart_query(smart_query=list_options.query),
Employees.company_id == token_dict.selected_company.company_id,
records = Employees.filter_all(
Employees.staff_id.in_([staff.id for staff in employees_staff]),
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
return AlchemyJsonResponse(
completed=True,
message="Employee are listed successfully",
result=records,
)
@@ -45,13 +50,20 @@ class EmployeeCreateEventMethods(MethodToEvent):
__event_keys__ = {
"1e1632c3-bb0e-46a5-8e45-da3f6d88ac43": "employee_create",
}
__event_validation__ = {"1e1632c3-bb0e-46a5-8e45-da3f6d88ac43": InsertEmployees}
@classmethod
def employee_create(
cls, data: InsertEmployees, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: InsertEmployees,
token_dict: EmployeeTokenObject,
):
person = People.find_one(uu_id=data.people_uu_id)
staff = Staff.find_one(uu_id=data.staff_uu_id)
person = People.filter_one(
People.uu_id == data.people_uu_id,
).data
staff = Staff.filter_one(
Staff.uu_id == data.staff_uu_id,
).data
if not staff:
return JSONResponse(
content={
@@ -61,8 +73,7 @@ class EmployeeCreateEventMethods(MethodToEvent):
},
status_code=status.HTTP_404_NOT_FOUND,
)
created_employee = Employees.create(
created_employee = Employees.find_or_create(
staff_id=staff.id,
staff_uu_id=str(staff.uu_id),
people_id=person.id if person else None,
@@ -71,7 +82,7 @@ class EmployeeCreateEventMethods(MethodToEvent):
Employees.save()
return JSONResponse(
content={
"completed": True if not created_employee.is_found else False,
"completed": True,
"message": "Create Employee record",
"data": created_employee.get_dict(),
},
@@ -85,10 +96,18 @@ class EmployeeUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"9015a076-d78c-463d-9474-ea343a125fb8": "employee_update",
}
__event_validation__ = {"9015a076-d78c-463d-9474-ea343a125fb8": None}
@classmethod
def employee_update(cls, employee_uu_id: str, data: PatchRecord, token_dict):
find_one_employee = Employees.find_one_or_abort(uu_id=employee_uu_id)
def employee_update(
cls,
employee_uu_id: str,
data: PatchRecord,
token_dict: EmployeeTokenObject,
):
find_one_employee = Employees.filter_one(
Employees.uu_id == employee_uu_id,
).data
access_authorized_employee = Employees.select_action(
employee_id=getattr(token_dict, "employee_id", 5),
filter_expr=[Employees.id == token_dict.get("")],
@@ -121,10 +140,14 @@ class EmployeePatchEventMethods(MethodToEvent):
__event_keys__ = {
"8446ce0b-9310-4b9f-93e2-61f56a9dacd1": "employee_patch",
}
__event_validation__ = {"8446ce0b-9310-4b9f-93e2-61f56a9dacd1": None}
@classmethod
def employee_patch(
cls, employee_uu_id: str, data: PatchRecord, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
employee_uu_id: str,
data: PatchRecord,
token_dict: EmployeeTokenObject,
):
find_one_employee = Employees.find_one_or_abort(uu_id=employee_uu_id)
access_authorized_employee = Employees.select_action(
@@ -166,11 +189,20 @@ class Employee2PeopleEmployEventMethods(MethodToEvent):
__event_keys__ = {
"5eb04057-7a74-4555-b2c6-14eda32dae89": "company_employee_employ",
}
__event_validation__ = {
"5eb04057-7a74-4555-b2c6-14eda32dae89": BindEmployees2People
}
@classmethod
def company_employee_employ(cls, data: BindEmployees2People, token_dict):
selected_staff = Staff.find_one(uu_id=data.staff_uu_id)
selected_people = People.find_one(uu_id=data.people_uu_id)
def company_employee_employ(
cls,
data: BindEmployees2People,
token_dict: EmployeeTokenObject,
):
selected_staff = Staff.filter_one(
Staff.uu_id == data.staff_uu_id,
).data
selected_people = People.filter_one(People.uu_id == data.people_uu_id).data
if not selected_staff:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -182,9 +214,8 @@ class Employee2PeopleEmployEventMethods(MethodToEvent):
detail="People record not found",
)
find_one_employee = Employees.filter_active(
find_one_employee = Employees.filter_all(
Employees.staff_id == selected_staff.id,
Employees.people_id == None,
).data
staff_name_upper = str(selected_staff.staff_name).upper()
@@ -198,9 +229,10 @@ class Employee2PeopleEmployEventMethods(MethodToEvent):
status_code=status.HTTP_406_NOT_ACCEPTABLE,
)
if not data.expiry_starts:
data.expiry_starts = datetime.now()
data.expiry_starts = str(system_arrow.now())
data.expiry_starts = str(system_arrow.get(str(data.expiry_starts)))
find_one_employee = find_one_employee[0].update(
find_one_employee = find_one_employee.update(
people_id=selected_people.id,
expiry_starts=data.expiry_starts,
**token_dict.update_creds,
@@ -222,17 +254,28 @@ class Employee2PeopleFireEventMethods(MethodToEvent):
__event_keys__ = {
"caf914fa-0899-4b0b-a85a-3d40fdaa06a5": "company_employee_fire",
}
__event_validation__ = {
"caf914fa-0899-4b0b-a85a-3d40fdaa06a5": BindEmployees2People
}
@classmethod
def company_employee_fire(cls, data: BindEmployees2People, token_dict):
selected_people = People.find_one(uu_id=data.people_uu_id)
def company_employee_fire(
cls,
data: BindEmployees2People,
token_dict: EmployeeTokenObject,
):
selected_people = People.filter_one(
People.uu_id == data.people_uu_id,
).data
if not selected_people:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="People record not found",
)
find_one_employee: Employees = Employees.find_one(people_id=selected_people.id)
find_one_employee: Employees = Employees.filter_one(
Employees.people_id == selected_people.id,
).data
if not find_one_employee:
return JSONResponse(
content={

View File

@@ -12,8 +12,8 @@ from api_validations.validations_request import (
from databases import Staff, Duties
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_objects.auth.token_objects import EmployeeTokenObject
from api_validations.core_response import AlchemyJsonResponse
class StaffListEventMethods(MethodToEvent):
@@ -21,15 +21,16 @@ class StaffListEventMethods(MethodToEvent):
__event_keys__ = {
"8984a519-99bf-4f25-8f34-2e1aebba468c": "staff_list",
}
__event_validation__ = {"8984a519-99bf-4f25-8f34-2e1aebba468c": None}
@classmethod
def staff_list(cls, list_options: ListOptions, token_dict):
def staff_list(cls, list_options: ListOptions, token_dict: EmployeeTokenObject):
Staff.filter_attr = list_options
records = Staff.filter_active(
*Staff.get_smart_query(smart_query=list_options.query),
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
records = Staff.filter_all()
return AlchemyJsonResponse(
completed=True,
message="Staff are listed successfully",
result=records,
)
@@ -38,11 +39,14 @@ class StaffCreateEventMethods(MethodToEvent):
__event_keys__ = {
"8f619257-19fd-404f-b713-7392c588dc36": "staff_create",
}
__event_validation__ = {"8f619257-19fd-404f-b713-7392c588dc36": InsertStaff}
@classmethod
def staff_create(cls, data: InsertStaff, token_dict: EmployeeTokenObject):
data_dict = data.excluded_dump()
duties = Duties.find_one(uu_id=data.duties_uu_id)
duties = Duties.filter_one(
Duties.uu_id == data.duties_uu_id,
).data
if not duties:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -67,14 +71,15 @@ class StaffGetByUUIDEventMethods(MethodToEvent):
__event_keys__ = {
"7724cfbb-c0ee-4261-959b-61b84e88a34f": "staff_get_by_uu_id",
}
__event_validation__ = {"7724cfbb-c0ee-4261-959b-61b84e88a34f": SelectStaff}
@classmethod
def staff_get_by_uu_id(cls, data: SelectStaff, token_dict):
def staff_get_by_uu_id(cls, data: SelectStaff, token_dict: EmployeeTokenObject):
if data.duties_uu_id:
duties_id = Duties.find_one(uu_id=data.duties_uu_id)
selected_staffs = Staff.filter_active(
Staff.duties_id == duties_id.id,
)
duties_id = Duties.filter_one(
Duties.uu_id == data.duties_uu_id,
).data
selected_staffs = Staff.filter_all(Staff.duties_id == duties_id.id)
return JSONResponse(
content={
"completed": True,
@@ -102,9 +107,10 @@ class StaffUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"5329f35d-ff9d-4656-a831-ba9c8204e483": "staff_update",
}
__event_validation__ = {"5329f35d-ff9d-4656-a831-ba9c8204e483": None}
@classmethod
def staff_update(cls, staff_uu_id: str, data, token_dict):
def staff_update(cls, staff_uu_id: str, data, token_dict: EmployeeTokenObject):
return JSONResponse(
content={"completed": True, "message": "Update Staff record", "data": {}},
status_code=status.HTTP_200_OK,
@@ -117,9 +123,12 @@ class StaffPatchEventMethods(MethodToEvent):
__event_keys__ = {
"b1cd7c0a-1458-472b-894f-3adc857c8512": "staff_patch",
}
__event_validation__ = {"b1cd7c0a-1458-472b-894f-3adc857c8512": None}
@classmethod
def staff_patch(cls, staff_uu_id: str, data: PatchRecord, token_dict):
def staff_patch(
cls, staff_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
):
return JSONResponse(
content={
"completed": False,

View File

@@ -17,8 +17,8 @@ from api_validations.validations_request import (
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_library.date_time_actions.date_functions import DateTimeLocal
from api_validations.core_response import AlchemyJsonResponse
from api_library.date_time_actions.date_functions import system_arrow
class DecisionBookListEventMethods(MethodToEvent):
@@ -27,6 +27,7 @@ class DecisionBookListEventMethods(MethodToEvent):
__event_keys__ = {
"5c10d6ae-2aee-4243-a7c3-94826d028d13": "building_decision_book_list",
}
__event_validation__ = {"5c10d6ae-2aee-4243-a7c3-94826d028d13": None}
@classmethod
def building_decision_book_list(
@@ -36,7 +37,6 @@ class DecisionBookListEventMethods(MethodToEvent):
):
records = []
if isinstance(token_dict, EmployeeTokenObject):
build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
@@ -46,17 +46,19 @@ class DecisionBookListEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
)
records = BuildDecisionBook.filter_active(
BuildDecisionBook.filter_attr = list_options
records = BuildDecisionBook.filter_all(
BuildDecisionBook.build_id.in_([build.id for build in build_id_list]),
*BuildDecisionBook.get_smart_query(list_options.query),
)
elif isinstance(token_dict, OccupantTokenObject):
records = BuildDecisionBook.filter_active(
BuildDecisionBook.filter_attr = list_options
records = BuildDecisionBook.filter_all(
BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
*BuildDecisionBook.get_smart_query(list_options.query),
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
return AlchemyJsonResponse(
completed=True,
message="DecisionBook are listed successfully",
result=records,
)
@@ -66,6 +68,7 @@ class DecisionBookCreateEventMethods(MethodToEvent):
__event_keys__ = {
"0a68cb44-271a-4829-81f6-cd99a5f326b4": "building_decision_book_create",
}
__event_validation__ = {"0a68cb44-271a-4829-81f6-cd99a5f326b4": InsertDecisionBook}
@classmethod
def building_decision_book_create(
@@ -78,15 +81,15 @@ class DecisionBookCreateEventMethods(MethodToEvent):
Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id
)
build = Build.filter_active(
build = Build.filter_one(
Build.uu_id == data.build_uu_id,
)
if not build.data:
).data
if not build:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Emloyee UUID {token_dict.selected_company.employee_uu_id} has no build with given UUID {data_dict.get('build_uu_id')}",
)
data_dict["build_id"] = build.data[0].id
data_dict["build_id"] = build.id
if data.resp_company_uu_id:
Companies.pre_query = Companies.select_action(
duty_id_list=[
@@ -94,21 +97,20 @@ class DecisionBookCreateEventMethods(MethodToEvent):
token_dict.selected_company.bulk_duties_id,
]
)
company = Companies.filter_active(
Companies.uu_id == data.resp_company_uu_id
)
if not company.data:
company = Companies.filter_one(
Companies.uu_id == data.resp_company_uu_id,
).data
if not company:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Duty UUID {token_dict.selected_company.duty_uu_id} has no company with given UUID {data_dict.get('resp_company_uu_id')}",
)
data_dict["resp_company_id"] = company.data[0].id
data_dict["resp_company_uu_id"] = str(company.data[0].uu_id)
data_dict["resp_company_id"] = company.id
data_dict["resp_company_uu_id"] = str(company.uu_id)
build_object = build.data[0]
decision_period_date = DateTimeLocal.get(build_object.decision_period_date)
data_dict["expiry_starts"] = DateTimeLocal.get(
DateTimeLocal.now().date().year,
decision_period_date = system_arrow.get(build.decision_period_date)
data_dict["expiry_starts"] = system_arrow.get(
system_arrow.now().date().year,
int(decision_period_date.date().month),
int(decision_period_date.date().day),
)
@@ -117,7 +119,7 @@ class DecisionBookCreateEventMethods(MethodToEvent):
)
data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
BuildDecisionBook.save()
build_decision_book.save_and_confirm()
return JSONResponse(
status_code=status.HTTP_200_OK,
content=dict(
@@ -127,29 +129,29 @@ class DecisionBookCreateEventMethods(MethodToEvent):
),
)
elif isinstance(token_dict, OccupantTokenObject):
occupant_manager = OccupantTypes.find_one(
occupant_manager = OccupantTypes.filter_by_one(
occupant_category_type="BU", occupant_code="BU-MNG"
)
).data
if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Only Build Manager can create decision book",
)
occupant_build = Build.find_one(id=token_dict.selected_occupant.build_id)
occupant_company = Companies.find_one(
id=token_dict.selected_occupant.responsible_company_id
)
occupant_build = Build.filter_one(
Build.id == token_dict.selected_occupant.build_id,
).data
occupant_company = Companies.filter_one(
Companies.id == token_dict.selected_occupant.responsible_company_id,
).data
data_dict["build_id"] = occupant_build.id
data_dict["build_uu_id"] = str(occupant_build.uu_id)
data_dict["resp_company_id"] = occupant_company.id
data_dict["resp_company_uu_id"] = str(occupant_company.uu_id)
decision_period_date = DateTimeLocal.get(
occupant_build.decision_period_date
)
data_dict["expiry_starts"] = DateTimeLocal.get(
DateTimeLocal.now().date().year,
decision_period_date = system_arrow.get(occupant_build.decision_period_date)
data_dict["expiry_starts"] = system_arrow.get(
system_arrow.now().date().year,
int(decision_period_date.date().month),
int(decision_period_date.date().day),
)
@@ -158,7 +160,9 @@ class DecisionBookCreateEventMethods(MethodToEvent):
)
data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
BuildDecisionBook.save()
build_decision_book.save()
build_decision_book.update(is_confirmed=True)
build_decision_book.save()
return JSONResponse(
status_code=status.HTTP_200_OK,
content=dict(
@@ -175,6 +179,7 @@ class DecisionBookUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29": "building_decision_book_update",
}
__event_validation__ = {"6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29": None}
@classmethod
def building_decision_book_update(cls, data: InsertDecisionBook, token_dict: dict):
@@ -187,6 +192,7 @@ class DecisionBookPatchEventMethods(MethodToEvent):
__event_keys__ = {
"7b58ed84-9a65-4588-994d-30df8366b050": "building_decision_book_patch",
}
__event_validation__ = {"7b58ed84-9a65-4588-994d-30df8366b050": None}
@classmethod
def building_decision_book_patch(cls, data: InsertDecisionBook, token_dict: dict):
@@ -199,6 +205,7 @@ class DecisionBookApprovalEventMethods(MethodToEvent):
__event_keys__ = {
"fc745142-3437-4ca2-89fa-c5a3e2b5c6c2": "building_decision_book_approval",
}
__event_validation__ = {"fc745142-3437-4ca2-89fa-c5a3e2b5c6c2": None}
@classmethod
def building_decision_book_approval(cls, data, token_dict):

View File

@@ -3,6 +3,9 @@ import typing
from fastapi import status, HTTPException
from fastapi.responses import JSONResponse
from api_events.events.events.events_bind_services import (
ServiceBindOccupantEventMethods,
)
from databases import (
Build,
BuildParts,
@@ -20,13 +23,15 @@ from databases import (
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
from api_validations.validations_request import (
InsertBuildDecisionBookItems,
ListOptions,
ListDecisionBook,
)
from databases.sql_models.event.event import Services
class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
@@ -35,14 +40,17 @@ class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
__event_keys__ = {
"eb36de59-8268-4d96-80b6-5d01c12bf0b1": "building_decision_book_items_list",
}
__event_validation__ = {"eb36de59-8268-4d96-80b6-5d01c12bf0b1": None}
@classmethod
def building_decision_book_items_list(
cls,
data: ListDecisionBook,
data: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
decision_book = BuildDecisionBook.find_one(uu_id=data.build_decision_book_uu_id)
decision_book = BuildDecisionBook.filter_one(
BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
).data
if not decision_book:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -52,10 +60,10 @@ class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id,
filter_expr=[
Build.uu_id == decision_book.build_decision_book_uu_id,
Build.uu_id == str(decision_book.uu_id),
],
)
reachable_building = Build.filter_active()
reachable_building = Build.filter_all()
if not reachable_building.data:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -67,34 +75,41 @@ class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
token_dict.selected_company.duty_id,
token_dict.selected_company.bulk_duties_id,
],
filter_expr=[Companies.id == decision_book.company_id],
filter_expr=[Companies.id == decision_book.resp_company_id],
)
reachable_companies = Companies.filter_active()
reachable_companies = Companies.filter_all()
if not reachable_companies.data:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
)
records = BuildDecisionBookItems.filter_active(
BuildDecisionBookItems.filter_attr = BuildDecisionBookItems.FilterModel(
**data.dump()
)
records = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.build_decision_book_id == decision_book.id
)
return JSONResponse(
status_code=status.HTTP_200_OK,
content=dict(
total_count=records.count,
count=len(records.data),
message=f"Decision Book Items has found from given Decision Book UUID {data.build_decision_book_uu_id}",
completed=True,
data=[record.get_dict() for record in records.data],
),
return AlchemyJsonResponse(
completed=True,
message="DecisionBook are listed successfully",
result=records,
)
# return JSONResponse(
# status_code=status.HTTP_200_OK,
# content=dict(
# total_count=records.count,
# count=len(records.data),
# message=f"Decision Book Items has found from given Decision Book UUID {data.build_decision_book_uu_id}",
# completed=True,
# data=[record.get_dict() for record in records.data],
# ),
# )
else:
# BuildDecisionBookItems.pre_query = BuildDecisionBookItems.select_action(
# occupant_id=token_dict.occupant_list["occupant_id"]
# )
# records = BuildDecisionBookItems.filter_active(
# *BuildDecisionBookItems.get_smart_query(list_options.query)
# BuildDecisionBookItems.filter_attr = list_options
# records = BuildDecisionBookItems.filter_all(
# )
# return return_json_response_from_alchemy(response=records, pagination=list_options)
return
@@ -106,18 +121,21 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
__event_keys__ = {
"dce10509-0da5-46fb-af3c-a81d54d5481c": "building_decision_book_items_create",
}
__event_validation__ = {
"dce10509-0da5-46fb-af3c-a81d54d5481c": InsertBuildDecisionBookItems
}
@classmethod
def iterate_over_build_parts(
cls,
build_parts_list,
payment_types,
local_date,
end_date,
unit_price,
unit_type,
book_payment_dict,
unit_price_is_fixed
cls,
build_parts_list,
payment_types,
local_date,
end_date,
unit_price,
unit_type,
book_payment_dict,
unit_price_is_fixed,
):
start_date, payment_return_dict = local_date, {}
for build_part_single in build_parts_list:
@@ -126,11 +144,12 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
local_date = system_arrow.find_last_day_of_month(local_date)
payment_amount = unit_price
if not unit_price_is_fixed:
unit_amount = str(build_part_single.due_part_key).replace(" ", "")
unit_amount = unit_amount.replace(str(unit_type).upper(), "")
unit_amount = int(build_part_single.part_net_size)
payment_amount = abs(unit_price * float(unit_amount)) * -1
payment_amount = -1 * (abs(payment_amount) + (50 - float(abs(payment_amount)) % 50))
BuildDecisionBookPayments.create(
payment_amount = -1 * (
abs(payment_amount) + (50 - float(abs(payment_amount)) % 50)
)
created_book_payment = BuildDecisionBookPayments.find_or_create(
build_parts_id=build_part_single.id,
build_parts_uu_id=str(build_part_single.uu_id),
payment_amount=payment_amount,
@@ -140,45 +159,49 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
process_date_m=int(local_date.month),
process_date_y=int(local_date.year),
period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}",
**book_payment_dict
**book_payment_dict,
)
created_book_payment.save_and_confirm()
local_date = local_date.shift(days=2)
part_key = str(build_part_single.due_part_key).upper()
if part_key not in payment_return_dict:
payment_return_dict[part_key] = payment_amount
return payment_return_dict
@classmethod
def create_payment_records_for_each_build_part(
cls,
data_info_type,
build_id,
unit_price,
unit_type,
decision_book,
decision_book_item,
unit_price_is_fixed,
currency,
debit_start_date: str = None,
debit_end_date: str = None,
cls,
data_info_type,
build_id,
unit_price,
unit_type,
decision_book,
decision_book_item,
unit_price_is_fixed,
currency,
debit_start_date: str = None,
debit_end_date: str = None,
):
build_parts_list = BuildParts.filter_active(
build_parts_list = BuildParts.filter_all(
BuildParts.human_livable == True,
BuildParts.build_id == build_id,
)
print("data_info_type.key", data_info_type.key)
book_payment_dict = dict(
payment_plan_time_periods=str(data_info_type.key),
build_decision_book_item_id=decision_book_item.id,
build_decision_book_item_uu_id=str(decision_book_item.uu_id),
is_confirmed=True,
currency=currency,
)
payment_types = ApiEnumDropdown.get_debit_search(search_debit="DT-D")
if data_info_type.key == "BDT-D":
local_date = system_arrow.get(system_arrow.get(decision_book.expiry_starts).date())
end_date = system_arrow.get(system_arrow.get(decision_book.expiry_ends).date())
cls.iterate_over_build_parts(
local_date = system_arrow.get(
system_arrow.get(decision_book.expiry_starts).date()
)
end_date = system_arrow.get(
system_arrow.get(decision_book.expiry_ends).date()
)
payment_return_dict = cls.iterate_over_build_parts(
build_parts_list=build_parts_list.data,
payment_types=payment_types,
local_date=local_date,
@@ -188,12 +211,11 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
unit_price_is_fixed=unit_price_is_fixed,
book_payment_dict=book_payment_dict,
)
BuildDecisionBookProjects.save()
return
return payment_return_dict
elif data_info_type.key == "BDT-A":
local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
end_date = system_arrow.get(system_arrow.get(debit_end_date).date())
cls.iterate_over_build_parts(
payment_return_dict = cls.iterate_over_build_parts(
build_parts_list=build_parts_list.data,
payment_types=payment_types,
local_date=local_date,
@@ -203,8 +225,7 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
unit_price_is_fixed=unit_price_is_fixed,
book_payment_dict=book_payment_dict,
)
BuildDecisionBookProjects.save()
return
return payment_return_dict
elif data_info_type.key == "BDT-R" or data_info_type.key == "BDT-L":
local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
end_date = system_arrow.get(system_arrow.get(debit_end_date).date())
@@ -212,32 +233,34 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
meeting_date = system_arrow.get(decision_book.meeting_date).date()
already_book_projects = BuildDecisionBookProjects.filter_all(
BuildDecisionBookProjects.build_decision_book_id==decision_book.id,
BuildDecisionBookProjects.project_type==f"{decision_book.decision_type}_{data_info_type.key}",
BuildDecisionBookProjects.build_decision_book_id == decision_book.id,
BuildDecisionBookProjects.project_type
== f"{decision_book.decision_type}_{data_info_type.key}",
system=True,
)
management_room = BuildParts.find_one(
build_id=build_id, part_no=0, active=True, is_confirmed=True
)
occupant_man = OccupantTypes.find_one(
occupant_code="MT-VPR", occupant_category_type="MT"
)
manager_living_space = BuildLivingSpace.filter_by_active(
build_parts_id=management_room.id, occupant_type=occupant_man.id,
)
if not manager_living_space.data:
management_room = BuildParts.filter_one(
BuildParts.build_id == build_id, BuildParts.part_no == 0, system=True
).data
occupant_man = OccupantTypes.filter_by_one(
system=True, occupant_code="MT-VPR", occupant_category_type="MT"
).data
manager_living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.build_parts_id == management_room.id,
BuildLivingSpace.occupant_type == occupant_man.id,
).data
if not manager_living_space:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"{occupant_man.occupant_description} Living Space is not found. Check manager living space and try again",
)
already_book_project_count = already_book_projects.count + 1
manager_living_space = manager_living_space.get(1)
book_project_dict = dict(
project_no=f"{data_info_type.key}_{decision_date.year}_{already_book_project_count}",
project_name=f"{str(meeting_date)}_{decision_book.decision_type} Project {already_book_projects.count + 1}",
project_start_date=str(local_date),
project_stop_date=str(end_date),
project_type=f"{decision_book.decision_type}_{data_info_type.key}",
project_note=f"Fill later",
project_note=str(decision_book_item.item_comment),
build_decision_book_id=decision_book.id,
build_decision_book_uu_id=str(decision_book.uu_id),
build_decision_book_item_id=decision_book_item.id,
@@ -245,30 +268,72 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
project_response_living_space_id=manager_living_space.id,
project_response_living_space_uu_id=str(manager_living_space.uu_id),
)
book_project_created = BuildDecisionBookProjects.find_or_create(**book_project_dict)
book_project_created = BuildDecisionBookProjects.find_or_create(
**book_project_dict
)
book_project_created.save_and_confirm()
print("book_project_created", book_project_created)
item_comment_at_database = decision_book_item.item_comment
decision_book_item.update(
item_comment=f"{book_project_created.project_no}_{book_project_created.project_name} "
f"is assigned to {occupant_man.occupant_description}"
)
project_lead = ApiEnumDropdown.find_one(
key="PTT-LDR", enum_class="ProjectTeamTypes"
f"is assigned to {occupant_man.occupant_description} | {item_comment_at_database}"
)
decision_book_item.save_and_confirm()
project_lead = OccupantTypes.filter_by_one(
system=True, occupant_code="PRJ-LDR", occupant_category_type="PRJ"
).data
build_new_president = OccupantTypes.filter_by_one(
system=True, occupant_code="MT-VPR", occupant_category_type="MT"
).data
new_president = BuildLivingSpace.filter_one(
BuildLivingSpace.occupant_type == build_new_president.id,
BuildLivingSpace.build_parts_id == management_room.id,
).data
project_leader = BuildLivingSpace.filter_one(
BuildLivingSpace.occupant_type == project_lead.id,
BuildLivingSpace.build_parts_id == management_room.id,
BuildLivingSpace.person_id == new_president.person_id,
).data
if not project_leader:
project_leader = BuildLivingSpace.find_or_create(
person_id=new_president.person_id,
person_uu_id=str(new_president.person_uu_id),
build_parts_id=management_room.id,
build_parts_uu_id=str(management_room.uu_id),
occupant_type=project_lead.id,
occupant_type_uu_id=str(project_lead.uu_id),
)
project_leader.save_and_confirm()
related_service = Services.filter_by_one(
system=True,
related_responsibility=project_lead.occupant_code,
).data
ServiceBindOccupantEventMethods.bind_services_occupant_system(
service_id=related_service.id,
build_living_space_id=project_leader.id,
)
project_person = BuildDecisionBookProjectPerson.find_or_create(
build_decision_book_project_id=book_project_created.id,
build_decision_book_project_uu_id=str(book_project_created.uu_id),
living_space_id=manager_living_space.id,
living_space_uu_id=str(manager_living_space.uu_id),
project_team_type_id=project_lead.id,
project_team_type_uu_id=str(project_lead.uu_id),
living_space_id=project_leader.id,
living_space_uu_id=str(project_leader.uu_id),
)
BuildDecisionBookProjects.save()
return
elif data_info_type.key == "BDT-SF":
project_person.save_and_confirm()
book_project_created.update(
project_response_living_space_id=project_leader.id,
project_response_living_space_uu_id=str(project_leader.uu_id),
)
book_project_created.save()
return book_project_created
elif data_info_type.key == "BDT-S":
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="BDT-SF is not implemented yet. Check info type and try again",
detail="BDT-S is not implemented yet. Check info type and try again",
)
elif data_info_type.key == "BDT-I":
return
else:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
@@ -289,9 +354,9 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
)
elif isinstance(token_dict, OccupantTokenObject):
data_dict = data.dump()
occupant_wrt = OccupantTypes.find_one(
occupant_code="MT-WRT", occupant_category_type="MT"
)
occupant_wrt = OccupantTypes.filter_by_one(
system=True, occupant_code="MT-WRT", occupant_category_type="MT"
).data
if token_dict.selected_occupant.occupant_type_id != occupant_wrt.id:
raise HTTPException(
@@ -299,46 +364,69 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
detail="Only WRITER can create decision book item. Check your occupant type and try again",
)
decision_book_person = BuildDecisionBookPerson.find_one(token=data.token)
decision_book = BuildDecisionBook.find_one(
id=decision_book_person.build_decision_book_id
)
BuildDecisionBookItems.check_meeting_is_valid_to_start_add_attendance(
decision_book=decision_book,
token_dict=token_dict,
)
book_items = BuildDecisionBookItems.filter_active(
decision_book_person = BuildDecisionBookPerson.filter_one(
BuildDecisionBookPerson.token == data.token,
).data
decision_book = BuildDecisionBook.filter_one(
BuildDecisionBook.id == decision_book_person.build_decision_book_id,
).data
book_items = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.build_decision_book_id == decision_book.id,
system=True,
)
if int(book_items.count) < 3:
BuildDecisionBookItems.check_meeting_is_valid_to_start_add_attendance(
decision_book=decision_book,
token_dict=token_dict,
)
book_items = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.build_decision_book_id == decision_book.id,
system=True,
)
data_dict["item_order"] = int(book_items.count) + 1
data_dict["build_decision_book_id"] = decision_book.id
data_dict["build_decision_book_uu_id"] = str(decision_book.uu_id)
data_dict["is_confirmed"] = True
data_info_types, data_info_type = ApiEnumDropdown.due_type_search(), None
data_info_type = ApiEnumDropdown.filter_by_one(
system=True,
enum_class="BuildDuesTypes",
key="BDT-I",
).data
data_info_types = ApiEnumDropdown.due_type_search()
for info_type in data_info_types:
if str(info_type.uu_id) == data_dict["info_type_uu_id"]:
data_info_type = info_type
break
if not data_info_type:
row_is_debit = str(data_info_type.key).upper() in ["BDT-A", "BDT-D"]
row_is_project = str(data_info_type.key).upper() in [
"BDT-R",
"BDT-L",
"BDT-S",
]
debit_dates_required = (
not data_dict["debit_start_date"] or not data_dict["debit_end_date"]
)
if row_is_project and debit_dates_required:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Info Type is not valid. Check info type and try again",
detail="Debit Start Date and Debit End Date is required for this payment type. "
"Check debit start date and debit end date and try again",
)
if str(data_info_type.key).upper() in ["BDT-A", "BDT-R", "BDT-L", "BDT-SF"]:
if not data_dict["debit_start_date"] or not data_dict["debit_end_date"]:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Debit Start Date and Debit End Date is required for this payment type. "
"Check debit start date and debit end date and try again",
)
data_dict["info_type_id"] = data_info_type.id
data_dict["info_type_uu_id"] = str(data_info_type.uu_id)
unit_price, unit_type = float(data_dict["unit_price"]), str(data_dict["unit_type"])
debit_start_date, debit_end_date = data_dict["debit_start_date"], data_dict["debit_end_date"]
unit_price, unit_type = float(data_dict["unit_price"]), str(
data_dict["unit_type"]
)
debit_start_date, debit_end_date = (
data_dict["debit_start_date"],
data_dict["debit_end_date"],
)
currency = data_dict["currency"]
del (
data_dict["token"],
@@ -347,59 +435,61 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
data_dict["unit_price_is_fixed"],
data_dict["debit_start_date"],
data_dict["debit_end_date"],
data_dict["currency"]
data_dict["currency"],
)
if new_decision_book_item := BuildDecisionBookItems.find_or_create(**data_dict):
if new_decision_book_item.is_found:
return JSONResponse(
status_code=status.HTTP_200_OK,
content=dict(
message=f"Decision Book Item is already exist for given Decision Book UUID {decision_book.uu_id}",
completed=True,
data=new_decision_book_item.get_dict(),
),
)
if created_payment_records_dict := cls.create_payment_records_for_each_build_part(
data_info_type=data_info_type,
build_id=decision_book.build_id,
unit_price=unit_price,
unit_type=unit_type.upper(),
decision_book=decision_book,
decision_book_item=new_decision_book_item,
unit_price_is_fixed=data.unit_price_is_fixed,
debit_start_date=debit_start_date,
debit_end_date=debit_end_date,
currency=currency
):
if data_info_type.key == "BDT-A" or data_info_type.key == "BDT-D":
if data_info_type.key == "BDT-D":
item_comment = "Regular Payment Plan : "
else:
item_comment = "Additional Payment Plan : "
for key, value in dict(sorted(
created_payment_records_dict.items(),
key=lambda x: x[1],
reverse=True
)).items():
item_comment += f" {key} | {abs(float(value))} {currency}, "
item_comment = item_comment[:-2]
new_decision_book_item.update(
item_comment=item_comment
new_decision_book_item = BuildDecisionBookItems.find_or_create(**data_dict)
new_decision_book_item.save_and_confirm()
print("new_decision_book_item", new_decision_book_item)
if created_payment_records_dict := cls.create_payment_records_for_each_build_part(
data_info_type=data_info_type,
build_id=decision_book.build_id,
unit_price=unit_price,
unit_type=unit_type.upper(),
decision_book=decision_book,
decision_book_item=new_decision_book_item,
unit_price_is_fixed=data.unit_price_is_fixed,
debit_start_date=debit_start_date,
debit_end_date=debit_end_date,
currency=currency,
):
if row_is_debit:
if data_info_type.key == "BDT-D":
item_comment = "Regular Payment Plan : "
else:
item_comment = "Additional Payment Plan : "
for key, value in dict(
sorted(
created_payment_records_dict.items(),
key=lambda x: x[1],
reverse=True,
)
new_decision_book_item.update(is_payment_created=True)
return JSONResponse(
status_code=status.HTTP_200_OK,
content=dict(
message=f"Decision Book Item has created for given Decision Book UUID {decision_book.uu_id}",
completed=True,
data=new_decision_book_item.get_dict(),
),
)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Decision Book Item is not created. Check info type and info no and try again. Unique constraint index is implemented for info type and info no",
)
).items():
item_comment += f" {key} | {abs(float(value))} {currency}, "
item_comment = item_comment[:-2]
new_decision_book_item.update(item_comment=item_comment)
new_decision_book_item.update(is_payment_created=True)
elif row_is_project:
project_no = str(created_payment_records_dict.project_no)
item_comment = (
f"{data.item_comment} | @ Project is created no : {project_no}."
)
new_decision_book_item.update(item_comment=item_comment)
new_decision_book_item.update(is_payment_created=True)
new_decision_book_item.save_and_confirm()
return JSONResponse(
status_code=status.HTTP_200_OK,
content=dict(
message=f"Decision Book Item has created for given Decision Book UUID {decision_book.uu_id}",
completed=True,
data=new_decision_book_item.get_dict(),
),
)
# raise HTTPException(
# status_code=status.HTTP_400_BAD_REQUEST,
# detail="Decision Book Item is not created. Check info type and info no and try again. Unique constraint index is implemented for info type and info no",
# )
class DecisionBookDecisionBookItemsUpdateEventMethods(MethodToEvent):
@@ -408,6 +498,7 @@ class DecisionBookDecisionBookItemsUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": "building_decision_book_items_update",
}
__event_validation__ = {"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": None}
@classmethod
def building_decision_book_items_update(
@@ -424,6 +515,7 @@ class DecisionBookDecisionBookItemsPatchEventMethods(MethodToEvent):
__event_keys__ = {
"42328809-b516-477b-82cc-2d6fadf28843": "building_decision_book_items_patch",
}
__event_validation__ = {"42328809-b516-477b-82cc-2d6fadf28843": None}
@classmethod
def building_decision_book_items_patch(

View File

@@ -1,5 +1,105 @@
import typing
from databases import (
Build,
BuildParts,
BuildDecisionBook,
BuildDecisionBookItems,
BuildDecisionBookPerson,
BuildDecisionBookPayments,
BuildDecisionBookProjects,
BuildDecisionBookProjectPerson,
ApiEnumDropdown,
OccupantTypes,
Companies,
BuildLivingSpace,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
class DecisionBookDecisionBookItemsDebitsEvents(MethodToEvent): ...
class DecisionBookDecisionBookItemsDebitsListEventMethods(MethodToEvent):
event_type = "SELECT"
__event_keys__ = {
"a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": "decision_book_decision_book_items_debits_list",
}
__event_validation__ = {"a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": None}
@classmethod
def decision_book_decision_book_items_debits_list(
cls,
decision_book_id: str,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
BuildDecisionBookItems.pre_query = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.decision_book_id == decision_book_id,
).query
BuildDecisionBookItems.filter_attr = None
records = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.decision_book_id == decision_book_id,
)
return AlchemyJsonResponse(
completed=True,
message="Decision Book Items Debits are listed",
result=records,
)
class DecisionBookDecisionBookItemsDebitsCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": "decision_book_decision_book_items_debits_create",
}
__event_validation__ = {"a1d2b1f6-9b8d-4f6b-8f4d-6b1f6a9d8b1a": None}
@classmethod
def decision_book_decision_book_items_debits_create(
cls,
decision_book_id: str,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
decision_book_items_debits: dict,
):
if isinstance(token_dict, EmployeeTokenObject):
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE,
detail="No employee can reach this event. An notification is send to admin about event registration",
)
decision_book_items_debits["decision_book_id"] = decision_book_id
decision_book_items_debits["created_at"] = system_arrow().datetime
decision_book_items_debits["created_by"] = token_dict.employee_id
decision_book_items_debits["updated_at"] = system_arrow().datetime
decision_book_items_debits["updated_by"] = token_dict.employee_id
decision_book_items_debits["is_active"] = True
decision_book_items_debits["is_confirmed"] = False
decision_book_items_debits["is_deleted"] = False
decision_book_items_debits["confirmed_at"] = None
decision_book_items_debits["confirmed_by"] = None
decision_book_items_debits["deleted_at"] = None
decision_book_items_debits["deleted_by"] = None
decision_book_items_debits["confirmed_at"] = None
decision_book_items_debits["confirmed_by"] = None
decision_book_items_debits["deleted_at"] = None
decision_book_items_debits["deleted_by"] = None
decision_book_items_debits["confirmed_at"] = None
decision_book_items_debits["confirmed_by"] = None
decision_book_items_debits["deleted_at"] = None
decision_book_items_debits["deleted_by"] = None
BuildDecisionBookItems.pre_query = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.decision_book_id == decision_book_id,
).query
BuildDecisionBookItems.filter_attr = None
records = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.decision_book_id == decision_book_id,
)
return AlchemyJsonResponse(
completed=True,
message="Decision Book Items Debits are listed",
result=records,
)

View File

@@ -25,7 +25,7 @@ from api_validations.validations_request import (
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class DecisionBookPersonListEventMethods(MethodToEvent):
@@ -34,10 +34,13 @@ class DecisionBookPersonListEventMethods(MethodToEvent):
__event_keys__ = {
"ea324dc0-3b08-4896-9040-7fa0401a176f": "building_decision_book_person_list",
}
__event_validation__ = {"ea324dc0-3b08-4896-9040-7fa0401a176f": None}
@classmethod
def building_decision_book_person_list(
cls, data: ListOptions, token_dict: EmployeeTokenObject
cls,
data: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
return
@@ -48,6 +51,9 @@ class DecisionBookPersonAddEventMethods(MethodToEvent):
__event_keys__ = {
"e346f720-880b-4b07-93d6-9ac76fbbaa33": "building_decision_book_person_add",
}
__event_validation__ = {
"e346f720-880b-4b07-93d6-9ac76fbbaa33": DecisionBookDecisionBookInvitationsUpdate
}
@classmethod
def building_decision_book_person_add(
@@ -61,17 +67,17 @@ class DecisionBookPersonAddEventMethods(MethodToEvent):
detail="Employee cannot create decision book invitations",
)
elif isinstance(token_dict, OccupantTokenObject):
decision_book = BuildDecisionBook.find_one(
uu_id=data.build_decision_book_uu_id
)
decision_book = BuildDecisionBook.filter_one(
BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
).data
if not decision_book:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"No Decision Book is match with given UUID {data.build_decision_book_uu_id}",
)
manager_occupant_type = OccupantTypes.find_or_abort(
occupant_code="BU-MNG", occupant_category_type="BU"
)
manager_occupant_type = OccupantTypes.filter_by_one(
system=True, occupant_code="BU-MNG", occupant_category_type="BU"
).data
if (
not manager_occupant_type.uu_id
== token_dict.selected_occupant.occupant_type_uu_id
@@ -81,42 +87,41 @@ class DecisionBookPersonAddEventMethods(MethodToEvent):
detail="Only Build Manager can update the invitation",
)
assign_occupant_type = OccupantTypes.find_or_abort(
assign_occupant_type = OccupantTypes.filter_by_one(
system=True,
uu_id=data.occupant_type_uu_id,
occupant_category_type="MT",
)
).data
if not assign_occupant_type:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
)
manger_book_person = BuildDecisionBookPerson.find_one(
token=data.token,
build_decision_book_uu_id=data.build_decision_book_uu_id,
is_confirmed=True,
active=True,
)
manger_book_person = BuildDecisionBookPerson.filter_one(
BuildDecisionBookPerson.token == data.token,
BuildDecisionBookPerson.build_decision_book_uu_id
== data.build_decision_book_uu_id,
).data
if not manger_book_person:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Manager person not found. Please check token",
)
book_invite = BuildDecisionBookInvitations.find_one(
id=manger_book_person.invite_id,
build_id=token_dict.selected_occupant.build_id,
)
book_invite = BuildDecisionBookInvitations.filter_one(
BuildDecisionBookInvitations.id == manger_book_person.invite_id,
BuildDecisionBookInvitations.build_id
== token_dict.selected_occupant.build_id,
).data
if not book_invite:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Invitation not found. Please check token",
)
selected_book_person = BuildDecisionBookPerson.find_one(
invite_id=book_invite.id,
person_uu_id=data.person_uu_id,
is_confirmed=True,
active=True,
)
selected_book_person = BuildDecisionBookPerson.filter_one(
BuildDecisionBookPerson.invite_id == book_invite.id,
BuildDecisionBookPerson.person_uu_id == data.person_uu_id,
).data
if not selected_book_person:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -143,6 +148,9 @@ class DecisionBookPersonRemoveEventMethods(MethodToEvent):
__event_keys__ = {
"30588869-04cd-48ea-ad00-0e4f8dd7f735": "building_decision_book_people_remove",
}
__event_validation__ = {
"30588869-04cd-48ea-ad00-0e4f8dd7f735": RemoveDecisionBookPerson
}
@classmethod
def building_decision_book_people_remove(
@@ -157,6 +165,9 @@ class DecisionBookPersonAttendEventMethods(MethodToEvent):
__event_keys__ = {
"bdcba521-0116-441c-ace1-84c5b68c86c7": "decision_book_invitations_attend",
}
__event_validation__ = {
"bdcba521-0116-441c-ace1-84c5b68c86c7": DecisionBookDecisionBookInvitationsAttend
}
@classmethod
def decision_book_invitations_attend(
@@ -171,10 +182,10 @@ class DecisionBookPersonAttendEventMethods(MethodToEvent):
detail="Employee cannot create decision book invitations",
)
token_user = Users.find_one(id=token_dict.user_id)
invitation_person = BuildDecisionBookPerson.find_one(
token=data.token, active=True, is_confirmed=True
)
token_user = Users.filter_one(Users.id == token_dict.user_id).data
invitation_person = BuildDecisionBookPerson.filter_one(
BuildDecisionBookPerson.token == data.token,
).data
if not invitation_person:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -189,10 +200,11 @@ class DecisionBookPersonAttendEventMethods(MethodToEvent):
# detail=f"Invitation for the user {token_user.email} is not valid. Please check token",
# )
# todo check if vicarious person is valid
invitation = BuildDecisionBookInvitations.find_one(
id=invitation_person.invite_id,
build_id=token_dict.selected_occupant.build_id,
)
invitation = BuildDecisionBookInvitations.filter_one(
BuildDecisionBookInvitations.id == invitation_person.invite_id,
BuildDecisionBookInvitations.build_id
== token_dict.selected_occupant.build_id,
).data
if not invitation:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -222,6 +234,9 @@ class DecisionBookPersonAssignOccupantEventMethods(MethodToEvent):
__event_keys__ = {
"c0b65098-9c79-4212-b1d0-c7e7836cf141": "decision_book_invitations_assign_occupant",
}
__event_validation__ = {
"c0b65098-9c79-4212-b1d0-c7e7836cf141": DecisionBookDecisionBookInvitationsAssign
}
@classmethod
def decision_book_invitations_assign_occupant(
@@ -236,89 +251,85 @@ class DecisionBookPersonAssignOccupantEventMethods(MethodToEvent):
detail="Employee cannot create decision book invitations",
)
book_person_manager = BuildDecisionBookPerson.find_one(
token=data.token,
build_living_space_id=token_dict.selected_occupant.living_space_id,
active=True,
is_confirmed=True,
)
manager_occupant_type = OccupantTypes.find_or_abort(
occupant_code="BU-MNG", occupant_category_type="BU"
)
book_person_manager = BuildDecisionBookPerson.filter_one(
BuildDecisionBookPerson.token == data.token,
BuildDecisionBookPerson.build_living_space_id
== token_dict.selected_occupant.living_space_id,
).data
manager_occupant_type = OccupantTypes.filter_by_one(
system=True, occupant_code="BU-MNG", occupant_category_type="BU"
).data
book_person_manager.check_occupant_type(manager_occupant_type)
# supervisor_occupant_type = OccupantTypes.find_or_abort(occupant_code="BU-SPV", occupant_category_type="BU")
# book_person_supervisor.check_occupant_type(supervisor_occupant_type)
invitation = BuildDecisionBookInvitations.find_one(
id=book_person_manager.invite_id,
build_id=token_dict.selected_occupant.build_id,
active=True,
is_confirmed=True,
)
invitation = BuildDecisionBookInvitations.filter_one(
BuildDecisionBookInvitations.id == book_person_manager.invite_id,
BuildDecisionBookInvitations.build_id
== token_dict.selected_occupant.build_id,
).data
if not invitation:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Invitation not found. Please check token",
)
assign_occupant_type = OccupantTypes.find_or_abort(
uu_id=data.occupant_type_uu_id, is_confirmed=True, active=True
)
assign_occupant_type = OccupantTypes.filter_by_one(
system=True,
uu_id=data.occupant_type_uu_id,
).data
if not assign_occupant_type:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
)
build_parts_of_token = BuildParts.filter_active(
build_parts_of_token = BuildParts.filter_all(
BuildParts.build_id == token_dict.selected_occupant.build_id,
)
selected_living_space = BuildLivingSpace.filter_active(
).data
selected_living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.uu_id == data.build_living_space_uu_id,
BuildLivingSpace.build_parts_id.in_(
[build.id for build in build_parts_of_token.data]
[build.id for build in build_parts_of_token]
),
)
if not selected_living_space.data:
).data
if not selected_living_space:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Person not found. Please check person uuid",
)
selected_living_space = selected_living_space.get(1)
book_person_to_assign: BuildDecisionBookPerson = (
BuildDecisionBookPerson.find_one(
build_living_space_id=selected_living_space.id,
invite_id=invitation.id,
active=True,
is_confirmed=True,
)
BuildDecisionBookPerson.filter_one(
BuildDecisionBookPerson.build_living_space_id
== selected_living_space.id,
BuildDecisionBookPerson.invite_id == invitation.id,
).data
)
if not book_person_to_assign:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Person not found in the invitation list. Please check person uuid: {data.person_uu_id}",
detail=f"Person not found in the invitation list. Please check person uuid: {data.build_living_space_uu_id}",
)
if not book_person_to_assign.is_attending:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Person is declined the invitation. This person is not attending the meeting. "
f"Please check person uuid: {data.person_uu_id}. Invite UUID: {invitation.uu_id}",
f"Please check person uuid: {data.build_living_space_uu_id}. Invite UUID: {invitation.uu_id}",
)
if assign_occupant_type.occupant_code in ("MT-PRS", "MT-WRT"):
occupant_type_unique = OccupantTypes.find_or_abort(
occupant_type_unique = OccupantTypes.filter_by_one(
system=True,
occupant_code=assign_occupant_type.occupant_code,
occupant_category_type="MT",
)
if assigned_book_person_occupant := BuildDecisionBookPersonOccupants.find_one(
invite_id=invitation.id,
occupant_type_id=occupant_type_unique.id,
active=True,
is_confirmed=True,
):
).data
if assigned_book_person_occupant := BuildDecisionBookPersonOccupants.filter_one(
BuildDecisionBookPersonOccupants.invite_id == invitation.id,
BuildDecisionBookPersonOccupants.occupant_type_id
== occupant_type_unique.id,
).data:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Only one person can be assigned to {assign_occupant_type.occupant_code} type"
@@ -326,13 +337,12 @@ class DecisionBookPersonAssignOccupantEventMethods(MethodToEvent):
)
if assign_occupant_type.occupant_code == "BU-MNG":
person_occupant_manager = BuildDecisionBookPersonOccupants.find_one(
invite_id=invitation.id,
occupant_type_id=manager_occupant_type.id,
active=True,
is_confirmed=True,
person_occupant_manager = BuildDecisionBookPersonOccupants.filter_one(
BuildDecisionBookPersonOccupants.invite_id == invitation.id,
BuildDecisionBookPersonOccupants.occupant_type_id
== manager_occupant_type.id,
)
person_occupant_manager.delete(destroy=True)
person_occupant_manager.query.delete()
book_person_to_assign.add_occupant_type(
occupant_type=assign_occupant_type,
@@ -373,7 +383,7 @@ DecisionBookPersonAssignOccupantEventMethod = (
# Build.id == decision_book.build_id,
# ],
# )
# reachable_building = Build.filter_active()
# reachable_building = Build.filter_all()
# if not reachable_building.data:
# raise HTTPException(
# status_code=status.HTTP_404_NOT_FOUND,
@@ -387,7 +397,7 @@ DecisionBookPersonAssignOccupantEventMethod = (
# ],
# filter_expr=[Companies.id == decision_book.resp_company_id],
# )
# reachable_companies = Companies.filter_active()
# reachable_companies = Companies.filter_all()
# if not reachable_companies.data:
# raise HTTPException(
# status_code=status.HTTP_404_NOT_FOUND,
@@ -399,7 +409,7 @@ DecisionBookPersonAssignOccupantEventMethod = (
# status_code=status.HTTP_404_NOT_FOUND,
# detail=f"No person is match with given UUID {data.person_uu_id}",
# )
# management_typecode = ApiEnumDropdown.filter_active(
# management_typecode = ApiEnumDropdown.filter_all(
# ApiEnumDropdown.uu_id == data.management_typecode_uu_id,
# ApiEnumDropdown.enum_class.in_("BuildManagementType", "BuildDuesTypes"),
# )

View File

@@ -22,7 +22,7 @@ from api_validations.validations_request import (
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from api_library.date_time_actions.date_functions import system_arrow
@@ -32,6 +32,7 @@ class BuildDecisionBookInvitationsListEventMethods(MethodToEvent):
__event_keys__ = {
"e2277528-8c9c-4c0c-ae64-3ce80cae664b": "decision_book_invitations_list",
}
__event_validation__ = {"e2277528-8c9c-4c0c-ae64-3ce80cae664b": None}
@classmethod
def decision_book_invitations_list(
@@ -48,6 +49,9 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
__event_keys__ = {
"d0bfa20c-841d-421c-98e6-d308f938d16a": "decision_book_invitations_create",
}
__event_validation__ = {
"d0bfa20c-841d-421c-98e6-d308f938d16a": DecisionBookDecisionBookInvitations
}
@classmethod
def decision_book_invitations_create(
@@ -62,9 +66,9 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
detail="Employee cannot create decision book invitations",
)
# Check token posses the occupant type of Build Manager
occupant_manager = OccupantTypes.find_one(
occupant_category_type="BU", occupant_code="BU-MNG"
)
occupant_manager = OccupantTypes.filter_by_one(
system=True, occupant_category_type="BU", occupant_code="BU-MNG"
).data
if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
@@ -72,31 +76,23 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
)
# Check decision book is valid for this token and building
decision_book = BuildDecisionBook.find_one(
uu_id=data.build_decision_book_uu_id,
build_id=token_dict.selected_occupant.build_id,
)
decision_book = BuildDecisionBook.filter_one(
BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
).data
if not decision_book:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Decision book not found. Please create decision book first",
)
occupant_building = Build.find_one(id=token_dict.selected_occupant.build_id)
# Check meeting type is valid
meeting_type = ApiEnumDropdown.find_one(
enum_class="MeetingTypes",
)
if not meeting_type:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Meeting type not found",
)
occupant_building = Build.filter_one(
Build.id == token_dict.selected_occupant.build_id
).data
# Check planned decision book date is valid
if (
not system_arrow.get(data.planned_date).date()
>= system_arrow.shift(days=1).date()
>= system_arrow.now().shift(days=1).date()
):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
@@ -104,48 +100,40 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
)
# Create an invitation for specific invitation type to start invite sending process
planned_date_expires = str(
system_arrow.get(data.planned_date).shift(days=15).date()
)
book_invitation = BuildDecisionBookInvitations.find_or_create(
build_id=token_dict.selected_occupant.build_id,
build_uu_id=token_dict.selected_occupant.build_uuid,
decision_book_id=decision_book.id,
decision_book_uu_id=str(decision_book.uu_id),
invitation_type=meeting_type.key,
invitation_type=str(decision_book.decision_type),
living_part_count=occupant_building.livable_part_count,
living_part_percentage=0.51,
message=data.message,
planned_date=data.planned_date,
planned_date_expires=str(
system_arrow.get(data.planned_date).shift(days=15).date()
),
planned_date=str(system_arrow.get(data.planned_date)),
planned_date_expires=planned_date_expires,
expiry_ends=str(system_arrow.get(data.planned_date).shift(days=15).date()),
is_confirmed=True,
)
if book_invitation.is_found:
detail_message = (
f"Invitation with: {str(book_invitation.planned_date)} already exists"
f" for {book_invitation.invitation_type}"
)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=detail_message,
)
book_invitation.save_and_confirm()
# Get all the parts of the building that is occupant in token
build_parts = BuildParts.filter_active(
BuildParts.build_id == occupant_building.id
build_parts = BuildParts.filter_all(
BuildParts.build_id == occupant_building.id,
)
# Get all build living spaces that is found in building with distinct person id
occupants = OccupantTypes.filter_all()
occupants = OccupantTypes.filter_all(system=True)
BuildLivingSpace.filter_attr = None
build_living_spaces_people = (
BuildLivingSpace.filter_active(
BuildLivingSpace.filter_all(
BuildLivingSpace.build_parts_id.in_(
[build_part.id for build_part in build_parts.data]
),
BuildLivingSpace.occupant_type.in_(
[occupant.id for occupant in occupants.data]
),
filter_records=False,
)
.query.distinct(BuildLivingSpace.person_id)
.all()
@@ -160,12 +148,12 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
)
# Send invitation to all the users as attend and update the manager as build manager
attendance_occupant_type = OccupantTypes.find_or_abort(
occupant_code="MT-ATT", occupant_category_type="MT"
)
manager_occupant_type = OccupantTypes.find_or_abort(
occupant_code="BU-MNG", occupant_category_type="BU"
)
attendance_occupant_type = OccupantTypes.filter_by_one(
system=True, occupant_code="MT-ATT", occupant_category_type="MT"
).data
manager_occupant_type = OccupantTypes.filter_by_one(
system=True, occupant_code="BU-MNG", occupant_category_type="BU"
).data
build_decision_book_person_dict = dict(
build_decision_book_id=decision_book.id,
@@ -175,14 +163,14 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
send_date=str(system_arrow.now().date()),
expiry_starts=decision_book.expiry_starts,
expiry_ends=decision_book.expiry_ends,
is_confirmed=True,
)
# Check if the invitation is already created at database
for build_living_spaces_user in build_living_spaces_people:
if invite := BuildDecisionBookPerson.find_one(
invite_id=book_invitation.id,
build_living_space_id=build_living_spaces_user.id,
):
if invite := BuildDecisionBookPerson.filter_one(
BuildDecisionBookPerson.invite_id == book_invitation.id,
BuildDecisionBookPerson.build_living_space_id
== build_living_spaces_user.id,
).data:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Invitation already send to {build_living_spaces_user.email} "
@@ -196,24 +184,24 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
person_id=build_living_spaces_user.person_id,
token=Users.generate_token(40),
)
invitations_person.save_and_confirm()
invitations_person.add_occupant_type(occupant_type=attendance_occupant_type)
if invitations_person and not invitations_person.is_found:
if invitations_person:
print(f'"{invitations_person.token}",')
spaces_user = Users.find_one(
active=True,
is_confirmed=True,
person_id=build_living_spaces_user.person_id,
)
spaces_user = Users.filter_one(
Users.person_id == build_living_spaces_user.person_id,
).data
# print(
# f"Invitation is send : {spaces_user.email} "
# f"Token : {invitations_person.token} "
# f"Send Date : {str(invitations_person.send_date.date())}"
# )
manager_living_spaces = BuildLivingSpace.filter_active(
manager_living_spaces = BuildLivingSpace.filter_all(
BuildLivingSpace.person_id == token_dict.person_id,
)
manager_people = BuildDecisionBookPerson.filter_active(
manager_people = BuildDecisionBookPerson.filter_all(
BuildDecisionBookPerson.invite_id == book_invitation.id,
BuildDecisionBookPerson.build_living_space_id.in_(
[
@@ -221,16 +209,19 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
for manager_living_space in manager_living_spaces.data
]
),
system=True,
)
manager_people_occupants = BuildDecisionBookPersonOccupants.filter_active(
manager_people_occupants = BuildDecisionBookPersonOccupants.filter_all(
BuildDecisionBookPersonOccupants.build_decision_book_person_id
== manager_people.get(1).id
== manager_people.get(1).id,
system=True,
)
dlt = [
occupants.delete(destroy=True)
for occupants in manager_people_occupants.data
]
dlt = [occupants.delete(destroy=True) for occupants in manager_people.data]
if manager_people_occupants.count:
manager_people_occupants.query.delete()
BuildDecisionBookPersonOccupants.save()
if manager_people.count:
manager_people.query.delete()
BuildDecisionBookPerson.save()
if book_person_manager := BuildDecisionBookPerson.find_or_create(
**build_decision_book_person_dict,
@@ -241,6 +232,7 @@ class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
person_id=token_dict.person_id,
token=Users.generate_token(40),
):
book_person_manager.save_and_confirm()
book_person_manager.add_occupant_type(occupant_type=manager_occupant_type)
print(f"Manager Token : {book_person_manager.token}")
BuildDecisionBookPerson.save()
@@ -260,6 +252,9 @@ class BuildDecisionBookInvitationsUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"92413636-53a8-4a05-842c-1485a64e00d1": "decision_book_invitations_attend",
}
__event_validation__ = {
"92413636-53a8-4a05-842c-1485a64e00d1": DecisionBookDecisionBookInvitationsUpdate
}
@classmethod
def decision_book_invitations_attend(

View File

@@ -0,0 +1,169 @@
from typing import Union
from fastapi.responses import JSONResponse
from fastapi import status
from api_validations.validations_response.parts import BuildPartsListResponse
from databases import (
Build,
BuildParts,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse
from api_validations.validations_request import (
InsertBuildParts,
UpdateBuildParts,
ListOptions,
)
from databases.sql_models.building.decision_book import BuildDecisionBookPayments
class DecisionBookPaymentListEventMethods(MethodToEvent):
event_type = "SELECT"
__event_keys__ = {
"49bb8ab8-520d-4676-a159-aaf84f37f372": "decision_book_payment_list"
}
__event_validation__ = {"49bb8ab8-520d-4676-a159-aaf84f37f372": None}
@classmethod
def decision_book_payment_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
"""
SELECT payment_plan_time_periods, process_date, payment_amount, currency, payment_types_id,
payment_types_uu_id, period_time, process_date_y, process_date_m, build_decision_book_item_id,
build_decision_book_item_uu_id, decision_book_project_id, decision_book_project_uu_id, build_parts_id,
build_parts_uu_id, id, uu_id, ref_id, created_at, updated_at, cryp_uu_id, created_by, created_by_id,
updated_by, updated_by_id, confirmed_by, confirmed_by_id, is_confirmed, replication_id, deleted,
active, is_notification_send, is_email_send, expiry_starts, expiry_ends, account_records_id,
account_records_uu_id FROM public.build_decision_book_payments;
"""
from sqlalchemy import func, select, union_all, extract, Integer
build_parts_id, build_decision_book_id = 7, ""
payment_types_id_recv, payment_types_id_deb = 46, 45
BuildDecisionBookPayments.filter_attr = list_options
# Define the subqueries
debit_subquery = (
select(
BuildDecisionBookPayments.payment_plan_time_periods,
func.sum(BuildDecisionBookPayments.payment_amount).label("debit"),
func.cast(0, Integer).label("recv"),
func.max(BuildDecisionBookPayments.process_date).label("ls"),
)
.where(
BuildDecisionBookPayments.build_parts_id == build_parts_id,
BuildDecisionBookPayments.payment_types_id == payment_types_id_deb,
BuildDecisionBookPayments.build_decision_book_id
== build_decision_book_id,
extract("year", func.current_date())
== extract("year", BuildDecisionBookPayments.process_date),
extract("month", func.current_date())
== extract("month", BuildDecisionBookPayments.process_date),
)
.group_by(BuildDecisionBookPayments.payment_plan_time_periods)
)
recv_subquery = (
select(
BuildDecisionBookPayments.payment_plan_time_periods,
func.cast(0, Integer).label("debit"),
func.sum(BuildDecisionBookPayments.payment_amount).label("recv"),
func.max(BuildDecisionBookPayments.process_date).label("ls"),
)
.where(
BuildDecisionBookPayments.build_parts_id == build_parts_id,
BuildDecisionBookPayments.payment_types_id == payment_types_id_recv,
BuildDecisionBookPayments.build_decision_book_id
== build_decision_book_id,
extract("year", func.current_date())
== extract("year", BuildDecisionBookPayments.process_date),
extract("month", func.current_date())
== extract("month", BuildDecisionBookPayments.process_date),
)
.group_by(BuildDecisionBookPayments.payment_plan_time_periods)
)
# Combine the subqueries using union_all
combined_subquery = union_all(debit_subquery, recv_subquery).alias("AA")
# Final query
final_query = select(
combined_subquery.c.payment_plan_time_periods,
func.sum(combined_subquery.c.debit).label("debit"),
func.sum(combined_subquery.c.recv).label("recv"),
combined_subquery.c.ls.label("Last Seen"),
).group_by(
combined_subquery.c.payment_plan_time_periods, combined_subquery.c.ls
)
# Execute the query
book_payments_month = BuildDecisionBookPayments.session.execute(
final_query
).fetchall()
print("book_payments_month", book_payments_month)
debit_subquery = (
select(
BuildDecisionBookPayments.payment_plan_time_periods,
func.sum(BuildDecisionBookPayments.payment_amount).label("debit"),
func.cast(0, Integer).label("recv"),
func.max(BuildDecisionBookPayments.process_date).label("ls"),
)
.where(
BuildDecisionBookPayments.build_parts_id == build_parts_id,
BuildDecisionBookPayments.payment_types_id == payment_types_id_deb,
BuildDecisionBookPayments.build_decision_book_id
== build_decision_book_id,
)
.group_by(BuildDecisionBookPayments.payment_plan_time_periods)
)
recv_subquery = (
select(
BuildDecisionBookPayments.payment_plan_time_periods,
func.cast(0, Integer).label("debit"),
func.sum(BuildDecisionBookPayments.payment_amount).label("recv"),
func.max(BuildDecisionBookPayments.process_date).label("ls"),
)
.where(
BuildDecisionBookPayments.build_parts_id == build_parts_id,
BuildDecisionBookPayments.payment_types_id == payment_types_id_recv,
BuildDecisionBookPayments.build_decision_book_id
== build_decision_book_id,
)
.group_by(BuildDecisionBookPayments.payment_plan_time_periods)
)
# Combine the subqueries using union_all
combined_subquery = union_all(debit_subquery, recv_subquery).alias("AA")
# Final query
final_query = select(
combined_subquery.c.payment_plan_time_periods,
func.sum(combined_subquery.c.debit).label("debit"),
func.sum(combined_subquery.c.recv).label("recv"),
combined_subquery.c.ls.label("Last Seen"),
).group_by(
combined_subquery.c.payment_plan_time_periods, combined_subquery.c.ls
)
# Execute the query
book_payments = BuildDecisionBookPayments.session.execute(
final_query
).fetchall()
print("book_payments", book_payments)
return AlchemyJsonResponse(
completed=True,
message="Building Parts Records are listed",
result=[book_payments, book_payments_month],
cls_object=BuildParts,
response_model=BuildPartsListResponse,
filter_attributes=list_options,
)

View File

@@ -0,0 +1,372 @@
from typing import Union
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
from databases import (
BuildDecisionBookProjects,
BuildDecisionBookProjectPerson,
BuildDecisionBookPayments,
OccupantTypes,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.validations_request import (
InsertBuildDecisionBookProjects,
UpdateBuildDecisionBookProjects,
ApprovalsBuildDecisionBookProjects,
ListOptions,
)
from api_validations.core_response import AlchemyJsonResponse
from databases import Build, BuildLivingSpace, BuildParts, ApiEnumDropdown
from databases.sql_models.building.decision_book import (
BuildDecisionBookProjectItems,
BuildDecisionBookItems,
BuildDecisionBook,
)
class ProjectDecisionBookListEventMethods(MethodToEvent):
event_type = "LIST"
__event_keys__ = {
"96459b36-37f2-4d5b-8370-c459058d5bce": "project_decision_book_list",
}
__event_validation__ = {"96459b36-37f2-4d5b-8370-c459058d5bce": None}
@classmethod
def project_decision_book_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
build_decision_book = BuildDecisionBook.filter_one(
BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
).data
if not build_decision_book:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message="Build decision book not found",
data={},
)
BuildDecisionBookProjects.filter_attr = list_options
decision_book_projects = BuildDecisionBookProjects.filter_all(
BuildDecisionBookProjects.build_decision_book_id
== build_decision_book.id,
)
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision book created successfully",
result=decision_book_projects,
)
class ProjectDecisionBookCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"b8e44bb2-f157-4dd5-8a24-0e02db4877c9": "project_decision_book_create",
}
__event_validation__ = {
"b8e44bb2-f157-4dd5-8a24-0e02db4877c9": InsertBuildDecisionBookProjects
}
@classmethod
def project_decision_book_create(
cls,
data: InsertBuildDecisionBookProjects,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == token_dict.selected_occupant.living_space_id,
).data
if not living_space:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message="Living space not found",
data={},
)
occupant_type = OccupantTypes.filter_by_one(
occupant_category_type="PRJ",
occupant_code="PRJ-LDR",
id=living_space.occupant_type,
).data
if not occupant_type:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message=f"{token_dict.selected_occupant.occupant_type_uu_id} occupant type is not allowed, only PRJ-LDR occupant type is allowed",
data={},
)
decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
BuildDecisionBookProjectPerson.living_space_id
== token_dict.selected_occupant.living_space_id,
)
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision book created successfully",
result=decision_book_project_person,
)
class ProjectDecisionBookUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"bfe3ef13-030f-495f-b692-94bcb746d700": "project_decision_book_update",
}
__event_validation__ = {
"bfe3ef13-030f-495f-b692-94bcb746d700": UpdateBuildDecisionBookProjects
}
@classmethod
def project_decision_book_update(
cls,
data: UpdateBuildDecisionBookProjects,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == token_dict.selected_occupant.living_space_id,
).data
if not living_space:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message="Living space not found",
data={},
)
occupant_type = OccupantTypes.filter_by_one(
occupant_category_type="PRJ",
occupant_code="PRJ-LDR",
id=living_space.occupant_type,
).data
if not occupant_type:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message=f"{token_dict.selected_occupant.occupant_type_uu_id} occupant type is not allowed, only PRJ-LDR occupant type is allowed",
data={},
)
decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
BuildDecisionBookProjectPerson.build_decision_book_project_uu_id
== data.build_decision_book_project_uu_id,
BuildDecisionBookProjectPerson.living_space_id
== token_dict.selected_occupant.living_space_id,
).data
if not decision_book_project_person:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message="This project is not allowed for this occupant",
data={},
)
decision_book_project = BuildDecisionBookProjects.filter_one(
BuildDecisionBookProjects.id
== decision_book_project_person.build_decision_book_project_id,
)
if decision_book_project.is_completed:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Project decision book is closed. No modification is allowed",
data={},
)
data_dict = data.excluded_dump()
decision_book_project.update(**data_dict)
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision book created successfully",
result=decision_book_project_person,
)
class ProjectDecisionBookApprovalEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"a83a83fe-8446-4c60-9ae5-d1c06adbf626": "project_decision_book_approval",
}
__event_validation__ = {
"a83a83fe-8446-4c60-9ae5-d1c06adbf626": ApprovalsBuildDecisionBookProjects
}
@classmethod
def project_decision_book_approval(
cls,
data: ApprovalsBuildDecisionBookProjects,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
BuildDecisionBookPayments.client_arrow = client_arrow
BuildDecisionBookPayments.client_arrow.timezone = token_dict.timezone or "GMT+3"
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == token_dict.selected_occupant.living_space_id,
).data
if not living_space:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message="Living space not found",
data={},
)
occupant_type = OccupantTypes.filter_by_one(
system=True,
occupant_category_type="PRJ",
occupant_code="PRJ-LDR",
id=living_space.occupant_type,
).data
if not occupant_type:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message=f"{token_dict.selected_occupant.occupant_type_uu_id} occupant type is not allowed, only PRJ-LDR occupant type is allowed",
data={},
)
decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
BuildDecisionBookProjectPerson.build_decision_book_project_uu_id
== data.build_decision_book_project_uu_id,
BuildDecisionBookProjectPerson.living_space_id
== token_dict.selected_occupant.living_space_id,
).data
if not decision_book_project_person:
raise BuildDecisionBookProjectPerson.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message="This project is not allowed for this occupant",
data={},
)
decision_book_project = BuildDecisionBookProjects.filter_one(
BuildDecisionBookProjects.id
== decision_book_project_person.build_decision_book_project_id,
).data
if decision_book_project.is_completed:
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Project decision book is closed. No modification is allowed",
data={},
)
data_dict = data.excluded_dump()
data_dict["is_completed"] = True
build_parts_list = BuildParts.filter_all(
BuildParts.human_livable == True,
BuildParts.build_id == token_dict.selected_occupant.build_id,
).data
decision_book_project_item = BuildDecisionBookItems.filter_one(
BuildDecisionBookItems.id
== decision_book_project.build_decision_book_item_id
).data
book_payment_dict = dict(
build_decision_book_item_id=decision_book_project_item.id,
build_decision_book_item_uu_id=str(decision_book_project_item.uu_id),
currency=decision_book_project.currency,
)
payment_type = ApiEnumDropdown.get_debit_search(search_debit="DT-D")
for final_price in data.final_price_list or []:
for build_part_single in build_parts_list:
local_date = BuildDecisionBookPayments.client_arrow.get(
str(final_price["date"])
)
local_date = system_arrow.get(local_date)
payment_amount = abs(float(final_price["price"])) * -1
created_book_payment = BuildDecisionBookPayments.find_or_create(
build_parts_id=build_part_single.id,
build_parts_uu_id=str(build_part_single.uu_id),
payment_amount=payment_amount,
payment_types_id=payment_type.id,
payment_types_uu_id=str(payment_type.uu_id),
process_date=str(local_date),
process_date_m=int(local_date.month),
process_date_y=int(local_date.year),
payment_plan_time_periods=str(
decision_book_project.project_type
),
period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}",
decision_book_project_id=decision_book_project.id,
decision_book_project_uu_id=str(decision_book_project.uu_id),
**book_payment_dict,
)
created_book_payment.save_and_confirm()
updated_decision_book_project = decision_book_project.update(**data_dict)
updated_decision_book_project.save_and_confirm()
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision book created successfully",
result=updated_decision_book_project,
)
class ProjectDecisionBookPatchEventMethods(MethodToEvent):
event_type = "PATCH"
__event_keys__ = {
"444d67a0-b3a8-4ca2-9d8d-f1acc75011e0": "project_decision_book_patch",
}
__event_validation__ = {"444d67a0-b3a8-4ca2-9d8d-f1acc75011e0": None}
@classmethod
def project_decision_book_patch(
cls,
data,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return
ProjectDecisionBookListEventMethod = ProjectDecisionBookListEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/list")
)
ProjectDecisionBookCreateEventMethod = ProjectDecisionBookCreateEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/create")
)
ProjectDecisionBookUpdateEventMethod = ProjectDecisionBookUpdateEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/update")
)
ProjectDecisionBookApprovalEventMethod = ProjectDecisionBookApprovalEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/approval")
)
ProjectDecisionBookPatchEventMethod = ProjectDecisionBookPatchEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/patch")
)

View File

@@ -0,0 +1,156 @@
from typing import Union
from databases import (
BuildDecisionBookProjectItems,
BuildDecisionBookProjectPerson,
)
from api_validations.validations_request import (
InsertBuildDecisionBookProjectItems,
UpdateBuildDecisionBookProjectItems,
ListOptions,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse
from databases.sql_models.building.decision_book import BuildDecisionBookProjects
class BuildDecisionBookProjectItemsListEventMethods(MethodToEvent):
event_type = "SELECT"
__event_keys__ = {
"ce3630e4-2bf9-4433-bdab-1ee72117e54b": "build_decision_book_project_items_list",
}
__event_validation__ = {"ce3630e4-2bf9-4433-bdab-1ee72117e54b": None}
@staticmethod
def build_decision_book_project_items_list(
requester: Union[EmployeeTokenObject, OccupantTokenObject],
list_options: ListOptions,
):
response = BuildDecisionBookProjectItems.list_items(
requester=requester,
list_options=list_options,
)
return AlchemyJsonResponse(
message="Build Decision Book Project Items List",
result=response,
)
class BuildDecisionBookProjectItemsCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"b27e4fd0-6e3e-441b-9b33-806ac7082444": "build_decision_book_project_items_create",
}
__event_validation__ = {
"b27e4fd0-6e3e-441b-9b33-806ac7082444": InsertBuildDecisionBookProjectItems,
}
@staticmethod
def build_decision_book_project_items_create(
data: InsertBuildDecisionBookProjectItems,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjectItems.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"No permission to create decision book project items",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
book_project = BuildDecisionBookProjects.filter_one(
BuildDecisionBookProjects.uu_id
== data.build_decision_book_project_uu_id,
BuildDecisionBookProjects.project_response_living_space_id
== token_dict.selected_occupant.living_space_id,
).data
if not book_project:
raise BuildDecisionBookProjectItems.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="NOT_FOUND",
message=f"This user can not create project item for this project uu_id : {data.build_decision_book_project_uu_id}",
data={},
)
data_dict = data.excluded_dump()
data_dict["build_decision_book_project_id"] = book_project.id
created_project_item = BuildDecisionBookProjectItems.find_or_create(
**data_dict
)
created_project_item.save_and_confirm()
return AlchemyJsonResponse(
message="Build Decision Book Project Items Create",
result=created_project_item.get_dict(),
)
class BuildDecisionBookProjectItemsUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"b2b7cdce-9a0c-4722-90ff-8bef36b4ec6b": "build_decision_book_project_items_update",
}
__event_validation__ = {
"b2b7cdce-9a0c-4722-90ff-8bef36b4ec6b": UpdateBuildDecisionBookProjectItems
}
@staticmethod
def build_decision_book_project_items_update(
requester: Union[EmployeeTokenObject, OccupantTokenObject],
decision_book_project_items: UpdateBuildDecisionBookProjectItems,
):
raise BuildDecisionBookProjectItems.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="UNAUTHORIZED",
message=f"No permission to update decision book project items",
data={},
)
class BuildDecisionBookProjectItemsPatchEventMethods(MethodToEvent):
event_type = "SELECT"
__event_keys__ = {
"e59d50df-dd22-4823-aeae-b9490332885c": "build_decision_book_project_items_patch",
}
__event_validation__ = {"e59d50df-dd22-4823-aeae-b9490332885c": None}
@staticmethod
def build_decision_book_project_items_patch(
requester: Union[EmployeeTokenObject, OccupantTokenObject],
decision_book_project_items: UpdateBuildDecisionBookProjectItems,
):
response = BuildDecisionBookProjectItems.delete_item(
requester=requester,
decision_book_project_items=decision_book_project_items,
)
return AlchemyJsonResponse(
message="Build Decision Book Project Items Patch",
result=response,
)
BuildDecisionBookProjectItemsListEventMethod = (
BuildDecisionBookProjectItemsListEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/items/list")
)
)
BuildDecisionBookProjectItemsCreateEventMethod = (
BuildDecisionBookProjectItemsCreateEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/items/create")
)
)
BuildDecisionBookProjectItemsUpdateEventMethod = (
BuildDecisionBookProjectItemsUpdateEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/items/update")
)
)
BuildDecisionBookProjectItemsPatchEventMethod = (
BuildDecisionBookProjectItemsPatchEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/items/patch")
)
)

View File

@@ -0,0 +1,189 @@
from typing import Union
from databases import (
BuildDecisionBookProjects,
BuildDecisionBookProjectPerson,
)
from api_validations.validations_request import (
InsertBuildDecisionBookProjectPerson,
UpdateBuildDecisionBookProjectPerson,
ListOptions,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse
class ProjectDecisionBookPersonListEventMethods(MethodToEvent):
event_type = "LIST"
__event_keys__ = {
"7101b5ca-8bef-40f9-8b4d-646d9994e18f": "project_decision_book_person_list",
}
__event_validation__ = {"7101b5ca-8bef-40f9-8b4d-646d9994e18f": None}
@classmethod
def project_decision_book_person_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
project_person = BuildDecisionBookProjectPerson.filter_all(
BuildDecisionBookProjects.living_space_id
== token_dict.selected_occupant.living_space_id,
)
decision_book_ids = [
_.build_decision_book_project_id for _ in project_person.data
]
decision_book_projects = BuildDecisionBookProjects.filter_all(
BuildDecisionBookProjects.build_decision_book_project_id.in_(
decision_book_ids
),
)
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision person book listed successfully",
result=decision_book_projects,
)
class ProjectDecisionBookPersonCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"9c88e314-84e8-435e-8c1e-6a5aae80b2e6": "project_decision_book_person_create",
}
__event_validation__ = {
"9c88e314-84e8-435e-8c1e-6a5aae80b2e6": InsertBuildDecisionBookProjectPerson
}
@classmethod
def project_decision_book_create(
cls,
data: InsertBuildDecisionBookProjectPerson,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
decision_book = BuildDecisionBookProjects.filter_one(
BuildDecisionBookProjects.build_decision_book_uu_id
== data.get("build_decision_book_uu_id"),
BuildDecisionBookProjects.project_response_living_space_id
== token_dict.selected_occupant.living_space_id,
)
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision book created successfully",
result=decision_book,
)
class ProjectDecisionBookPersonUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"7fbd18a0-c099-4494-ada1-bb23e39bb141": "project_decision_book_update_person",
}
__event_validation__ = {
"7fbd18a0-c099-4494-ada1-bb23e39bb141": UpdateBuildDecisionBookProjectPerson
}
@classmethod
def project_decision_book_update(
cls,
data: UpdateBuildDecisionBookProjectPerson,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
BuildDecisionBookProjects.build_decision_book_project_uu_id
== data.get("build_decision_book_uu_id"),
BuildDecisionBookProjects.living_space_id
== token_dict.selected_occupant.living_space_id,
)
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision book created successfully",
result=decision_book_project_person,
)
class ProjectDecisionBookPersonPatchEventMethods(MethodToEvent):
event_type = "PATCH"
__event_keys__ = {
"a122e84a-5556-4bf7-b680-1f47c438d4f7": "project_decision_book_person_patch",
}
__event_validation__ = {"a122e84a-5556-4bf7-b680-1f47c438d4f7": None}
@classmethod
def project_decision_book_patch(
cls,
data,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if isinstance(token_dict, EmployeeTokenObject):
raise BuildDecisionBookProjects.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
error_case="NOT_ALLOWED",
message="Employee cannot create project project decision book",
data={},
)
elif isinstance(token_dict, OccupantTokenObject):
decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
BuildDecisionBookProjects.build_decision_book_project_uu_id
== data.get("build_decision_book_uu_id"),
BuildDecisionBookProjects.living_space_id
== token_dict.selected_occupant.living_space_id,
)
return AlchemyJsonResponse(
status_code="HTTP_200_OK",
message="Project decision book created successfully",
result=decision_book_project_person,
)
ProjectDecisionBookPersonListEventMethod = ProjectDecisionBookPersonListEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/people/list")
)
ProjectDecisionBookPersonCreateEventMethod = (
ProjectDecisionBookPersonCreateEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/people/create")
)
)
ProjectDecisionBookPersonUpdateEventMethod = (
ProjectDecisionBookPersonUpdateEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/people/update")
)
)
ProjectDecisionBookPersonPatchEventMethod = ProjectDecisionBookPersonPatchEventMethods(
action=ActionsSchema(endpoint="/build/decision_book/project/people/patch")
)

View File

@@ -1,6 +0,0 @@
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
class ProjectDecisionBookProjectDecisionBookEvents(MethodToEvent): ...

View File

@@ -1,6 +0,0 @@
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
class ProjectDecisionBookProjectDecisionBookPersonEvents(MethodToEvent): ...

View File

@@ -4,42 +4,91 @@ from databases import (
Modules,
BuildLivingSpace,
)
from api_validations.validations_request import RegisterModules2Occupant, RegisterModules2Employee
from api_validations.validations_request import (
RegisterModules2Occupant,
RegisterModules2Employee,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_events.events.events.events_bind_services import ServiceBindOccupantEventMethods
from api_events.events.events.events_bind_services import (
ServiceBindOccupantEventMethods,
)
from api_library.date_time_actions.date_functions import system_arrow
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from databases.sql_models.company.employee import Employees
from databases.sql_models.event.event import Event2Occupant, Event2Employee
class ModulesBindOccupantEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"": "modules_bind_occupant",
"91003e90-8ead-4705-98a3-f8731c6ecb38": "modules_bind_occupant",
}
__event_validation__ = {
"91003e90-8ead-4705-98a3-f8731c6ecb38": None,
}
@classmethod
def modules_bind_occupant_system(
cls, build_living_space_id: int, modules_id: int, expires_at: str = None
def bind_default_module_for_first_init_occupant(
cls, build_living_space_id: int, expires_at: str = None
):
living_space = BuildLivingSpace.filter_one(Modules.id==build_living_space_id).data
modules = Modules.filter_one(Modules.id==modules_id).data
living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == build_living_space_id, system=True
).data
modules = Modules.filter_all(Modules.is_default_module == True).data
print("living_space", living_space, "modules", modules)
if not living_space or not modules:
print(f"Giving living Space or Modules: Default not found")
return
service_build_dict = dict(build_living_space_id=living_space.id)
service_build_dict["expires_at"] = str(system_arrow.get(living_space.expiry_ends))
if not expires_at:
if expires_at:
service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
else:
expiry_ends = str(system_arrow.get(living_space.expiry_ends))
service_build_dict["expires_at"] = expiry_ends
for service in modules.retrieve_services():
ServiceBindOccupantEventMethods.bind_services_occupant_system(
**service_build_dict,
service_id=service.id,
)
BuildLivingSpace.save()
for module in modules:
for service in module.retrieve_services():
event_occupant = Event2Occupant.find_or_create(
event_service_id=service.id,
event_service_uu_id=str(service.uu_id),
build_living_space_id=living_space.id,
build_living_space_uu_id=str(living_space.uu_id),
)
event_occupant.save_and_confirm()
return True
# @classmethod
# def modules_bind_occupant_system(
# cls, build_living_space_id: int, modules_id: int, expires_at: str = None
# ):
#
# living_space = BuildLivingSpace.filter_one(
# BuildLivingSpace.id == build_living_space_id,
# ).data
# modules = Modules.filter_one(Modules.id == modules_id).data
#
# if not living_space or not modules:
# print(f"Giving living Space or Modules: {modules.module_name} not found")
# return
# service_build_dict = dict(build_living_space_id=living_space.id)
# if expires_at:
# service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
# else:
# service_build_dict["expires_at"] = str(
# system_arrow.get(living_space.expiry_ends)
# )
#
# for service in modules.retrieve_services():
# ServiceBindOccupantEventMethods.bind_services_occupant_system(
# **service_build_dict,
# service_id=service.id,
# )
# BuildLivingSpace.save()
# return True
@classmethod
def modules_bind_occupant(
cls,
@@ -54,8 +103,42 @@ class ModulesBindEmployeeEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"": "modules_bind_employee",
"d4ed23db-62e9-4015-b7c0-698a7917aa0c": "modules_bind_employee",
}
__event_validation__ = {
"d4ed23db-62e9-4015-b7c0-698a7917aa0c": None,
}
@classmethod
def bind_default_module_for_first_init_occupant(
cls, employee_id: int, expires_at: str = None
):
employee = Employees.filter_one(
Employees.id == employee_id,
).data
modules = Modules.filter_all(Modules.is_default_module == True).data
print("living_space", employee, "modules", modules)
if not employee or not modules:
print(f"Giving living Space or Modules: Default not found")
return
service_build_dict = dict(build_living_space_id=employee.id)
if expires_at:
service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
else:
expiry_ends = str(system_arrow.get(employee.expiry_ends))
service_build_dict["expires_at"] = expiry_ends
for module in modules:
for service in module.retrieve_services():
event_employee = Event2Employee.find_or_create(
event_service_id=service.id,
event_service_uu_id=str(service.uu_id),
employee_id=employee.id,
employee_uu_id=str(employee.uu_id),
)
event_employee.save_and_confirm()
return True
@classmethod
def modules_bind_employee(

View File

@@ -4,21 +4,24 @@ from fastapi import status
from fastapi.responses import JSONResponse
from fastapi.exceptions import HTTPException
from api_library.date_time_actions.date_functions import system_arrow
from databases import (
Modules,
Employees,
BuildParts,
BuildLivingSpace,
Service2Events,
Services,
OccupantTypes,
Event2Employee,
Event2Occupant,
)
from api_validations.validations_request import RegisterServices2Occupant, RegisterServices2Employee
from api_validations.validations_request import (
RegisterServices2Occupant,
RegisterServices2Employee,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class ServiceBindOccupantEventMethods(MethodToEvent):
@@ -26,43 +29,40 @@ class ServiceBindOccupantEventMethods(MethodToEvent):
__event_keys__ = {
"0d2bc5c9-d4b1-4951-8305-69da4a687fdc": "bind_services_occupant",
}
__event_validation__ = {
"0d2bc5c9-d4b1-4951-8305-69da4a687fdc": RegisterServices2Occupant
}
@classmethod
def bind_services_occupant_system(
cls, build_living_space_id: int, service_id: int, expires_at: str = None
):
from sqlalchemy.dialects.postgresql import insert
living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == build_living_space_id,
).data
service = Services.filter_one(Services.id == service_id).data
if not service:
print("Service is not valid. Service can not be binded")
return
living_space = BuildLivingSpace.filter_one(BuildLivingSpace.id==build_living_space_id)
service = Services.filter_one(Services.id==service_id)
add_events_list = Service2Events.filter_all(Service2Events.service_id == service.id).data
if not add_events_list:
raise Exception(
"Service has no events registered. Please contact with your manager"
)
if not living_space:
print("Living Space is not valid. Service is not binded")
return
event_ids_list = [
{
"build_living_space_id": living_space.id,
"build_living_space_uu_id": str(living_space.uu_id),
"event_id": service_event.event_id,
"event_uu_id": str(service_event.event_uu_id),
"is_confirmed": True,
"expiry_ends": str(expires_at) if expires_at else "2099-12-31 03:00:00",
}
for service_event in add_events_list
]
if expires_at:
expires_at = str(system_arrow.get(expires_at))
else:
expires_at = str(system_arrow.get(living_space.expiry_ends))
session_execute = Services.session.execute(
insert(Event2Occupant)
.values(event_ids_list)
.on_conflict_do_nothing(
index_elements=["build_living_space_id", "event_id"],
)
occupants_event = Event2Occupant.find_or_create(
event_service_id=service.id,
event_service_uu_id=str(service.uu_id),
build_living_space_id=living_space.id,
build_living_space_uu_id=str(living_space.uu_id),
expiry_ends=expires_at,
)
count_row = session_execute.rowcount
print(f"{count_row} events are added to occupant {str(living_space.uu_id)}")
Services.save()
occupants_event.save_and_confirm()
print(f"{service.service_name} is added to occupant {str(living_space.uu_id)}")
@classmethod
def bind_services_occupant(
@@ -78,11 +78,10 @@ class ServiceBindOccupantEventMethods(MethodToEvent):
detail="Employee is not authorized to add service to any occupant",
)
occupants_build_part = BuildParts.find_one(
uu_id=data.build_part_uu_id,
build_id=token_dict.selected_occupant.build_id,
)
print("occupants_build_part", occupants_build_part)
occupants_build_part = BuildParts.filter_one(
BuildParts.uu_id == data.build_part_uu_id,
BuildParts.build_id == token_dict.selected_occupant.build_id,
).data
if not occupants_build_part:
return JSONResponse(
content={
@@ -93,7 +92,9 @@ class ServiceBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
occupant_occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
occupant_occupant_type = OccupantTypes.filter_by_one(
uu_id=data.occupant_uu_id
).data
if not occupant_occupant_type:
return JSONResponse(
content={
@@ -104,7 +105,7 @@ class ServiceBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
service = Services.find_one(uu_id=data.service_uu_id)
service = Services.filter_one(Services.uu_id == data.service_uu_id).data
if not service:
return JSONResponse(
content={
@@ -115,26 +116,20 @@ class ServiceBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
default_module = Modules.find_one(module_code="USR-PUB")
add_default_service = Services.find_one(module_id=default_module.id)
service_events = Service2Events.filter_all(
Service2Events.service_id == service.id,
)
default_service_events = Service2Events.filter_all(
Service2Events.service_id == add_default_service.id,
)
add_events_list = service_events.data + default_service_events.data
if not add_events_list:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Service has no events registered. Please contact with your manager",
)
# service_events = Service2Events.filter_all(
# Service2Events.service_id == service.id,
# ).data
# if not service_events:
# raise HTTPException(
# status_code=status.HTTP_404_NOT_FOUND,
# detail="Service has no events registered. Please contact with your manager",
# )
living_space = BuildLivingSpace.find_one(
build_parts_id=occupants_build_part.id,
occupant_types_id=occupant_occupant_type.id,
person_id=token_dict.person_id,
)
living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.build_parts_id == occupants_build_part.id,
BuildLivingSpace.occupant_types_id == occupant_occupant_type.id,
BuildLivingSpace.person_id == token_dict.person_id,
).data
if not living_space:
return JSONResponse(
content={
@@ -145,27 +140,27 @@ class ServiceBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
event_ids_list = [
{
"build_living_space_id": living_space.id,
"build_living_space_uu_id": str(living_space.uu_id),
"event_id": service_event.event_id,
"event_uu_id": str(service_event.event_uu_id),
"is_confirmed": True,
}
for service_event in add_events_list
]
session_execute = Services.session.execute(
insert(Event2Occupant)
.values(event_ids_list)
.on_conflict_do_nothing(
index_elements=["employee_id", "event_id"],
)
)
count_row = session_execute.rowcount
print(f"{count_row} events are added to employee {str(living_space.uu_id)}")
Services.save()
# event_ids_list = [
# {
# "build_living_space_id": living_space.id,
# "build_living_space_uu_id": str(living_space.uu_id),
# "event_id": service_event.event_id,
# "event_uu_id": str(service_event.event_uu_id),
# "is_confirmed": True,
# }
# for service_event in service_events
# ]
#
# session_execute = Services.session.execute(
# insert(Event2Occupant)
# .values(event_ids_list)
# .on_conflict_do_nothing(
# index_elements=["employee_id", "event_id"],
# )
# )
# count_row = session_execute.rowcount
# print(f"{count_row} events are added to employee {str(living_space.uu_id)}")
# Services.save()
class ServiceBindEmployeeEventMethods(MethodToEvent):
@@ -174,52 +169,54 @@ class ServiceBindEmployeeEventMethods(MethodToEvent):
__event_keys__ = {
"50f84023-d8ec-4257-bfce-08ddf077c101": "bind_services_employee_super_user",
}
__event_validation__ = {"50f84023-d8ec-4257-bfce-08ddf077c101": None}
@classmethod
def bind_services_employee(cls, service_id: int, employee_id: int):
from sqlalchemy.dialects.postgresql import insert
employee = Employees.filter_by_one(
id=employee_id, **Employees.valid_record_dict
).data
service = Services.filter_by_one(
id=service_id, **Services.valid_record_dict
).data
if not service:
print("Service is not valid. Service can not be binded")
return
employee = Employees.find_or_abort(
id=employee_id,
)
service = Services.find_or_abort(
id=service_id,
)
default_module = Modules.find_one(module_code="USR-PUB")
add_default_service = Services.find_one(module_id=default_module.id)
service_events = Service2Events.filter_all(
Service2Events.service_id == service.id,
)
default_service_events = Service2Events.filter_all(
Service2Events.service_id == add_default_service.id,
)
add_events_list = service_events.data + default_service_events.data
if not add_events_list:
raise Exception(
"Service has no events registered. Please contact with your manager"
)
if not employee:
print("Employee is not valid. Service is not binded")
return
event_ids_list = [
{
"employee_id": employee_id,
"employee_uu_id": str(employee.uu_id),
"event_id": service_event.event_id,
"event_uu_id": str(service_event.event_uu_id),
"is_confirmed": True,
}
for service_event in add_events_list
]
# service_events = Service2Events.filter_all(
# Service2Events.service_id == service.id,
# ).data
# if not service_events:
# raise Exception(
# "Service has no events registered. Please contact with your manager"
# )
session_execute = Services.session.execute(
insert(Event2Employee)
.values(event_ids_list)
.on_conflict_do_nothing(
index_elements=["employee_id", "event_id"],
)
)
count_row = session_execute.rowcount
print(f"{count_row} events are added to employee {employee.uu_id}")
Services.save()
# event_ids_list = [
# {
# "employee_id": employee_id,
# "employee_uu_id": str(employee.uu_id),
# "event_id": service_event.event_id,
# "event_uu_id": str(service_event.event_uu_id),
# "is_confirmed": True,
# }
# for service_event in service_events
# ]
#
# session_execute = Services.session.execute(
# insert(Event2Employee)
# .values(event_ids_list)
# .on_conflict_do_nothing(
# index_elements=["employee_id", "event_id"],
# )
# )
# count_row = session_execute.rowcount
# print(f"{count_row} events are added to employee {employee.uu_id}")
# for service_event in service_events:
# service_event.save_and_confirm()
@classmethod
def bind_services_employee_super_user(
@@ -227,15 +224,15 @@ class ServiceBindEmployeeEventMethods(MethodToEvent):
data: RegisterServices2Employee,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
from sqlalchemy.dialects.postgresql import insert
if isinstance(token_dict, OccupantTokenObject):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Occupant is not authorized to add service to any employee",
)
employee = Employees.find_one(uu_id=data.employee_uu_id)
employee = Employees.filter_by_one(
uu_id=data.employee_uu_id, **Employees.valid_record_dict
).data
if not employee:
return JSONResponse(
content={
@@ -246,7 +243,9 @@ class ServiceBindEmployeeEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
service = Services.find_one(uu_id=data.service_uu_id)
service = Services.filter_by_one(
uu_id=data.service_uu_id, **Services.valid_record_dict
).data
if not service:
return JSONResponse(
content={
@@ -257,60 +256,61 @@ class ServiceBindEmployeeEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND,
)
service_events = Service2Events.filter_all(
Service2Events.service_id == service.id,
event_of_employee = Event2Employee.find_or_create(
event_service_id=service.id,
event_service_uu_id=str(service.uu_id),
employee_id=employee.id,
employee_uu_id=str(employee.uu_id),
)
event_of_employee.save_and_confirm()
print(f"{service.service_name} is added to employee {str(employee.uu_id)}")
default_module = Modules.find_one(module_code="USR-PUB")
add_default_service = Services.find_one(module_id=default_module.id)
default_service_events = Service2Events.filter_all(
Service2Events.service_id == add_default_service.id,
)
add_events_list = service_events.data + default_service_events.data
if not add_events_list:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Service has no events registered. Please contact with your manager",
)
event_ids_list = [
{
"employee_id": employee.id,
"employee_uu_id": employee.uu_id,
"event_id": service_event.event_id,
"event_uu_id": service_event.event_uu_id,
"is_confirmed": True,
}
for service_event in add_events_list
]
session_execute = Services.session.execute(
insert(Event2Employee)
.values(event_ids_list)
.on_conflict_do_nothing(
index_elements=["employee_id", "event_id"],
)
)
count_row = session_execute.rowcount
if not count_row:
Services.save()
return JSONResponse(
content={
"completed": False,
"message": "No events are added to employee",
"data": {},
},
status_code=status.HTTP_200_OK,
)
return JSONResponse(
content={
"completed": True,
"message": f"{count_row} events are added to employee",
"data": {},
},
status_code=status.HTTP_200_OK,
)
# service_events = Service2Events.filter_all(
# Service2Events.service_id == service.id,
# ).data
# if not service_events:
# raise HTTPException(
# status_code=status.HTTP_404_NOT_FOUND,
# detail="Service has no events registered. Please contact with your manager",
# )
#
# event_ids_list = [
# {
# "employee_id": employee.id,
# "employee_uu_id": employee.uu_id,
# "event_id": service_event.event_id,
# "event_uu_id": service_event.event_uu_id,
# "is_confirmed": True,
# }
# for service_event in service_events
# ]
#
# session_execute = Services.session.execute(
# insert(Event2Employee)
# .values(event_ids_list)
# .on_conflict_do_nothing(
# index_elements=["employee_id", "event_id"],
# )
# )
# count_row = session_execute.rowcount
# if not count_row:
# Services.save()
# return JSONResponse(
# content={
# "completed": False,
# "message": "No events are added to employee",
# "data": {},
# },
# status_code=status.HTTP_200_OK,
# )
# return JSONResponse(
# content={
# "completed": True,
# "message": f"{count_row} events are added to employee",
# "data": {},
# },
# status_code=status.HTTP_200_OK,
# )
ServiceBindOccupantEventMethod = ServiceBindOccupantEventMethods(

View File

@@ -2,6 +2,7 @@ from typing import Union
from fastapi.exceptions import HTTPException
from api_events.events.events.events_services import ServicesEvents
from databases import (
Events,
Employees,
@@ -14,13 +15,12 @@ from databases import (
from api_validations.validations_request import (
RegisterEvents2Employee,
RegisterEvents2Occupant,
CreateEvents,
ListOptions,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class EventsListEventMethods(MethodToEvent):
@@ -29,100 +29,47 @@ class EventsListEventMethods(MethodToEvent):
__event_keys__ = {
"9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": "events_list",
}
__event_validation__ = {"9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": None}
@classmethod
def events_list(cls, list_options: ListOptions, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]):
records = Events.filter_active(
*Events.get_smart_query(list_options.query),
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
)
class EventsCreateEventMethods(MethodToEvent):
event_type = "CREATE"
__event_keys__ = {
"514a9f8f-e5e5-4e10-9d0b-2de8f461fc1b": "events_create",
}
@classmethod
def events_create(cls, data: CreateEvents, token_dict):
event = Events.find_or_create(
**token_dict.user_creds,
event_name=data.event_name,
event_description=data.event_description,
event_date=data.event_date,
event_location=data.event_location,
active=True,
deleted=False,
)
Events.save()
return {
"status": "success",
"message": "Event created successfully.",
"event": event.uu_id,
}
class EventsUpdateEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"f94e7b79-2369-4840-bf2b-244934ca3136": "events_update",
}
@classmethod
def events_update(cls, data: CreateEvents, token_dict):
event = Events.find_one(uu_id=data.uu_id)
if not event:
raise HTTPException(
status_code=404,
detail="No event found. Please contact your responsible company.",
def events_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
list_options.page = 1
list_options.size = 10000
Events.filter_attr = list_options
if isinstance(token_dict, OccupantTokenObject):
occupant_events = Event2Occupant.filter_all(
Event2Occupant.build_living_space_id
== token_dict.selected_occupant.living_space_id
).data
records = Events.filter_all(
Events.id.in_([event.event_id for event in occupant_events])
)
event.update(
**token_dict.user_creds,
event_name=data.event_name,
event_description=data.event_description,
event_date=data.event_date,
event_location=data.event_location,
)
Events.save()
return {
"status": "success",
"message": "Event updated successfully.",
"event": event.uu_id,
}
class EventsPatchEventMethods(MethodToEvent):
event_type = "PATCH"
__event_keys__ = {
"41944c63-22d3-4866-affd-34bcd49da58b": "events_patch",
}
@classmethod
def events_patch(cls, data: CreateEvents, token_dict):
event = Events.find_one(uu_id=data.uu_id)
if not event:
raise HTTPException(
status_code=404,
detail="No event found. Please contact your responsible company.",
return AlchemyJsonResponse(
completed=True,
message="Events are listed successfully",
result=records,
)
event.update(
**token_dict.user_creds,
event_name=data.event_name,
event_description=data.event_description,
event_date=data.event_date,
event_location=data.event_location,
elif isinstance(token_dict, EmployeeTokenObject):
employee_events = Event2Employee.filter_all(
Event2Employee.employee_id == token_dict.selected_company.employee_id
).data
records = Events.filter_all(
Events.id.in_([event.event_id for event in employee_events])
)
return AlchemyJsonResponse(
completed=True,
message="Events are listed successfully",
result=records,
)
return AlchemyJsonResponse(
completed=False,
message="Events are NOT listed successfully",
result=[],
)
return {
"status": "success",
"message": "Event patched successfully.",
"event": event.uu_id,
}
class EventsBindEventToOccupantMethods(MethodToEvent):
@@ -131,21 +78,31 @@ class EventsBindEventToOccupantMethods(MethodToEvent):
__event_keys__ = {
"d9aa58aa-37f7-4c27-861d-3105f76f5cdc": "bind_events_employee",
}
__event_validation__ = {
"d9aa58aa-37f7-4c27-861d-3105f76f5cdc": RegisterEvents2Employee
}
@classmethod
def bind_events_employee(cls, data: RegisterEvents2Employee, token_dict):
events = Events.filter_active(Events.uu_id.in_(data.event_id))
events = Events.filter_all(
Events.uu_id.in_(data.event_id),
).data
if not events:
raise HTTPException(
status_code=401,
detail="No event found. Please contact your super user.",
)
employee = Employees.find_one(employee_uu_id=data.employee_uu_id)
employee_is_not_valid = False
employee = Employees.filter_one(
Employees.employee_uu_id == data.employee_uu_id,
).data
if employee:
staff = Staff.find_one(id=employee.staff_id)
duties = Duties.find_one(id=staff.duties_id)
staff = Staff.filter_one(
Staff.id == employee.staff_id,
).data
duties = Duties.filter_one(
Duties.id == staff.duties_id,
).data
if duties.company_id not in token_dict.companies_id_list:
employee_is_not_valid = True
@@ -155,7 +112,7 @@ class EventsBindEventToOccupantMethods(MethodToEvent):
detail="This employee can not be reached by this user. Please contact your super user.",
)
for event in events.data:
for event in events:
employee = Event2Employee.find_or_create(
**token_dict.user_creds, employee_id=employee.id, event_id=event.id
)
@@ -173,24 +130,29 @@ class EventsBindEventToEmployeeMethods(MethodToEvent):
__event_keys__ = {
"8bb4f4fc-b474-427e-90b3-d8681f308bb5": "bind_events_occupant",
}
__event_validation__ = {
"8bb4f4fc-b474-427e-90b3-d8681f308bb5": RegisterEvents2Occupant
}
@classmethod
def bind_events_occupant(cls, data: RegisterEvents2Occupant, token_dict):
events = Events.filter_active(Events.uu_id.in_(data.event_id))
events = Events.filter_all(
Events.uu_id.in_(data.event_id),
).data
if not events:
raise HTTPException(
status_code=401,
detail="No event found. Please contact your super user.",
)
occupant = BuildLivingSpace.find_one(uu_id=data.build_living_space_uu_id)
occupant_is_not_valid = False
if occupant_is_not_valid:
occupant = BuildLivingSpace.filter_one(
BuildLivingSpace.uu_id == data.build_living_space_uu_id,
).data
if not occupant:
raise HTTPException(
status_code=401,
detail="This occupant can not be reached by this user. Please contact your super user.",
)
for event in events.data:
for event in events:
occupant = Event2Occupant.find_or_create(
**token_dict.user_creds,
build_living_space_id=occupant.id,
@@ -204,21 +166,105 @@ class EventsBindEventToEmployeeMethods(MethodToEvent):
}
EventsListEventMethod = EventsListEventMethods(
action=ActionsSchema(endpoint="/event/list")
)
EventsCreateEventMethod = EventsCreateEventMethods(
action=ActionsSchema(endpoint="/event/create")
)
EventsUpdateEventMethod = EventsUpdateEventMethods(
action=ActionsSchema(endpoint="/event/update")
)
EventsPatchEventMethod = EventsPatchEventMethods(
action=ActionsSchema(endpoint="/event/patch")
)
EventsBindEventToOccupantMethod = EventsBindEventToOccupantMethods(
action=ActionsSchema(endpoint="/bind/events/occupant")
)
EventsBindEventToEmployeeMethod = EventsBindEventToEmployeeMethods(
action=ActionsSchema(endpoint="/bind/events/employee")
)
EventsListEventMethod = EventsListEventMethods(
action=ActionsSchema(endpoint="/event/list")
)
# EventsCreateEventMethod = EventsCreateEventMethods(
# action=ActionsSchema(endpoint="/event/create")
# )
# EventsUpdateEventMethod = EventsUpdateEventMethods(
# action=ActionsSchema(endpoint="/event/update")
# )
# EventsPatchEventMethod = EventsPatchEventMethods(
# action=ActionsSchema(endpoint="/event/patch")
# )
#
# class EventsCreateEventMethods(MethodToEvent):
#
# event_type = "CREATE"
# __event_keys__ = {
# "514a9f8f-e5e5-4e10-9d0b-2de8f461fc1b": "events_create",
# }
#
# @classmethod
# def events_create(cls, data: CreateEvents, token_dict):
# event = Events.find_or_create(
# **token_dict.user_creds,
# event_name=data.event_name,
# event_description=data.event_description,
# event_date=data.event_date,
# event_location=data.event_location,
# active=True,
# deleted=False,
# )
# Events.save()
# return {
# "status": "success",
# "message": "Event created successfully.",
# "event": event.uu_id,
# }
# class EventsUpdateEventMethods(MethodToEvent):
#
# event_type = "UPDATE"
# __event_keys__ = {
# "f94e7b79-2369-4840-bf2b-244934ca3136": "events_update",
# }
#
# @classmethod
# def events_update(cls, data: CreateEvents, token_dict):
# event = Events.filter_by_one(uu_id=data.uu_id, **Events.valid_record_dict).data
# if not event:
# raise HTTPException(
# status_code=404,
# detail="No event found. Please contact your responsible company.",
# )
# event.update(
# **token_dict.user_creds,
# event_name=data.event_name,
# event_description=data.event_description,
# event_date=data.event_date,
# event_location=data.event_location,
# )
# Events.save()
# return {
# "status": "success",
# "message": "Event updated successfully.",
# "event": event.uu_id,
# }
#
#
# class EventsPatchEventMethods(MethodToEvent):
#
# event_type = "PATCH"
# __event_keys__ = {
# "41944c63-22d3-4866-affd-34bcd49da58b": "events_patch",
# }
#
# @classmethod
# def events_patch(cls, data: CreateEvents, token_dict):
# event = Events.filter_by_one(uu_id=data.uu_id, **Events.valid_record_dict).data
# if not event:
# raise HTTPException(
# status_code=404,
# detail="No event found. Please contact your responsible company.",
# )
# event.update(
# **token_dict.user_creds,
# event_name=data.event_name,
# event_description=data.event_description,
# event_date=data.event_date,
# event_location=data.event_location,
# )
# return {
# "status": "success",
# "message": "Event patched successfully.",
# "event": event.uu_id,
# }

View File

@@ -1,8 +1,12 @@
from api_validations.validations_request import DepartmentsPydantic, PatchRecord, ListOptions
from api_validations.validations_request import (
DepartmentsPydantic,
PatchRecord,
ListOptions,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class ModelEvents(MethodToEvent):

View File

@@ -2,7 +2,7 @@ from api_validations.validations_request import DepartmentsPydantic, PatchRecord
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class ModulesEvents(MethodToEvent):

View File

@@ -1,34 +1,62 @@
from api_validations.validations_request import DepartmentsPydantic, PatchRecord, ListOptions
from typing import Union
from api_validations.validations_request import (
DepartmentsPydantic,
PatchRecord,
ListOptions,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class ServicesEvents(MethodToEvent):
@classmethod
def services_list(cls, list_options: ListOptions):
def services_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return
@classmethod
def services_create(cls, data: DepartmentsPydantic, token_dict):
def services_create(
cls,
data: DepartmentsPydantic,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return
@classmethod
def services_update(cls, service_uu_id: str, data: DepartmentsPydantic, token_dict):
def services_update(
cls,
service_uu_id: str,
data: DepartmentsPydantic,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return
@classmethod
def services_patch(cls, service_uu_id: str, data: PatchRecord, token_dict):
def services_patch(
cls,
service_uu_id: str,
data: PatchRecord,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return
@classmethod
def bind_service_to_action(cls, data, token_dict):
def bind_service_to_action(
cls, data, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
return
@classmethod
def bind_module_to_service(cls, data, token_dict):
def bind_module_to_service(
cls, data, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
return
@classmethod

View File

@@ -3,17 +3,18 @@ from typing import Union
from fastapi import status
from fastapi.responses import JSONResponse
from api_validations.validations_response.people import PeopleListResponse
from databases import (
Build,
People,
Users,
Companies,
)
from api_validations.validations_request import InsertPerson, UpdateUsers
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
class PeopleListEventMethods(MethodToEvent):
@@ -22,32 +23,77 @@ class PeopleListEventMethods(MethodToEvent):
__event_keys__ = {
"0a05f03c-6ed8-4230-a4ff-6e7cf886909b": "super_users_people_list",
"b5612538-0445-4a4a-ab13-d2a06037f7a5": "sales_users_people_list",
"c81c2cec-d32c-4cf2-9727-d4493e11ee1f": "human_resources_users_people_list",
"d1b1b1b1-1b1b-1b1b-1b1b-1b1b1b1b1b1b": "people_list_only_occupant_tenant_or_owner",
"25cbbaf8-117a-470f-a844-2cfc70f71dde": "human_resources_users_people_list",
"cdf62f06-ec50-40de-b19e-adb3dd34bb95": "people_list_only_occupant_tenant_or_owner",
}
__event_validation__ = {
"0a05f03c-6ed8-4230-a4ff-6e7cf886909b": PeopleListResponse,
"b5612538-0445-4a4a-ab13-d2a06037f7a5": None,
"25cbbaf8-117a-470f-a844-2cfc70f71dde": None,
"cdf62f06-ec50-40de-b19e-adb3dd34bb95": None,
}
@classmethod
def super_users_people_list(cls, list_options, token_dict):
records = People.filter_active(
*People.get_smart_query(smart_query=list_options.query)
)
return return_json_response_from_alchemy(
response=records, pagination=list_options
def super_users_people_list(
cls, list_options, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
records = []
if isinstance(token_dict, EmployeeTokenObject):
People.pre_query = People.select_action(
duty_id_list=[
token_dict.selected_company.duty_id,
token_dict.selected_company.bulk_duties_id,
],
)
People.filter_attr = list_options
records = People.filter_all()
elif isinstance(token_dict, OccupantTokenObject):
related_users = Users.filter_all(
Users.related_company
== token_dict.selected_occupant.responsible_company_id,
).data
People.pre_query = People.filter_all(
People.id.in_([user.person_id for user in related_users]),
).query
People.filter_attr = list_options
records = People.filter_all()
return AlchemyJsonResponse(
completed=True,
message="People are listed successfully",
result=records,
cls_object=People,
filter_attributes=list_options,
response_model=PeopleListResponse,
)
@classmethod
def sales_users_people_list(cls, data, token_dict):
records = People.filter_active(*People.get_smart_query(smart_query=data.query))
# records = [model_class(**record) for record in records.data]
return return_json_response_from_alchemy(response=records, pagination=data)
def sales_users_people_list(
cls,
list_options,
token_dict: EmployeeTokenObject,
):
People.filter_attr = list_options
records = People.filter_all().data
return AlchemyJsonResponse(
completed=True,
message="People are listed successfully",
result=records,
)
@classmethod
def human_resources_users_people_list(cls, data, token_dict):
records = People.filter_active(*People.get_smart_query(smart_query=data.query))
# records = [model_class(**record) for record in records.data]
return return_json_response_from_alchemy(response=records, pagination=data)
def human_resources_users_people_list(
cls,
list_options,
token_dict: EmployeeTokenObject,
):
if isinstance(token_dict, EmployeeTokenObject):
People.filter_attr = list_options
records = People.filter_all().data
return AlchemyJsonResponse(
completed=True,
message="People are listed successfully",
result=records,
)
class PeopleCreateEventMethods(MethodToEvent):
@@ -56,13 +102,22 @@ class PeopleCreateEventMethods(MethodToEvent):
__event_keys__ = {
"2d1513f4-44ed-4fa3-84d1-dfbd0eadf9a1": "people_create",
}
__event_validation__ = {
"2d1513f4-44ed-4fa3-84d1-dfbd0eadf9a1": InsertPerson,
}
@classmethod
def people_create(
cls, data: InsertPerson, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: InsertPerson,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
created_user = People.create_action(data=data, token=token_dict)
People.save()
if isinstance(token_dict, EmployeeTokenObject):
created_user = People.create_action(data=data, token=token_dict)
People.save()
elif isinstance(token_dict, OccupantTokenObject):
created_user = People.create_action(data=data, token=token_dict)
People.save()
return JSONResponse(
content={
"completed": True,
@@ -79,28 +134,49 @@ class PeopleUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"e05cf22c-16c4-450b-86c8-417896a26afc": "people_update",
}
__event_validation__ = {"e05cf22c-16c4-450b-86c8-417896a26afc": UpdateUsers}
@classmethod
def people_update(
cls, data: UpdateUsers, user_uu_id: str, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: UpdateUsers,
user_uu_id: str,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
find_one_user = Users.find_one_or_abort(uu_id=user_uu_id)
access_authorized_company = Companies.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
filter_expr=[Companies.id == find_one_user.id],
)
if access_authorized_company.count:
data_dict = data.excluded_dump()
updated_user = find_one_user.update(**data_dict)
Users.save()
return JSONResponse(
content={
"completed": True,
"message": "Update User record",
"data": updated_user,
},
status_code=status.HTTP_200_OK,
data_dict = data.excluded_dump()
if isinstance(token_dict, EmployeeTokenObject):
find_one_user = Users.filter_one(
Users.uu_id == user_uu_id,
).data
access_authorized_company = Companies.select_action(
duty_id_list=[
token_dict.selected_company.duty_id,
token_dict.selected_company.bulk_duties_id,
],
)
if access_authorized_company.count:
updated_user = find_one_user.update(**data_dict)
Users.save()
return JSONResponse(
content={
"completed": True,
"message": "Update User record",
"data": updated_user,
},
status_code=status.HTTP_200_OK,
)
elif isinstance(token_dict, OccupantTokenObject):
find_one_user = People.filter_one(
People.uu_id == user_uu_id,
).data
access_authorized_company = Companies.select_action(
duty_id_list=[getattr(token_dict, "duty_id")],
filter_expr=[Companies.id == find_one_user.id],
)
if access_authorized_company.count:
data_dict = data.excluded_dump()
updated_user = find_one_user.update(**data_dict)
People.save()
return JSONResponse(
content={"completed": True, "message": "Update User record", "data": {}},
status_code=status.HTTP_200_OK,
@@ -113,6 +189,7 @@ class PeoplePatchEventMethods(MethodToEvent):
__event_keys__ = {
"3ae16d66-090b-4d27-b567-cce1b10a1c3b": "people_patch",
}
__event_validation__ = {"3ae16d66-090b-4d27-b567-cce1b10a1c3b": None}
@classmethod
def people_patch(cls):
@@ -125,6 +202,7 @@ class PeopleDeleteEventMethods(MethodToEvent):
__event_keys__ = {
"7f84c7a2-a120-4867-90d4-6767a41320db": "people_delete",
}
__event_validation__ = {"7f84c7a2-a120-4867-90d4-6767a41320db": None}
PeopleListEventMethod = PeopleListEventMethods(
@@ -139,6 +217,3 @@ PeopleUpdateEventMethod = PeopleUpdateEventMethods(
PeoplePatchEventMethod = PeoplePatchEventMethods(
action=ActionsSchema(endpoint="/people/patch")
)
PeopleDeleteEventMethod = PeopleDeleteEventMethods(
action=ActionsSchema(endpoint="/people/delete")
)

View File

@@ -3,19 +3,21 @@ import typing
from fastapi import status
from fastapi.responses import JSONResponse
from api_configs import ApiStatic
from databases import MongoQueryIdentity, Users, Companies, People
from databases.no_sql_models.validations import DomainViaUser
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import return_json_response_from_alchemy
from api_validations.core_response import AlchemyJsonResponse
from api_services.email.service import send_email
from api_services.templates.password_templates import change_your_password_template
from api_validations.validations_request import (
InsertUsers,
UpdateUsers,
PatchRecord,
ListOptions, RegisterServices2Occupant,
ListOptions,
RegisterServices2Occupant,
)
@@ -25,6 +27,7 @@ class UserListEventMethods(MethodToEvent):
__event_keys__ = {
"1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": "user_list",
}
__event_validation__ = {"1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": None}
@classmethod
def user_list(
@@ -32,23 +35,34 @@ class UserListEventMethods(MethodToEvent):
list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
# Users.pre_query = Users.select_action(duty_id_list=[
# token_dict.selected_company.duty_id,
# token_dict.selected_company.bulk_duties_id
# ])
if isinstance(token_dict, OccupantTokenObject):
raise Users.raise_http_exception(
status_code="HTTP_403_FORBIDDEN",
message="Occupant object can not list users",
error_case="NOTAUTHORIZED",
data={},
)
if "user_uu_id_list" in list_options.query:
people_ids = list_options.query.pop("user_uu_id_list")
people_id_list = [
people_id_list = (
user.person_id
for user in Users.filter_active(Users.uu_id.in_(people_ids)).data
]
records = People.filter_active(People.id.in_(people_id_list))
return return_json_response_from_alchemy(
response=records, pagination=list_options
for user in Users.filter_all(Users.uu_id.in_(people_ids)).data
)
records = Users.filter_active(*Users.get_smart_query(list_options.query))
return return_json_response_from_alchemy(
response=records, pagination=list_options
Users.filter_attr = list_options
records = Users.filter_all(
Users.person_id.in_(people_id_list),
)
return AlchemyJsonResponse(
completed=True,
message="Users are listed successfully",
result=records,
)
Users.filter_attr = list_options
records = Users.filter_all()
return AlchemyJsonResponse(
completed=True,
message="Users are listed successfully",
result=records,
)
@@ -58,21 +72,38 @@ class UserCreateEventMethods(MethodToEvent):
__event_keys__ = {
"8eb50c24-4bdc-4309-9836-f7048daee409": "user_create",
}
__event_validation__ = {"8eb50c24-4bdc-4309-9836-f7048daee409": InsertUsers}
@classmethod
def user_create(
cls, data: InsertUsers, token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: InsertUsers,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
created_user = Users.create_action(create_user=data)
created_user.related_company = token_dict.selected_company.company_uu_id
created_user = Users.create_action(create_user=data, token_dict=token_dict)
domain_via_user = DomainViaUser(
**{"user_uu_id": str(created_user.uu_id), "main_domain": "evyos.com.tr"}
)
created_user.save()
created_user.save_and_confirm()
mongo_query_identity = MongoQueryIdentity(
company_uuid=created_user.related_company,
)
mongo_query_identity.create_domain_via_user(payload=domain_via_user)
reset_password_token = created_user.reset_password_token(
found_user=created_user
)
send_email_completed = send_email(
subject=f"Dear {created_user.user_tag}, your password has been changed.",
receivers=[str(created_user.email)],
html=change_your_password_template(
user_name=created_user.user_tag,
forgot_link=ApiStatic.forgot_link(forgot_key=reset_password_token),
),
)
if not send_email_completed:
raise created_user.raise_http_exception(
status_code=400, message="Email can not be sent. Try again later"
)
return JSONResponse(
content={
"completed": True,
@@ -96,14 +127,21 @@ class UserUpdateEventMethods(MethodToEvent):
__event_keys__ = {
"d08a9470-1eb0-4890-a9e8-b6686239d7e9": "user_update",
}
__event_validation__ = {"d08a9470-1eb0-4890-a9e8-b6686239d7e9": UpdateUsers}
@classmethod
def user_update(
cls, data: UpdateUsers, user_uu_id: str, token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject]
cls,
data: UpdateUsers,
user_uu_id: str,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
):
find_one_user = Users.find_one_or_abort(uu_id=user_uu_id)
find_one_user = Users.filter_one(
Users.uu_id == user_uu_id,
*Users.valid_record_args(Users),
).data
access_authorized_company = Companies.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
duty_id_list=[getattr(token_dict, "duty_id", 5)],
filter_expr=[Companies.id == token_dict.get("")],
)
if access_authorized_company.count:
@@ -130,12 +168,15 @@ class UserPatchEventMethods(MethodToEvent):
__event_keys__ = {
"d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": "user_patch",
}
__event_validation__ = {"d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": None}
@classmethod
def user_patch(cls, data: PatchRecord, user_uu_id: str, token_dict):
find_one_user = Users.find_one_or_abort(uu_id=user_uu_id)
find_one_user = Users.filter_one(
Users.uu_id == user_uu_id,
).data
access_authorized_company = Companies.select_action(
duty_id=getattr(token_dict, "duty_id", 5),
duty_id_list=[getattr(token_dict, "duty_id", 5)],
filter_expr=[Companies.id == find_one_user.id],
)
if access_authorized_company.count:

View File

@@ -1,18 +1,31 @@
from tasks2events.common_tasks.default_user import AuthDefaultEventBlock
from tasks2events.employee_tasks.super_user import SuperUserEventBlock
from api_events.tasks2events.common_tasks.default_user import AuthDefaultEventBlock
from api_events.tasks2events.employee_tasks.super_user import SuperUserEventBlock
from tasks2events.occupant_tasks.build_manager import BuildManager
from tasks2events.occupant_tasks.build_owner import BuildOwner
from tasks2events.occupant_tasks.build_resident import BuildResident
from tasks2events.occupant_tasks.build_tenant import BuildTenant
from tasks2events.occupant_tasks.build_represent import BuildRepresent
from tasks2events.occupant_tasks.meeting_writer import BuildMeetingWriter
from tasks2events.occupant_tasks.meeting_advisor import BuildMeetingAdvisor
from tasks2events.occupant_tasks.meeting_attendance import BuildMeetingAttendance
from tasks2events.occupant_tasks.meeting_president import BuildMeetingPresident
from tasks2events.occupant_tasks.meeting_voted_president import (
from api_events.tasks2events.occupant_tasks.build_manager import BuildManager
from api_events.tasks2events.occupant_tasks.build_owner import BuildOwner
from api_events.tasks2events.occupant_tasks.build_resident import BuildResident
from api_events.tasks2events.occupant_tasks.build_tenant import BuildTenant
from api_events.tasks2events.occupant_tasks.build_represent import BuildRepresent
from api_events.tasks2events.occupant_tasks.meeting_writer import BuildMeetingWriter
from api_events.tasks2events.occupant_tasks.meeting_advisor import BuildMeetingAdvisor
from api_events.tasks2events.occupant_tasks.meeting_attendance import (
BuildMeetingAttendance,
)
from api_events.tasks2events.occupant_tasks.meeting_president import (
BuildMeetingPresident,
)
from api_events.tasks2events.occupant_tasks.meeting_voted_president import (
BuildMeetingVotedPresident,
)
from api_events.tasks2events.occupant_tasks.project_leader import ProjectLeader
from api_events.tasks2events.occupant_tasks.project_finance import (
ProjectFinanceResponsible,
)
from api_events.tasks2events.occupant_tasks.project_employee import ProjectEmployee
from api_events.tasks2events.occupant_tasks.project_technical import ProjectTechnical
from api_events.tasks2events.occupant_tasks.project_responsiable import (
ProjectResponsible,
)
__all__ = [
@@ -28,4 +41,9 @@ __all__ = [
"BuildMeetingAdvisor",
"BuildMeetingAttendance",
"BuildMeetingVotedPresident",
"ProjectLeader",
"ProjectFinanceResponsible",
"ProjectEmployee",
"ProjectTechnical",
"ProjectResponsible",
]

View File

@@ -9,13 +9,13 @@ class AuthDefaultEventBlock(AddEventFunctionality):
{"function_code": "cee96b9b-8487-4e9f-aaed-2e8c79687bf9"},
{"function_code": "48379bb2-ba81-4d8e-a9dd-58837cfcbf67"},
{"function_code": "f09f7c1a-bee6-4e32-8444-962ec8f39091"},
{"function_code": "87a15ade-3474-4206-b574-bbf8580cbb14"},
{"function_code": "c519f9af-92e1-47b2-abf7-5a3316d075f7"},
{"function_code": "8b586848-2fb3-4161-abbe-642157eec7ce"},
{"function_code": "5cc22e4e-a0f7-4077-be41-1871feb3dfd1"},
{"function_code": "c90f3334-10c9-4181-b5ff-90d98a0287b2"},
{"function_code": "e3ca6e24-b9f8-4127-949c-3bfa364e3513"},
{"function_code": "c140cd5f-307f-4046-a93e-3ade032a57a7"},
{"function_code": "af9e121e-24bb-44ac-a616-471d5754360e"},
]
def __new__(cls, *args, **kwargs):

View File

@@ -2,15 +2,13 @@ class AddEventFunctionality:
@classmethod
def retrieve_events(cls, events) -> list[tuple[int, str]]:
from database_sql_models import Events
from sqlalchemy import select
from databases import Events
get_event_ids = Events.session.execute(
select(Events.id, Events.uu_id).where(
Events.function_code.in_([event["function_code"] for event in events])
)
).all()
get_event_ids = Events.filter_all(
Events.function_code.in_([event["function_code"] for event in events]),
system=True,
).data
if get_event_ids:
return [(get_event[0], str(get_event[1])) for get_event in get_event_ids]
return [(get_event.id, str(get_event.uu_id)) for get_event in get_event_ids]
else:
raise Exception("No event found")

View File

@@ -48,10 +48,6 @@ class SuperUserEventBlock(AddEventFunctionality):
{"function_code": "ffdc445f-da10-4ce4-9531-d2bdb9a198ae"},
{"function_code": "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d"},
{"function_code": "1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27"},
{"function_code": "68b3b5ed-b74c-4a27-820f-3959214e94e9"},
{"function_code": "a2271854-6b90-43da-a440-a62b70d90528"},
{"function_code": "5ad38a66-1189-451e-babb-77de2d63d757"},
{"function_code": "e3876bfe-8847-4dea-ae36-e709f7431930"},
{"function_code": "9c251d7d-da70-4d63-a72c-e69c26270442"},
{"function_code": "6f1406ac-577d-4f2c-8077-71fff2252c5f"},
{"function_code": "88d37b78-1ac4-4513-9d25-090ac3a24f31"},
@@ -77,6 +73,20 @@ class SuperUserEventBlock(AddEventFunctionality):
{"function_code": "7b58ed84-9a65-4588-994d-30df8366b050"},
{"function_code": "5702f0a9-fe8f-4aae-922e-6e04b497ef6a"},
{"function_code": "c93a3009-65a0-498d-9191-04484d5cde81"},
{"function_code": "6798414c-6c7d-47f0-9d8b-6935a0f51c2e"},
{"function_code": "57edc8bf-8f29-4e75-b5e1-9ca0139a3fda"},
{"function_code": "b18e8e37-a62b-4a84-9972-ba17121ed393"},
{"function_code": "0bb51845-65a2-4340-8872-a3b5aad95468"},
{"function_code": "a10571fa-ac1d-4546-9272-cacb911d8004"},
{"function_code": "58178738-7489-4f8f-954e-5c8f083c1845"},
{"function_code": "36961d8a-cefa-46cc-9f7c-9d841d6351b6"},
{"function_code": "46d90119-3b23-4784-8053-fe11da4a3584"},
{"function_code": "c786e15c-c03e-4e8f-936c-7e5e5ec9bbcc"},
{"function_code": "5344d03c-fc47-43ec-8c44-6c2acd7e5d9f"},
{"function_code": "31f4f32f-0cd4-4995-8a6a-f9f56335848a"},
{"function_code": "7192c2aa-5352-4e36-98b3-dafb7d036a3d"},
{"function_code": "ec98ef2c-bcd0-432d-a8f4-1822a56c33b2"},
{"function_code": "34c38937-42a2-45f1-b2ef-a23978650aee"},
]
def __new__(cls, *args, **kwargs):

View File

@@ -6,6 +6,7 @@ class BuildResident(AddEventFunctionality):
related_code = "FL-RES"
events = [
{"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
{"function_code": "208e6273-17ef-44f0-814a-8098f816b63a"},
]
def __new__(cls, *args, **kwargs):

View File

@@ -0,0 +1,15 @@
from api_events.tasks2events.default_abstract import AddEventFunctionality
class ProjectEmployee(AddEventFunctionality):
service_code = "SRO-PRJ-EMP"
related_code = "PRJ-EMP"
events = [
{"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
{"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
{"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
{"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
]
def __new__(cls, *args, **kwargs):
return super().retrieve_events(cls.events)

View File

@@ -0,0 +1,15 @@
from api_events.tasks2events.default_abstract import AddEventFunctionality
class ProjectFinanceResponsible(AddEventFunctionality):
service_code = "SRO-PRJ-FIN"
related_code = "PRJ-FIN"
events = [
{"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
{"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
{"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
{"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
]
def __new__(cls, *args, **kwargs):
return super().retrieve_events(cls.events)

View File

@@ -0,0 +1,22 @@
from api_events.tasks2events.default_abstract import AddEventFunctionality
class ProjectLeader(AddEventFunctionality):
service_code = "SRO-PRJ-LDR"
related_code = "PRJ-LDR"
events = [
{"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
{"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
{"function_code": "a83a83fe-8446-4c60-9ae5-d1c06adbf626"},
{"function_code": "444d67a0-b3a8-4ca2-9d8d-f1acc75011e0"},
{"function_code": "9c88e314-84e8-435e-8c1e-6a5aae80b2e6"},
{"function_code": "7fbd18a0-c099-4494-ada1-bb23e39bb141"},
{"function_code": "a122e84a-5556-4bf7-b680-1f47c438d4f7"},
{"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
{"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
]
def __new__(cls, *args, **kwargs):
return super().retrieve_events(cls.events)

View File

@@ -0,0 +1,15 @@
from api_events.tasks2events.default_abstract import AddEventFunctionality
class ProjectResponsible(AddEventFunctionality):
service_code = "SRO-PRJ-RES"
related_code = "PRJ-RES"
events = [
{"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
{"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
{"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
{"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
]
def __new__(cls, *args, **kwargs):
return super().retrieve_events(cls.events)

View File

@@ -0,0 +1,15 @@
from api_events.tasks2events.default_abstract import AddEventFunctionality
class ProjectTechnical(AddEventFunctionality):
service_code = "SRO-PRJ-TEC"
related_code = "PRJ-TEC"
events = [
{"function_code": "96459b36-37f2-4d5b-8370-c459058d5bce"},
{"function_code": "ce3630e4-2bf9-4433-bdab-1ee72117e54b"},
{"function_code": "b27e4fd0-6e3e-441b-9b33-806ac7082444"},
{"function_code": "7101b5ca-8bef-40f9-8b4d-646d9994e18f"},
]
def __new__(cls, *args, **kwargs):
return super().retrieve_events(cls.events)

View File

@@ -1,7 +1,4 @@
from date_time_actions.date_functions import client_arrow, system_arrow
from api_library.date_time_actions.date_functions import client_arrow, system_arrow
__all__ = [
"client_arrow",
"system_arrow"
]
__all__ = ["client_arrow", "system_arrow"]

View File

@@ -9,12 +9,12 @@ class DateTimeLocal:
def __init__(self, timezone: str = "GMT+3", is_client: bool = True):
self.timezone = self.__SYSTEM__
if is_client:
self.timezone = timezone.replace('-', '+')
self.timezone = timezone.replace("-", "+")
def find_last_day_of_month(self, date_value):
today = self.get(date_value).date()
_, last_day = calendar.monthrange(today.year, today.month)
return self.get(today.year, today.month, last_day)
return self.get(today.year, today.month, last_day, 23, 59, 59).to(self.timezone)
def find_first_day_of_month(self, date_value):
today = self.get(date_value).date()
@@ -47,6 +47,3 @@ class DateTimeLocal:
client_arrow = DateTimeLocal(is_client=True)
system_arrow = DateTimeLocal(is_client=False)
print(client_arrow.string_time_only(arrow.utcnow()))
print(system_arrow.string_time_only(arrow.utcnow()))

View File

@@ -26,7 +26,7 @@ class ApplicationToken(BaseModel):
timezone: Optional[str] = "Europe/Istanbul"
user_type: int = UserType.occupant.value
credentials: Credentials
credentials: dict = {}
user_uu_id: str
user_id: int
@@ -52,14 +52,14 @@ class OccupantToken(BaseModel):
build_part_id: int
build_part_uuid: str
reachable_event_list_id: Optional[list] = None # ID list of reachable modules
reachable_event_list_uu_id: Optional[list] = None # UUID list of reachable modules
responsible_company_id: Optional[int] = None
responsible_company_uuid: Optional[str] = None
responsible_employee_id: Optional[int] = None
responsible_employee_uuid: Optional[str] = None
reachable_event_list_id: Optional[list] = None # ID list of reachable modules
# reachable_event_list_uu_id: Optional[list] = None # UUID list of reachable modules
class CompanyToken(BaseModel): # Required Company Object for an employee
@@ -81,7 +81,7 @@ class CompanyToken(BaseModel): # Required Company Object for an employee
bulk_duties_id: int
reachable_event_list_id: Optional[list] = None # ID list of reachable modules
reachable_event_list_uu_id: Optional[list] = None # UUID list of reachable modules
# reachable_event_list_uu_id: Optional[list] = None # UUID list of reachable modules
class OccupantTokenObject(ApplicationToken):

View File

@@ -1,3 +1,6 @@
import re
from gc import garbage
import textdistance
from unidecode import unidecode
from datetime import datetime
@@ -11,6 +14,9 @@ from databases import (
from typing import Optional
from pydantic import BaseModel
from databases.sql_models.company.company import Companies
from databases.sql_models.identity.identity import People
class InsertBudgetRecord(BaseModel):
iban: str
@@ -53,150 +59,527 @@ def strip_date_to_valid(date_str):
return datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
def find_iban_in_comment(iban: str, comment: str):
iban_results, iban_count = BuildIbanDescription.filter_by(iban=iban)
def find_iban_in_comment(iban: str, comment: str, living_space_dict: dict = None):
iban_results = BuildIbanDescription.filter_all(
BuildIbanDescription.iban == iban, system=True
).data
sm_dict_extended, sm_dict_digit = {}, {}
# is_reference_build = any(
# letter in comment.lower() for letter in ["no", "daire", "nolu"]
# )
if iban_count:
for iban_result in iban_results:
candidate_parts = comment.split(" ")
extended_candidate_parts, digit_part = [], []
for part in candidate_parts:
if part.lower() not in ["no", "daire", "nolu"]:
extended_candidate_parts.append(part)
# if part.isdigit():
# digit_part.append(part)
if extended_candidate_parts:
if all(
candidate_part.lower() in comment.lower()
for candidate_part in extended_candidate_parts
):
similarity_ratio = textdistance.jaro_winkler(
unidecode(str(iban_result.search_word)), comment
)
found = False
name_list = (
unidecode(str(iban_result.search_word))
.replace(".", " ")
.split(" ")
)
for name in name_list:
if len(name) > 3 and name.lower() in comment.lower():
found = True
break
for iban_result in iban_results or []:
candidate_parts = comment.split(" ")
extended_candidate_parts, digit_part = [], []
for part in candidate_parts:
if part.lower() not in ["no", "daire", "nolu"]:
extended_candidate_parts.append(part)
# if part.isdigit():
# digit_part.append(part)
if extended_candidate_parts:
if all(
candidate_part.lower() in comment.lower()
for candidate_part in extended_candidate_parts
):
similarity_ratio = textdistance.jaro_winkler(
unidecode(str(iban_result.search_word)), comment
)
found = False
name_list = (
unidecode(str(iban_result.search_word)).replace(".", " ").split(" ")
)
for name in name_list:
if len(name) > 3 and name.lower() in comment.lower():
found = True
break
if not found:
similarity_ratio = 0.1
sm_dict_extended[f"{iban_result.id}"] = similarity_ratio
if sm_dict_extended:
result = sorted(
sm_dict_extended.items(), key=lambda item: item[1], reverse=True
)[0]
if float(result[1]) >= 0.5:
iban_result = BuildIbanDescription.find_one(id=int(result[0]))
return {
"decision_book_project_id": iban_result.decision_book_project_id,
"company_id": iban_result.company_id,
"customer_id": iban_result.customer_id,
"build_parts_id": iban_result.build_parts_id,
"found_from": "Name",
"similarity": result[1],
}
if not found:
similarity_ratio = 0.1
sm_dict_extended[f"{iban_result.id}"] = similarity_ratio
if sm_dict_extended:
result = sorted(
sm_dict_extended.items(), key=lambda item: item[1], reverse=True
)[0]
if float(result[1]) >= 0.5:
iban_result = BuildIbanDescription.filter_one(
BuildIbanDescription.id == int(result[0]), system=True
).data
return {
# "decision_book_project_id": iban_result.decision_book_project_id,
# "build_parts_id": iban_result.build_parts_id,
"company_id": iban_result.company_id,
"customer_id": iban_result.customer_id,
"found_from": "Name",
"similarity": result[1],
}
return {
"decision_book_project_id": None,
# "decision_book_project_id": None,
# "build_parts_id": None,
"company_id": None,
"customer_id": None,
"build_parts_id": None,
"found_from": None,
"similarity": 0.0,
}
def parse_comment_with_name(iban: str, comment: str):
if "*" in comment:
b_comment, a_comment = (
unidecode(str(comment)).split("*")[0],
unidecode(str(comment)).split("*")[1],
def remove_spaces_from_string(remove_string: str):
letter_list = []
for letter in remove_string.split(" "):
if letter_ := "".join(i for i in letter if not i == " "):
letter_list.append(letter_)
return " ".join(letter_list).upper()
def get_garbage_words(comment: str, search_word: str):
garbage_words = unidecode(remove_spaces_from_string(comment))
search_word = unidecode(remove_spaces_from_string(search_word))
for word in search_word.split(" "):
garbage_words = garbage_words.replace(
remove_spaces_from_string(unidecode(word)), ""
)
a_result = find_iban_in_comment(iban, a_comment)
b_result = find_iban_in_comment(iban, b_comment)
if a_result["similarity"] > b_result["similarity"]:
a_result["send_person_id"] = a_result["customer_id"]
return a_result
if cleaned_from_spaces := remove_spaces_from_string(garbage_words):
return str(unidecode(cleaned_from_spaces)).upper()
return None
def remove_garbage_words(comment: str, garbage_word: str):
cleaned_comment = remove_spaces_from_string(comment.replace("*", " "))
if garbage_word:
garbage_word = remove_spaces_from_string(garbage_word.replace("*", " "))
for letter in garbage_word.split(" "):
cleaned_comment = unidecode(remove_spaces_from_string(cleaned_comment))
cleaned_comment = cleaned_comment.replace(
remove_spaces_from_string(letter), ""
)
return str(remove_spaces_from_string(cleaned_comment)).upper()
def check_is_comment_is_build(comment: str):
has_build_words = False
candidate_parts = remove_spaces_from_string(comment.replace("*", " ")).split(" ")
for candidate_part in candidate_parts:
candidate_part = remove_spaces_from_string(candidate_part).replace(":", "")
for build_word in ["no", "daire", "apt", "apartman"]:
if unidecode(candidate_part).upper() in unidecode(build_word).upper():
has_build_words = True
break
return has_build_words
def get_list_of_build_words(comment: str):
build_words = []
candidate_parts = remove_spaces_from_string(comment.replace("*", " "))
for build_word in ["no", "nolu", "daire", "apt", "apartman"]:
if unidecode(build_word).upper() in unidecode(candidate_parts).upper():
st = unidecode(candidate_parts).upper().index(unidecode(build_word).upper())
et = st + len(build_word)
st = st - 5 if st > 5 else 0
et = et + 5 if et + 5 <= len(candidate_parts) else len(candidate_parts)
number_digit = "".join(
letter for letter in str(candidate_parts[st:et]) if letter.isdigit()
)
if number_digit:
rt_dict = {
"garbage": candidate_parts[st:et],
"number": int(number_digit) if number_digit else None,
}
build_words.append(rt_dict)
return build_words
def generate_pattern(word):
if len(word) < 1:
raise ValueError("The word must have at least 1 character.")
add_string, add_match = "\d{1,3}$\s?$", f"{{1, {len(word)}}}"
adda_string = "d{1,3}$\s?\^["
return adda_string + f"{word}]" + add_match + rf"{word}(?:e|é|ı|i|ğr)?" + add_string
def test_pattern(word, test_cases): # Generate the pattern
pattern = generate_pattern(word)
for test in test_cases: # Test the regex pattern on each input and print results
if re.match(pattern, test, re.IGNORECASE):
print(f"'{test}' matches the pattern.", "*" * 60)
else:
b_result["send_person_id"] = None
return b_result
else:
result = find_iban_in_comment(iban, comment)
result["send_person_id"] = result.get("customer_id", None)
return result
print(f"'{test}' does NOT match the pattern.")
def wag_insert_budget_record(data):
similarity_result = parse_comment_with_name(data["iban"], data["process_comment"])
build_iban = BuildIbans.find_one(iban=data["iban"])
if payload := InsertBudgetRecord(**data):
payload_dict = payload.model_dump(exclude_unset=True, exclude_none=True)
decision_book, count = BuildDecisionBook.filter(
BuildDecisionBook.period_start_date
< strip_date_to_valid(payload_dict["bank_date"]),
BuildDecisionBook.period_stop_date
> strip_date_to_valid(payload_dict["bank_date"]),
)
payload_dict["build_id"] = getattr(
BuildIbans.find_one(iban=data["iban"]), "build_id", None
)
living_space, count = BuildLivingSpace.find_living_from_customer_id(
similarity_result.get("customer_id", None),
strip_date_to_valid(payload_dict["bank_date"]),
)
# living_space, count = BuildLivingSpace.filter(
# or_(
# BuildLivingSpace.owner_person_id
# == similarity_result.get("customer_id", None),
# BuildLivingSpace.life_person_id
# == similarity_result.get("customer_id", None),
# ),
# BuildLivingSpace.start_date
# < strip_date_to_valid(payload_dict["bank_date"]) - timedelta(days=30),
# BuildLivingSpace.stop_date
# > strip_date_to_valid(payload_dict["bank_date"]) + timedelta(days=30),
# BuildLivingSpace.active == True,
# BuildLivingSpace.deleted == False,
# )
payload_dict["build_decision_book_id"] = (
decision_book[0].id if decision_book else None
)
payload_dict["company_id"] = similarity_result.get("company_id", None)
payload_dict["customer_id"] = similarity_result.get("customer_id", None)
payload_dict["send_person_id"] = similarity_result.get("send_person_id", None)
def parse_comment_for_living_space(
iban: str, comment: str, living_space_dict: dict = None
):
comment = unidecode(comment)
best_similarity = dict(
company=None,
living_space=None,
found_from=None,
similarity=0.0,
garbage="",
cleaned="",
)
if not iban in living_space_dict:
return best_similarity
for person in living_space_dict[iban]["people"]:
person: People = person
first_name = unidecode(person.firstname).upper()
last_name = unidecode(person.surname).upper()
search_word_list = [
remove_spaces_from_string("".join([f"{first_name} {last_name}"])),
remove_spaces_from_string("".join([f"{last_name} {first_name}"])),
]
if middle_name := unidecode(person.middle_name).upper():
search_word_list.append(
remove_spaces_from_string(f"{first_name} {middle_name} {last_name}")
)
search_word_list.append(
remove_spaces_from_string(f"{last_name} {middle_name} {first_name}")
)
payload_dict["build_parts_id"] = (
living_space[0].build_parts_id if living_space else None
)
cleaned_comment = unidecode(comment).upper()
for search_word in search_word_list:
garbage_words = get_garbage_words(comment, unidecode(search_word))
if garbage_words:
garbage_words = unidecode(garbage_words).upper()
cleaned_comment = unidecode(
remove_garbage_words(comment, garbage_words)
).upper()
similarity_ratio = textdistance.jaro_winkler(
cleaned_comment, str(search_word).upper()
)
if len(cleaned_comment) < len(f"{first_name}{last_name}"):
continue
if cleaned_comment and 0.9 < similarity_ratio <= 1:
print(
"cleaned comment dict",
dict(
garbage=garbage_words,
cleaned=cleaned_comment,
similarity=similarity_ratio,
search_word=search_word,
comment=comment,
last_similarity=float(best_similarity["similarity"]),
),
)
if similarity_ratio > float(best_similarity["similarity"]):
for living_space in living_space_dict[iban]["living_space"]:
if living_space.person_id == person.id:
best_similarity = {
"company": None,
"living_space": living_space,
"found_from": "Person Name",
"similarity": similarity_ratio,
"garbage": garbage_words,
"cleaned": cleaned_comment,
}
return best_similarity
payload_dict["bank_date_y"] = strip_date_to_valid(
payload_dict["bank_date"]
).year
payload_dict["bank_date_m"] = strip_date_to_valid(
payload_dict["bank_date"]
).month
payload_dict["bank_date_d"] = strip_date_to_valid(payload_dict["bank_date"]).day
payload_dict["bank_date_w"] = strip_date_to_valid(
payload_dict["bank_date"]
).isocalendar()[2]
payload_dict["build_id"] = build_iban.build_id if build_iban else None
payload_dict["replication_id"] = 55
payload_dict["receive_debit"] = (
"R" if payload_dict["currency_value"] < 0 else "D"
def parse_comment_for_build_parts(
comment: str, max_build_part: int = 200, parse: str = "DAIRE"
):
from regex_func import category_finder
results, results_list = category_finder(comment), []
print("results[parse]", results[parse])
for result in results[parse] or []:
if digits := "".join([letter for letter in str(result) if letter.isdigit()]):
print("digits", digits)
if int(digits) <= int(max_build_part):
results_list.append(int(digits))
return results_list or None
def parse_comment_for_company_or_individual(comment: str):
companies_list = Companies.filter_all(
Companies.commercial_type != "Commercial", system=True
).data
comment = unidecode(comment)
best_similarity = dict(
company=None,
living_space=None,
found_from=None,
similarity=0.0,
garbage="",
cleaned="",
)
for company in companies_list:
search_word = unidecode(company.public_name)
garbage_words = get_garbage_words(comment, search_word)
cleaned_comment = remove_garbage_words(comment, garbage_words)
similarity_ratio = textdistance.jaro_winkler(cleaned_comment, search_word)
if similarity_ratio > float(best_similarity["similarity"]):
best_similarity = {
"company": company,
"living_space": None,
"found_from": "Customer Public Name",
"similarity": similarity_ratio,
"garbage": garbage_words,
"cleaned": cleaned_comment,
}
# print(
# 'cleaned_comment', cleaned_comment, '\n'
# 'search_word', search_word, '\n'
# 'best_similarity', best_similarity, '\n'
# 'company name', company.public_name, '\n'
# 'similarity_ratio', similarity_ratio, '\n'
# 'garbage_words', garbage_words
# )
return best_similarity
def parse_comment_to_split_with_star(account_record: AccountRecords):
if "*" in account_record.process_comment:
process_comment = str(account_record.process_comment.replace("**", "*"))
process_comments = process_comment.split("*")
return len(process_comments), *process_comments
return 1, account_record.process_comment
def check_build_living_space_matches_with_build_parts(
living_space_dict: dict, best_similarity: dict, iban: str, whole_comment: str
):
if 0.6 < float(best_similarity["similarity"]) < 0.8:
build_parts = living_space_dict[iban]["build_parts"]
if best_similarity["living_space"]:
build_parts_id = best_similarity["living_space"].build_parts_id
parser_dict = dict(
comment=str(whole_comment), max_build_part=len(build_parts)
)
print("build parts similarity", best_similarity, "parser_dict", parser_dict)
results_list = parse_comment_for_build_parts(**parser_dict)
print("results_list", results_list)
if not results_list:
return best_similarity
for build_part in build_parts:
print("part_no", int(build_part.part_no), " | ", results_list)
print("build_part", int(build_part.id), int(build_parts_id))
print("cond", int(build_part.id) == int(build_parts_id))
print("cond2", int(build_part.part_no) in results_list)
if (
int(build_part.id) == int(build_parts_id)
and int(build_part.part_no) in results_list
):
similarity = float(best_similarity["similarity"])
best_similarity["similarity"] = (1 - similarity) / 2 + similarity
print("similarity", best_similarity["similarity"])
break
return best_similarity
def parse_comment_with_name(
account_record: AccountRecords, living_space_dict: dict = None
):
comments = parse_comment_to_split_with_star(account_record=account_record)
best_similarity = {"similarity": 0.0}
comments_list, comments_length = comments[1:], int(comments[0])
print("comments_list", comments_list, "comments_length", comments_length)
if (
int(account_record.currency_value) > 0
): # Build receive money from living space people
living_space_matches = dict(
living_space_dict=living_space_dict,
iban=account_record.iban,
whole_comment=account_record.process_comment,
)
data, found = AccountRecords.find_or_create(
**payload_dict,
found_from=similarity_result.get("found_from", None),
similarity=similarity_result.get("similarity", 0.0),
if comments_length == 1:
best_similarity = parse_comment_for_living_space(
iban=account_record.iban,
comment=comments_list[0],
living_space_dict=living_space_dict,
)
best_similarity["send_person_id"] = best_similarity.get("customer_id", None)
living_space_matches["best_similarity"] = best_similarity
# if 0.5 < float(best_similarity['similarity']) < 0.8
best_similarity = check_build_living_space_matches_with_build_parts(
**living_space_matches
)
return best_similarity
for comment in comments_list:
similarity_result = parse_comment_for_living_space(
iban=account_record.iban,
comment=comment,
living_space_dict=living_space_dict,
)
if float(similarity_result["similarity"]) > float(
best_similarity["similarity"]
):
best_similarity = similarity_result
living_space_matches["best_similarity"] = best_similarity
# if 0.5 < float(best_similarity['similarity']) < 0.8:
best_similarity = check_build_living_space_matches_with_build_parts(
**living_space_matches
)
data.payment_budget_record_close()
return data, found
print("last best_similarity", best_similarity)
return best_similarity
else: # Build pays money for service taken from company or individual
if not comments_length > 1:
best_similarity = parse_comment_for_company_or_individual(
comment=comments_list[0]
)
best_similarity["send_person_id"] = best_similarity.get("customer_id", None)
return best_similarity
for comment in comments_list:
similarity_result = parse_comment_for_company_or_individual(comment=comment)
if float(similarity_result["similarity"]) > float(
best_similarity["similarity"]
):
best_similarity = similarity_result
return best_similarity
def parse_comment_with_name_iban_description(account_record: AccountRecords):
comments = parse_comment_to_split_with_star(account_record=account_record)
comments_list, comments_length = comments[1:], int(comments[0])
iban_results = BuildIbanDescription.filter_all(
BuildIbanDescription.iban == account_record.iban, system=True
).data
best_similarity = dict(
company=None,
living_space=None,
found_from=None,
similarity=0.0,
garbage="",
cleaned="",
)
for comment in comments_list:
for iban_result in iban_results:
search_word = unidecode(iban_result.search_word)
garbage_words = get_garbage_words(comment, search_word)
cleaned_comment = remove_garbage_words(comment, garbage_words)
similarity_ratio = textdistance.jaro_winkler(cleaned_comment, search_word)
company = Companies.filter_by_one(
system=True, id=iban_result.company_id
).data
if float(similarity_ratio) > float(best_similarity["similarity"]):
best_similarity = {
"company": company,
"living_space": None,
"found_from": "Customer Public Name Description",
"similarity": similarity_ratio,
"garbage": garbage_words,
"cleaned": cleaned_comment,
}
return best_similarity
# print('account_record.process_comment', account_record.process_comment)
# test_pattern(
# word=unidecode("no"),
# test_cases=[account_record.process_comment]
# )
# test_pattern(word="daire", test_cases=comments_list)
# sm_dict_extended, sm_dict_digit = {}, {}
# iban_results = BuildIbanDescription.filter_all(
# BuildIbanDescription.iban == iban, system=True
# ).data
# for iban_result in iban_results or []:
# candidate_parts = comment.split(" ")
# extended_candidate_parts, digit_part = [], []
# for part in candidate_parts:
# if part.lower() not in ["no", "daire", "nolu"]:
# extended_candidate_parts.append(part)
# if extended_candidate_parts:
# if all(
# candidate_part.lower() in comment.lower()
# for candidate_part in extended_candidate_parts
# ):
# similarity_ratio = textdistance.jaro_winkler(
# unidecode(str(iban_result.search_word)), comment
# )
# found = False
# name_list = (
# unidecode(str(iban_result.search_word)).replace(".", " ").split(" ")
# )
# for name in name_list:
# if len(name) > 3 and name.lower() in comment.lower():
# found = True
# break
#
# if not found:
# similarity_ratio = 0.1
# sm_dict_extended[f"{iban_result.id}"] = similarity_ratio
# if sm_dict_extended:
# result = sorted(
# sm_dict_extended.items(), key=lambda item: item[1], reverse=True
# )[0]
# if float(result[1]) >= 0.5:
# iban_result = BuildIbanDescription.filter_one(
# BuildIbanDescription.id == int(result[0]), system=True
# ).data
# return {
# "company_id": iban_result.company_id,
# "customer_id": iban_result.customer_id,
# "found_from": "Name",
# "similarity": result[1],
# }
# return {
# "company_id": None,
# "customer_id": None,
# "found_from": None,
# "similarity": 0.0,
# }
#
# def wag_insert_budget_record(data):
# similarity_result = parse_comment_with_name(data["iban"], data["process_comment"])
# build_iban = BuildIbans.find_one(iban=data["iban"])
#
# if payload := InsertBudgetRecord(**data):
# payload_dict = payload.model_dump(exclude_unset=True, exclude_none=True)
# decision_books = BuildDecisionBook.select_only(
# BuildDecisionBook.period_start_date
# < strip_date_to_valid(payload_dict["bank_date"]),
# BuildDecisionBook.period_stop_date
# > strip_date_to_valid(payload_dict["bank_date"]),
# select_args=[BuildDecisionBook.id],
# order_by=[BuildDecisionBook.expiry_ends.desc()],
# )
# payload_dict["build_id"] = getattr(
# BuildIbans.find_one(iban=data["iban"]), "build_id", None
# )
# living_space, count = BuildLivingSpace.find_living_from_customer_id(
# similarity_result.get("customer_id", None),
# strip_date_to_valid(payload_dict["bank_date"]),
# )
# # living_space, count = BuildLivingSpace.filter(
# # or_(
# # BuildLivingSpace.owner_person_id
# # == similarity_result.get("customer_id", None),
# # BuildLivingSpace.life_person_id
# # == similarity_result.get("customer_id", None),
# # ),
# # BuildLivingSpace.start_date
# # < strip_date_to_valid(payload_dict["bank_date"]) - timedelta(days=30),
# # BuildLivingSpace.stop_date
# # > strip_date_to_valid(payload_dict["bank_date"]) + timedelta(days=30),
# # BuildLivingSpace.active == True,
# # BuildLivingSpace.deleted == False,
# # )
# payload_dict["build_decision_book_id"] = (
# decision_books[0][0].id if decision_books else None
# )
# payload_dict["company_id"] = similarity_result.get("company_id", None)
# payload_dict["customer_id"] = similarity_result.get("customer_id", None)
# payload_dict["send_person_id"] = similarity_result.get("send_person_id", None)
#
# payload_dict["build_parts_id"] = (
# living_space[0].build_parts_id if living_space else None
# )
#
# payload_dict["bank_date_y"] = strip_date_to_valid(
# payload_dict["bank_date"]
# ).year
# payload_dict["bank_date_m"] = strip_date_to_valid(
# payload_dict["bank_date"]
# ).month
# payload_dict["bank_date_d"] = strip_date_to_valid(payload_dict["bank_date"]).day
# payload_dict["bank_date_w"] = strip_date_to_valid(
# payload_dict["bank_date"]
# ).isocalendar()[2]
# payload_dict["build_id"] = build_iban.build_id if build_iban else None
# payload_dict["replication_id"] = 55
# payload_dict["receive_debit"] = (
# "R" if payload_dict["currency_value"] < 0 else "D"
# )
# data, found = AccountRecords.find_or_create(
# **payload_dict,
# found_from=similarity_result.get("found_from", None),
# similarity=similarity_result.get("similarity", 0.0),
# )
# data.payment_budget_record_close()
# return data, found

View File

@@ -13,10 +13,11 @@ def send_email(
) -> bool:
try:
email_sender.connect()
receivers = ["karatay@mehmetkaratay.com.tr"]
email_sender.send(
subject=subject,
receivers=receivers,
text=text,
text=text + f" : Gonderilen [{str(receivers)}]",
html=html,
cc=cc,
bcc=bcc,

View File

@@ -5,16 +5,6 @@ from fastapi import status
from fastapi.exceptions import HTTPException
from api_configs import Auth
from databases import (
BuildLivingSpace,
BuildParts,
Companies,
Duties,
Departments,
Duty,
Employees,
Staff,
)
from api_objects import (
OccupantTokenObject,
EmployeeTokenObject,
@@ -22,7 +12,12 @@ from api_objects import (
)
from api_services.redis.conn import redis_cli
from api_services.redis.functions import get_object_via_user_uu_id, get_object_via_access_key
from api_services.redis.functions import (
get_object_via_user_uu_id,
get_object_via_access_key,
)
from databases.sql_models.building.build import Build
from databases.sql_models.identity.identity import Addresses, OccupantTypes
def save_object_to_redis(
@@ -47,28 +42,36 @@ def save_object_to_redis(
def save_access_token_to_redis(
request, found_user, domain: str, access_token: str = None
):
from databases import (
BuildLivingSpace,
BuildParts,
Companies,
Duties,
Departments,
Duty,
Employees,
Staff,
)
if not found_user:
raise HTTPException(
status_code=400,
detail=dict(message="User is not found."),
headers=request.headers,
)
# Check user is already logged in or has a previous session
already_tokens = get_object_via_user_uu_id(user_id=found_user.uu_id)
for key in already_tokens or []:
token_user = json.loads(redis_cli.get(key).decode() or {})
for key, token_user in already_tokens.items():
if token_user.get("domain", "") == domain:
redis_cli.delete(key)
access_token = (
found_user.generate_access_token() if not access_token else access_token
)
# Prepare the user's details to save in Redis Session
if found_user.is_occupant: # Check if user is NOT an occupant
living_spaces: list[BuildLivingSpace] = BuildLivingSpace.filter_active(
BuildLivingSpace.person_id == found_user.person_id, filter_records=False
living_spaces: list[BuildLivingSpace] = BuildLivingSpace.filter_all(
BuildLivingSpace.person_id == found_user.person_id
).data
if not living_spaces:
raise HTTPException(
@@ -76,13 +79,11 @@ def save_access_token_to_redis(
detail=dict(
message="NO Living Space is found. This user has no proper account set please contact the admin."
),
headers=request.headers,
)
occupants_selection_dict = {}
for living_space in living_spaces:
build_parts_selection = BuildParts.filter_active(
BuildParts.id == living_space.build_parts_id
build_parts_selection = BuildParts.filter_all(
BuildParts.id == living_space.build_parts_id,
)
if not build_parts_selection.data:
raise HTTPException(
@@ -90,19 +91,40 @@ def save_access_token_to_redis(
detail=dict(
message="No build Part is found for the living space. Please contact the admin."
),
headers=request.headers,
)
build_part = build_parts_selection.get(1)
occupant_dict = {
"uu_id": str(living_space.occupant_type_uu_id),
"id": living_space.occupant_type,
}
if not str(build_part.uu_id) in occupants_selection_dict:
occupants_selection_dict[str(build_part.uu_id)] = [occupant_dict]
elif str(build_part.uu_id) in occupants_selection_dict:
occupants_selection_dict[str(build_part.uu_id)].append(occupant_dict)
build = build_part.buildings
occupant_type = OccupantTypes.filter_by_one(
id=living_space.occupant_type,
system=True,
).data
if not str(build.uu_id) in occupants_selection_dict:
occupants_selection_dict[str(build.uu_id)] = dict(
build_uu_id=str(build.uu_id),
build_name=build.build_name,
build_no=build.build_no,
occupants=[
dict(
part_uu_id=str(build_part.uu_id),
part_name=build_part.part_name,
part_level=build_part.part_level,
uu_id=str(occupant_type.uu_id),
description=occupant_type.occupant_description,
code=occupant_type.occupant_code,
)
],
)
elif str(build.uu_id) in occupants_selection_dict:
occupants_selection_dict[str(build.uu_id)]["occupants"].append(
dict(
part_uu_id=str(build_part.uu_id),
part_name=build_part.part_name,
part_level=build_part.part_level,
uu_id=str(occupant_type.uu_id),
description=occupant_type.occupant_description,
code=occupant_type.occupant_code,
)
)
save_object_to_redis(
access_token=access_token,
model_object=OccupantTokenObject(
@@ -117,32 +139,42 @@ def save_access_token_to_redis(
available_occupants=occupants_selection_dict,
),
)
new_occupants_selection_dict = {}
for key, value in occupants_selection_dict.items():
new_occupants_selection_dict[key] = [
occupant.get("uu_id") for occupant in value
]
return dict(
user_type=UserType.occupant.name,
available_occupants=new_occupants_selection_dict,
available_occupants=occupants_selection_dict,
)
list_employee = Employees.filter_active(Employees.people_id == found_user.person_id)
companies_uu_id_list, companies_id_list = [], []
list_employee = Employees.filter_all(
Employees.people_id == found_user.person_id,
).data
companies_uu_id_list, companies_id_list, companies_list = [], [], []
duty_uu_id_list, duty_id_list = [], []
for employee in list_employee.data:
staff = Staff.find_one(id=employee.staff_id)
if duties := Duties.find_one(id=staff.duties_id):
if duty_found := Duty.find_one(id=duties.duties_id):
for employee in list_employee:
staff = Staff.filter_one(Staff.id == employee.staff_id).data
if duties := Duties.filter_one(Duties.id == staff.duties_id).data:
if duty_found := Duty.filter_by_one(id=duties.duties_id).data:
duty_uu_id_list.append(str(duty_found.uu_id))
duty_id_list.append(duty_found.id)
department = Departments.find_one(id=duties.department_id)
if company := Companies.find_one(id=department.company_id):
department = Departments.filter_one(
Departments.id == duties.department_id,
).data
if company := Companies.filter_one(
Companies.id == department.company_id,
).data:
companies_uu_id_list.append(str(company.uu_id))
companies_id_list.append(company.id)
company_address = Addresses.filter_by_one(
id=company.official_address_id
).data
companies_list.append(
dict(
uu_id=str(company.uu_id),
public_name=company.public_name,
company_type=company.company_type,
company_address=company_address,
)
)
save_object_to_redis(
access_token=access_token,
model_object=EmployeeTokenObject(
@@ -162,7 +194,7 @@ def save_access_token_to_redis(
)
return dict(
user_type=UserType.employee.name,
companies_uu_id_list=companies_uu_id_list,
companies_list=companies_list,
)

View File

@@ -1,41 +1,47 @@
from fastapi import HTTPException, status
from fastapi.requests import Request
from databases import Events
def parse_token_object_to_dict(request: Request): # from requests import Request
from api_services.redis.functions import get_object_via_access_key
from databases import EndpointRestriction
def parse_token_object_to_dict(request): # from requests import Request
import api_events.events as events
from api_services.redis.functions import get_object_via_access_key
from databases import EndpointRestriction, Events
from api_configs.configs import Config
if valid_token := get_object_via_access_key(request=request):
endpoint_name = str(request.url).replace(str(request.base_url), "/")
endpoint_active = EndpointRestriction.filter_active(
EndpointRestriction.endpoint_name.ilike(f"%{endpoint_name}%")
).data[0]
if (
str(endpoint_name) in Config.INSECURE_PATHS
or str(endpoint_name) in Config.NOT_SECURE_PATHS
):
return valid_token
if "update" in endpoint_name:
endpoint_name = endpoint_name.split("update")[0] + "update"
endpoint_active = EndpointRestriction.filter_one(
EndpointRestriction.endpoint_name.ilike(f"%{endpoint_name}%"),
system=True,
).data
if not endpoint_active:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This endpoint is not active for this user, please contact your responsible company for further information.",
detail=f"This endpoint {endpoint_name} is not active for this user, please contact your responsible company for further information.",
)
if valid_token.user_type == 1:
if not valid_token.selected_company:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Selected company is not found in the token object.",
)
selected_event = Events.filter_active(
selected_event = Events.filter_one(
Events.endpoint_id == endpoint_active.id,
Events.id.in_(valid_token.selected_company.reachable_event_list_id),
)
if not selected_event.data:
).data
if not selected_event:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This endpoint requires event validation. Please contact your responsible company to use this event.",
)
selected_event = selected_event.data[0]
event_function_class = getattr(selected_event, "function_class", None)
event_function_code = getattr(selected_event, "function_code", None)
function_class = getattr(events, event_function_class, None)
@@ -57,14 +63,14 @@ def parse_token_object_to_dict(request: Request): # from requests import Reques
status_code=status.HTTP_418_IM_A_TEAPOT,
detail="Selected occupant is not found in the token object.",
)
selected_event = Events.filter_active(
selected_event = Events.filter_all(
Events.endpoint_id == endpoint_active.id,
Events.id.in_(valid_token.selected_occupant.reachable_event_list_id),
)
if not selected_event.data:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This endpoint requires event validation. Please contact your responsible company to use this event.",
detail=f"This endpoint {endpoint_name} requires event validation. Please contact your responsible company to use this event.",
)
selected_event = selected_event.data[0]
event_function_class = getattr(selected_event, "function_class", None)
@@ -78,7 +84,7 @@ def parse_token_object_to_dict(request: Request): # from requests import Reques
if not active_function:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This endpoint requires event validation. Please contact your responsible company to use this event.",
detail=f"This endpoint {endpoint_name} requires event validation. Please contact your responsible company to use this event.",
)
valid_token.available_event = active_function
return valid_token

View File

@@ -1,9 +1,6 @@
import json
import typing
from fastapi import status
from fastapi.exceptions import HTTPException
from .conn import redis_cli
from api_configs import Auth
@@ -13,6 +10,9 @@ from api_objects import EmployeeTokenObject, OccupantTokenObject
def get_object_via_access_key(
request,
) -> typing.Union[EmployeeTokenObject, OccupantTokenObject, None]:
from fastapi import status
from fastapi.exceptions import HTTPException
if not hasattr(request, "headers"):
raise HTTPException(
status_code=401,
@@ -28,7 +28,6 @@ def get_object_via_access_key(
already_tokens = redis_cli.scan_iter(
match=str(request.headers.get(Auth.ACCESS_TOKEN_TAG) + ":*")
)
if already_tokens := list(already_tokens):
try:
if redis_object := json.loads(
@@ -63,9 +62,11 @@ def get_object_via_access_key(
)
def get_object_via_user_uu_id(user_id: str) -> typing.Union[list, None]:
def get_object_via_user_uu_id(user_id: str) -> typing.Union[dict, None]:
already_tokens = redis_cli.scan_iter(match=str("*:" + str(user_id)))
already_tokens = list(already_tokens)
if list(already_tokens):
return list(already_tokens)
return None
already_tokens_list, already_tokens_dict = [], {}
for already_token in already_tokens:
redis_object = json.loads(redis_cli.get(already_token) or {})
already_tokens_list.append(redis_object)
already_tokens_dict[already_token.decode()] = redis_object
return already_tokens_dict

View File

@@ -1,58 +1,147 @@
from typing import Any, Union
from fastapi import status
from fastapi.responses import JSONResponse
from databases.sql_models.response_model import AlchemyResponse
class AlchemyJsonResponse:
status_code: status
message: str
result: AlchemyResponse
completed: bool
filter_attributes: Any = None
response_model: Any = None
cls_object: Any = None
@staticmethod
def get_total_count(cls_object, filter_attributes):
total_page_number = 1
count_to_use = cls_object.total_count / int(filter_attributes.size)
if cls_object.total_count > int(filter_attributes.size):
if isinstance(count_to_use, int):
total_page_number = round(count_to_use, 0)
elif isinstance(count_to_use, float):
total_page_number = round(count_to_use, 0) + 1
return total_page_number
def __new__(
cls,
message: str,
status_code: str = "HTTP_200_OK",
result: Union[Any, list] = None,
completed: bool = True,
response_model: Any = None,
cls_object: Any = None,
filter_attributes: Any = None,
):
cls.status_code = getattr(status, status_code, "HTTP_200_OK")
cls.message = message
cls.result = result
cls.completed = completed
cls.response_model = response_model
def return_json_response_from_alchemy(
response, cls_obj=None, pagination=None, response_model=None
):
enums = cls_obj.__enums__ if cls_obj else []
if response.count:
total_count = response.query.limit(None).offset(None).count()
total_page_number = round(total_count / int(pagination.size), 0) + 1
pagination_dict = {
"size/total_count": [response.count, total_count],
"page/total_page": [pagination.page, total_page_number],
"order_field": pagination.order_field,
"order_type": pagination.order_type,
"size/total_count": [10, 10],
"page/total_page": [1, 1],
"order_field": "id",
"order_type": "asc",
}
if filter_attributes:
total_page_number = cls.get_total_count(cls_object, filter_attributes)
pagination_dict = {
"size/total_count": [filter_attributes.size, cls_object.total_count],
"page/total_page": [filter_attributes.page, total_page_number],
"order_field": filter_attributes.order_field,
"order_type": filter_attributes.order_type,
}
if isinstance(cls.result, dict) or isinstance(cls.result, list):
return JSONResponse(
status_code=cls.status_code,
content=dict(
total_count=len(cls.result),
count=len(cls.result),
pagination=pagination_dict,
completed=cls.completed,
message=cls.message,
data=cls.result,
),
)
first_item = getattr(cls.result, "data", None)
if not first_item:
return JSONResponse(
status_code=cls.status_code,
content=dict(
total_count=0,
count=0,
pagination=pagination_dict,
completed=cls.completed,
message=cls.message,
data=[],
),
)
if cls.result.first:
return JSONResponse(
status_code=cls.status_code,
content=dict(
total_count=1,
count=1,
pagination=pagination_dict,
completed=cls.completed,
message=cls.message,
data=cls.result.data.get_dict(),
),
)
if not cls.result.get(1).filter_attr and isinstance(cls.result.data, list):
counts = cls.result.count
return JSONResponse(
status_code=cls.status_code,
content=dict(
total_count=counts,
count=counts,
pagination=pagination_dict,
completed=cls.completed,
message=cls.message,
data=[result_data.get_dict() for result_data in cls.result.data],
),
)
# filter_model = cls.result.get(1).filter_attr
total_count = cls.result.get(1).query.limit(None).offset(None).count()
total_page_number = cls.get_total_count(cls_object, filter_attributes)
pagination_dict = {
"size/total_count": [filter_attributes.size, cls_object.total_count],
"page/total_page": [filter_attributes.page, total_page_number],
"order_field": filter_attributes.order_field,
"order_type": filter_attributes.order_type,
}
include_joins = dict(
include_joins=pagination.include_joins if pagination.include_joins else None
include_joins=(
filter_attributes.include_joins
if filter_attributes.include_joins
else []
)
)
if not isinstance(response.data[0], dict):
data = []
for obj in response.data:
data_object = obj.get_dict(**include_joins)
if response_model:
data_object = response_model(
**obj.get_dict(**include_joins)
).model_dump()
data.append(data_object)
else:
data = []
for obj in response.data:
data_object = obj
if response_model:
data_object = response_model(**obj).model_dump()
data.append(data_object)
data = []
for data_object in cls.result.data:
data_dict = data_object.get_dict(include_joins=include_joins)
if cls.response_model:
data_dict = cls.response_model(
**data_object.get_dict(include_joins=include_joins)
).dump()
data.append(data_dict)
return JSONResponse(
status_code=status.HTTP_200_OK,
status_code=cls.status_code,
content=dict(
total_count=total_count or 1,
count=cls.result.count,
pagination=pagination_dict,
message="Found records are listed",
completed=True,
message=cls.message,
completed=cls.completed,
data=data,
),
)
return JSONResponse(
status_code=status.HTTP_404_NOT_FOUND,
content=dict(
total_count=0,
count=0,
message="No record has found",
completed=False,
data=[],
),
)

View File

@@ -20,4 +20,3 @@ class BaseModelRegular(BaseModel):
def dump(self):
return self.model_dump()

View File

@@ -1,15 +1,20 @@
from .core_request_validations import (
ListOptions,
EndpointValidation,
PydanticBaseModel,
PatchRecord,
EndpointPydantic,
BaseModelRegular,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
from .address import (
InsertAddress,
UpdateAddress,
UpdatePostCode,
InsertPostCode,
SearchAddress
SearchAddress,
)
from .application import (
SingleEnumUUID,
@@ -34,6 +39,11 @@ from .authentication import (
OccupantSelection,
EmployeeSelection,
)
from .account_records import (
InsertAccountRecord,
UpdateAccountRecord,
)
from .build_living_space import (
InsertBuildLivingSpace,
UpdateBuildLivingSpace,
@@ -87,27 +97,30 @@ from .employee import (
UpdateCompanyDuty,
)
from .events import (
CreateEvents,
# CreateEvents,
RegisterEvents2Employee,
RegisterEvents2Occupant,
)
from .people import (
UpdatePerson,
InsertPerson,
ResponsePersonSalesMange,
)
from .project_decision_book import (
InsertBuildDecisionBookProjectItems,
UpdateBuildDecisionBookProjectItems,
InsertBuildDecisionBookProjectItemDebits,
UpdateBuildDecisionBookProjectItemDebits,
InsertBuildDecisionBookProjects,
UpdateBuildDecisionBookProjects,
InsertBuildDecisionBookProjectPerson,
UpdateBuildDecisionBookProjectPerson,
InsertBuildDecisionBookProjectItems,
UpdateBuildDecisionBookProjectItems,
ApprovalsBuildDecisionBookProjects,
)
from .rules import (
UpdateEndpointAccess,
UpdateEndpointAccessList,
InsertEndpointAccess,
CheckEndpointAccess,
)
from .services import (
RegisterServices2Employee,
@@ -121,9 +134,9 @@ from .user import (
InsertUsers,
UpdateUsers,
QueryUsers,
ActiveUsers,
ListUsers,
DeleteUsers,
# ActiveUsers,
# ListUsers,
# DeleteUsers,
)
from .modules import (
RegisterModules2Occupant,
@@ -133,11 +146,17 @@ from .modules import (
__all__ = [
"ListOptions",
"EndpointValidation",
"PydanticBaseModelValidation",
"CrudRecordValidation",
"CrudRecords",
"PydanticBaseModel",
"PatchRecord",
"EndpointPydantic",
"BaseModelRegular",
"InsertAddress",
"UpdateAddress",
"UpdatePostCode",
"InsertPostCode",
"SearchAddress",
"SingleEnumUUID",
@@ -157,6 +176,8 @@ __all__ = [
"CreatePassword",
"OccupantSelection",
"EmployeeSelection",
"InsertAccountRecord",
"UpdateAccountRecord",
"InsertBuildLivingSpace",
"UpdateBuildLivingSpace",
"InsertBuildParts",
@@ -195,21 +216,23 @@ __all__ = [
"InsertCompanyDuty",
"UpdateCompanyEmployeesSalaries",
"UpdateCompanyDuty",
"CreateEvents",
"RegisterEvents2Employee",
"RegisterEvents2Occupant",
"UpdatePerson",
"InsertPerson",
"ResponsePersonSalesMange",
"InsertBuildDecisionBookProjectItems",
"UpdateBuildDecisionBookProjectItems",
"ApprovalsBuildDecisionBookProjects",
"InsertBuildDecisionBookProjectItemDebits",
"UpdateBuildDecisionBookProjectItemDebits",
"InsertBuildDecisionBookProjects",
"UpdateBuildDecisionBookProjects",
"InsertBuildDecisionBookProjectPerson",
"UpdateBuildDecisionBookProjectPerson",
"UpdateEndpointAccess",
"UpdateEndpointAccessList",
"InsertEndpointAccess",
"CheckEndpointAccess",
"RegisterServices2Employee",
"RegisterServices2Occupant",
"InsertStaff",
@@ -217,9 +240,6 @@ __all__ = [
"InsertUsers",
"UpdateUsers",
"QueryUsers",
"ActiveUsers",
"ListUsers",
"DeleteUsers",
"RegisterModules2Occupant",
"RegisterModules2Employee",
]

View File

@@ -0,0 +1,163 @@
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
ListOptions,
)
from typing import Optional
class AccountValidation:
tr = {
"iban": "IBAN Numarası",
"bank_date": "Bank Tarih",
"currency_value": "Para Değeri",
"bank_balance": "Banka Bakiye",
"currency": "Para Birimi",
"additional_balance": "Ek Bakiye",
"channel_branch": "Kanal Şubesi",
"process_name": "İşlem Adı",
"process_type": "İşlem Tipi",
"process_comment": "İşlem Yorum",
"bank_reference_code": "Banka Referans Kodu",
"add_comment_note": "Yorum Not",
"is_receipt_mail_send": "Fiş Mail Gönderildi",
"found_from": "Bulunduğu Yer",
"similarity": "Benzerlik",
"remainder_balance": "Kalan Bakiye",
"bank_date_y": "Bank Tarih Yıl",
"bank_date_m": "Bank Tarih Ay",
"bank_date_w": "Bank Tarih Hafta",
"bank_date_d": "Bank Tarih Gün",
"approving_accounting_record": "Onaylayan Muhasebe Kaydı",
"accounting_receipt_date": "Muhasebe Fiş Tarihi",
"accounting_receipt_number": "Muhasebe Fiş Numarası",
"approved_record": "Onaylanmış Kayıt",
"import_file_name": "İçe Aktarım Dosya Adı",
"receive_debit_uu_id": "Alacak UUID",
"budget_type_uu_id": "Bütçe Tipi UUID",
"company_uu_id": "Şirket UUID",
"send_company_uu_id": "Gönderen Şirket UUID",
"customer_id": "Müşteri ID",
"customer_uu_id": "Müşteri UUID",
"send_person_uu_id": "Gönderen Kişi UUID",
"approving_accounting_person_uu_id": "Onaylayan Muhasebe Kişi UUID",
"build_parts_uu_id": "Daire UUID",
"build_decision_book_uu_id": "Karar Defteri UUID",
}
en = {
"iban": "IBAN Number",
"bank_date": "Bank Date",
"currency_value": "Currency Value",
"bank_balance": "Bank Balance",
"currency": "Currency",
"additional_balance": "Additional Balance",
"channel_branch": "Channel Branch",
"process_name": "Process Name",
"process_type": "Process Type",
"process_comment": "Process Comment",
"bank_reference_code": "Bank Reference Code",
"add_comment_note": "Comment Note",
"is_receipt_mail_send": "Receipt Mail Send",
"found_from": "Found From",
"similarity": "Similarity",
"remainder_balance": "Remainder Balance",
"bank_date_y": "Bank Date Year",
"bank_date_m": "Bank Date Month",
"bank_date_w": "Bank Date Week",
"bank_date_d": "Bank Date Day",
"approving_accounting_record": "Approving Accounting Record",
"accounting_receipt_date": "Accounting Receipt Date",
"accounting_receipt_number": "Accounting Receipt Number",
"approved_record": "Approved Record",
"import_file_name": "Import File Name",
"receive_debit_uu_id": "Receive Debit UUID",
"budget_type_uu_id": "Budget Type UUID",
"company_uu_id": "Company UUID",
"send_company_uu_id": "Send Company UUID",
"customer_id": "Customer ID",
"customer_uu_id": "Customer UUID",
"send_person_uu_id": "Send Person UUID",
"approving_accounting_person_uu_id": "Approving Accounting Person UUID",
"build_parts_uu_id": "Build Parts UUID",
"build_decision_book_uu_id": "Build Decision Book UUID",
}
class InsertAccountRecord(BaseModelRegular, AccountValidation):
iban: str
bank_date: str
currency_value: float
bank_balance: float
currency: str
additional_balance: float
channel_branch: str
process_name: str
process_type: str
process_comment: str
bank_reference_code: str
add_comment_note: Optional[str] = None
is_receipt_mail_send: Optional[bool] = None
found_from: Optional[str] = None
similarity: Optional[float] = None
remainder_balance: Optional[float] = None
bank_date_y: Optional[int] = None
bank_date_m: Optional[int] = None
bank_date_w: Optional[int] = None
bank_date_d: Optional[int] = None
approving_accounting_record: Optional[bool] = None
accounting_receipt_date: Optional[str] = None
accounting_receipt_number: Optional[int] = None
approved_record: Optional[bool] = None
import_file_name: Optional[str] = None
# receive_debit_uu_id: Optional[str] = None
budget_type_uu_id: Optional[str] = None
company_uu_id: Optional[str] = None
send_company_uu_id: Optional[str] = None
customer_id: Optional[str] = None
customer_uu_id: Optional[str] = None
send_person_uu_id: Optional[str] = None
approving_accounting_person_uu_id: Optional[str] = None
build_parts_uu_id: Optional[str] = None
build_decision_book_uu_id: Optional[str] = None
class UpdateAccountRecord(PydanticBaseModel, AccountValidation):
iban: Optional[str] = None
bank_date: Optional[str] = None
currency_value: Optional[float] = None
bank_balance: Optional[float] = None
currency: Optional[str] = None
additional_balance: Optional[float] = None
channel_branch: Optional[str] = None
process_name: Optional[str] = None
process_type: Optional[str] = None
process_comment: Optional[str] = None
bank_reference_code: Optional[str] = None
add_comment_note: Optional[str] = None
is_receipt_mail_send: Optional[bool] = None
found_from: Optional[str] = None
similarity: Optional[float] = None
remainder_balance: Optional[float] = None
bank_date_y: Optional[int] = None
bank_date_m: Optional[int] = None
bank_date_w: Optional[int] = None
bank_date_d: Optional[int] = None
approving_accounting_record: Optional[bool] = None
accounting_receipt_date: Optional[str] = None
accounting_receipt_number: Optional[int] = None
approved_record: Optional[bool] = None
import_file_name: Optional[str] = None
receive_debit_uu_id: Optional[str] = None
budget_type_uu_id: Optional[str] = None
company_uu_id: Optional[str] = None
send_company_uu_id: Optional[str] = None
customer_id: Optional[str] = None
customer_uu_id: Optional[str] = None
send_person_uu_id: Optional[str] = None
approving_accounting_person_uu_id: Optional[str] = None
build_parts_uu_id: Optional[str] = None
build_decision_book_uu_id: Optional[str] = None

View File

@@ -6,17 +6,65 @@ from api_validations.validations_request import (
from typing import Optional
class InsertPostCode(PydanticBaseModel):
class PostCodeValidation:
tr = {
"post_code": "Posta Kodu",
"street_uu_id": "Sokak UUID",
}
en = {
"post_code": "Post Code",
"street_uu_id": "Street UUID",
}
class InsertPostCode(BaseModelRegular, PostCodeValidation):
street_uu_id: str
post_code: str
class SearchAddress(PydanticBaseModel):
class UpdatePostCode(PydanticBaseModel, PostCodeValidation):
street_uu_id: Optional[str] = None
post_code: Optional[str] = None
class SearchAddressValidation:
tr = {
"search": "Ara",
"list_options": "Liste Seçenekleri",
}
en = {
"search": "Search",
"list_options": "List Options",
}
class SearchAddress(PydanticBaseModel, SearchAddressValidation):
search: str
list_options: ListOptions
class InsertStreet(PydanticBaseModel):
class StreetValidation:
tr = {
"street_code": "Sokak Kodu",
"street_name": "Sokak Adı",
"postcode": "Posta Kodu",
"type_code": "Tip Kodu",
"type_description": "Tip Açıklaması",
"gov_code": "Devlet Kodu",
"address_geographic_uu_id": "Coğrafi UUID",
}
en = {
"street_code": "Street Code",
"street_name": "Street Name",
"postcode": "Post Code",
"type_code": "Type Code",
"type_description": "Type Description",
"gov_code": "Government Code",
"address_geographic_uu_id": "Address Geographic UUID",
}
class InsertStreet(PydanticBaseModel, StreetValidation):
street_code: str
street_name: str
postcode: str
@@ -27,7 +75,32 @@ class InsertStreet(PydanticBaseModel):
address_geographic_uu_id: Optional[str] = None
class InsertAddress(PydanticBaseModel):
class AddressValidation:
tr = {
"post_code_uu_id": "Posta Kodu UUID",
"comment_address": "Adres Yorumu",
"letter_address": "Mektup Adresi",
"build_number": "Bina Numarası",
"door_number": "Kapı Numarası",
"floor_number": "Kat Numarası",
"short_letter_address": "Kısa Mektup Adresi",
"latitude": "Enlem",
"longitude": "Boylam",
}
en = {
"post_code_uu_id": "Post Code UUID",
"comment_address": "Address Comment",
"letter_address": "Letter Address",
"build_number": "Build Number",
"door_number": "Door Number",
"floor_number": "Floor Number",
"short_letter_address": "Short Letter Address",
"latitude": "Latitude",
"longitude": "Longitude",
}
class InsertAddress(BaseModelRegular, AddressValidation):
post_code_uu_id: str
comment_address: Optional[str] = None
@@ -42,14 +115,16 @@ class InsertAddress(PydanticBaseModel):
longitude: Optional[float] = None
class _UpdateAddress(PydanticBaseModel):
...
# country_code: Optional[str] = None
# city: Optional[str] = None
# district: Optional[str] = None
# b_state: Optional[str] = None
# neighborhood: Optional[str] = None
# street: Optional[str] = None
# postcode: Optional[str] = None
# latitude: Optional[float] = None
# longitude: Optional[float] = None
class UpdateAddress(PydanticBaseModel, AddressValidation):
post_code_uu_id: Optional[str] = None
comment_address: Optional[str] = None
letter_address: Optional[str] = None
build_number: Optional[str] = None
door_number: Optional[str] = None
floor_number: Optional[str] = None
short_letter_address: Optional[str] = None
latitude: Optional[float] = None
longitude: Optional[float] = None

View File

@@ -1,22 +1,69 @@
from api_validations.core_validations import BaseModelRegular
class SingleEnumClassKeyValidation:
tr = {
"class_name": "Sınıf Adı",
"key_name": "Anahtar Adı",
}
en = {
"class_name": "Class Name",
"key_name": "Key Name",
}
class SingleEnumClassKey(BaseModelRegular):
class_name: str
key_name: str
class SingleEnumUUIDValidation:
tr = {
"uu_id": "UUID",
}
en = {
"uu_id": "UUID",
}
class SingleEnumUUID(BaseModelRegular):
uu_id: str
class SingleEnumOnlyClassValidation:
tr = {
"class_name": "Sınıf Adı",
}
en = {
"class_name": "Class Name",
}
class SingleEnumOnlyClass(BaseModelRegular):
class_name: str
class SingleOccupantTypeClassKeyValidation:
tr = {
"type_code": "Tip Kodu",
}
en = {
"type_code": "Type Code",
}
class SingleOccupantTypeClassKey(BaseModelRegular):
type_code: str
class SingleOccupantTypeUUIDValidation:
tr = {
"uu_id": "Görev UUID",
}
en = {
"uu_id": "Occupant UUID",
}
class SingleOccupantTypeUUID(BaseModelRegular):
uu_id: str

View File

@@ -5,7 +5,33 @@ from api_validations.validations_request import (
ListOptions,
)
class InsertBuildArea(BaseModelRegular):
class BuildAreaValidation:
tr = {
"area_name": "Alan Adı",
"area_code": "Alan Kodu",
"area_type": "Alan Tipi",
"area_direction": "Alan Yönü",
"area_gross_size": "Brüt Alan",
"area_net_size": "Net Alan",
"width": "Genişlik",
"size": "En",
}
en = {
"area_name": "Area Name",
"area_code": "Area Code",
"area_type": "Area Type",
"area_direction": "Area Direction",
"area_gross_size": "Gross Size",
"area_net_size": "Net Size",
"width": "Width",
"size": "Size",
}
class InsertBuildArea(BaseModelRegular, BuildAreaValidation):
build_uu_id: str
area_name: str
area_code: str
@@ -17,7 +43,8 @@ class InsertBuildArea(BaseModelRegular):
size: Optional[int] = None
class UpdateBuildArea(PydanticBaseModel):
class UpdateBuildArea(PydanticBaseModel, BuildAreaValidation):
area_name: Optional[str] = None
area_code: Optional[str] = None
area_type: Optional[str] = None
@@ -28,12 +55,23 @@ class UpdateBuildArea(PydanticBaseModel):
size: Optional[int] = None
class InsertBuildSites(BaseModelRegular):
class BuildSites:
tr = {"address_uu_id": "Adres UU ID", "site_name": "Site Adı", "site_no": "Site No"}
en = {
"address_uu_id": "Address UU ID",
"site_name": "Site Name",
"site_no": "Site No",
}
class InsertBuildSites(BaseModelRegular, BuildSites):
address_uu_id: str
site_name: str
site_no: str
class UpdateBuildSites(PydanticBaseModel):
class UpdateBuildSites(PydanticBaseModel, BuildSites):
site_name: Optional[str] = None
site_no: Optional[str] = None

View File

@@ -6,44 +6,103 @@ from api_validations.validations_request import (
from typing import Optional
from pydantic import BaseModel
class ChangePassword(BaseModelRegular):
domain_name: str
access_key: str
class ChangePasswordValidation:
tr = {"old_password": "Eski Şifre", "new_password": "Yeni Şifre"}
en = {"old_password": "Old Password", "new_password": "New Password"}
class ChangePassword(BaseModelRegular, ChangePasswordValidation):
old_password: str
new_password: str
class CreatePassword(BaseModelRegular):
class CreatePasswordValidation:
tr = {
"password_token": "Şifre Token",
"password": "Şifre",
"re_password": "Şifre Tekrar",
}
en = {
"password_token": "Password Token",
"password": "Password",
"re_password": "Re-Password",
}
class CreatePassword(BaseModelRegular, CreatePasswordValidation):
password_token: str
password: str
re_password: str
class OccupantSelection(BaseModel):
class OccupantSelectionValidation:
tr = {"occupant_uu_id": "Kiracı UU ID", "build_part_uu_id": "Bölüm UU ID"}
en = {"occupant_uu_id": "Occupant UU ID", "build_part_uu_id": "Build Part UU ID"}
class OccupantSelection(BaseModel, OccupantSelectionValidation):
occupant_uu_id: str
build_part_uu_id: str
class EmployeeSelection(BaseModel):
class EmployeeSelectionValidation:
tr = {"company_uu_id": "Şirket UU ID"}
en = {"company_uu_id": "Company UU ID"}
class EmployeeSelection(BaseModel, EmployeeSelectionValidation):
company_uu_id: str
class Login(BaseModelRegular):
class LoginValidation:
tr = {
"domain": "Domain",
"access_key": "Erişim Anahtarı",
"password": "Şifre",
"remember_me": "Beni Hatırla",
}
en = {
"domain": "Domain",
"access_key": "Access Key",
"password": "Password",
"remember_me": "Remember Me",
}
class Login(BaseModelRegular, LoginValidation):
domain: str
access_key: str
password: str
remember_me: Optional[bool] = False
class Logout(BaseModelRegular):
class LogoutValidation:
tr = {"domain": "Domain"}
en = {"domain": "Domain"}
class Logout(BaseModelRegular, LogoutValidation):
domain: str
class Remember(BaseModelRegular):
class RememberValidation:
tr = {"domain": "Domain", "refresh_token": "Yenileme Anahtarı"}
en = {"domain": "Domain", "refresh_token": "Refresh Token"}
class Remember(BaseModelRegular, RememberValidation):
domain: str
refresh_token: str
class Forgot(BaseModelRegular):
class ForgotValidation:
tr = {"domain": "Domain", "access_key": "Erişim Anahtarı"}
en = {"domain": "Domain", "access_key": "Access Key"}
class Forgot(BaseModelRegular, ForgotValidation):
domain: str
access_key: str

View File

@@ -2,17 +2,52 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class InsertBuildLivingSpace(BaseModelRegular):
class BuildLivingSpaceValidation:
tr = {
"person_uu_id": "Kişi UUID'si",
"build_parts_uu_id": "Bina UUID'si",
"occupant_type_uu_id": "Mülk Sahibi UUID'si",
"expiry_starts": "Geçerlilik Başlangıç Tarihi",
"expiry_ends": "Geçerlilik Bitiş Tarihi",
}
en = {
"person_uu_id": "Person UUID",
"build_parts_uu_id": "Build UUID",
"occupant_type_uu_id": "Occupant UUID",
"expiry_starts": "Expiry Starts",
"expiry_ends": "Expiry Ends",
}
class PydanticBaseModelValidationUpdate:
tr = {
**PydanticBaseModelValidation.tr,
"is_tenant_live": "Kiracı mı?",
"build_parts_uu_id": "Bina UUID'si",
"person_uu_id": "Kişi UUID'si",
}
en = {
**PydanticBaseModelValidation.en,
"is_tenant_live": "Is Tenant Live?",
"build_parts_uu_id": "Build UUID",
"person_uu_id": "Person UUID",
}
class InsertBuildLivingSpace(BaseModelRegular, BuildLivingSpaceValidation):
person_uu_id: str
build_parts_uu_id: str
occupant_type_uu_id: str
expiry_starts: str
expiry_ends: Optional[str] = None
class UpdateBuildLivingSpace(PydanticBaseModel):
class UpdateBuildLivingSpace(PydanticBaseModel, BuildLivingSpaceValidation):
is_tenant_live: Optional[bool] = None
build_parts_uu_id: Optional[str] = None
person_uu_id: Optional[str] = None

View File

@@ -2,20 +2,81 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class UpdateBuildTypes(PydanticBaseModel): ...
class BuildTypesUpdateValidation:
tr = {
**PydanticBaseModelValidation.tr,
"function_code": "Fonksiyon Kodu",
"type_code": "Tip Kodu",
"lang": "Dil",
"type_name": "Tip Adı",
}
en = {
**PydanticBaseModelValidation.en,
"function_code": "Function Code",
"type_code": "Type Code",
"lang": "Language",
"type_name": "Type Name",
}
class InsertBuildTypes(PydanticBaseModel):
class BuildTypesValidation:
tr = {
"function_code": "Fonksiyon Kodu",
"type_code": "Tip Kodu",
"lang": "Dil",
"type_name": "Tip Adı",
}
en = {
"function_code": "Function Code",
"type_code": "Type Code",
"lang": "Language",
"type_name": "Type Name",
}
class InsertBuildTypes(BaseModelRegular, BuildTypesValidation):
function_code: str
type_code: str
lang: str
type_name: str
class InsertBuildParts(PydanticBaseModel):
class UpdateBuildTypes(PydanticBaseModel, BuildTypesUpdateValidation): ...
class BuildPartsValidation:
tr = {
"address_gov_code": "Adres İl Kodu",
"part_no": "Daire No",
"part_level": "Daire Seviyesi",
"build_part_type_uu_id": "Bina Daire Tipi UUID'si",
"part_code": "Daire Kodu",
"part_gross_size": "Daire Brüt Alanı",
"part_net_size": "Daire Net Alanı",
"default_accessory": "Varsayılan Aksesuar",
"human_livable": "İnsan Yaşanabilir",
"part_direction": "Daire Yönü",
}
en = {
"address_gov_code": "Address Gov Code",
"part_no": "Flat No",
"part_level": "Flat Level",
"build_part_type_uu_id": "Build Flat Type UUID",
"part_code": "Flat Code",
"part_gross_size": "Flat Gross Size",
"part_net_size": "Flat Net Size",
"default_accessory": "Default Accessory",
"human_livable": "Human Livable",
"part_direction": "Flat Direction",
}
class InsertBuildParts(BaseModelRegular, BuildPartsValidation):
build_uu_id: str
address_gov_code: str
part_no: int
@@ -27,12 +88,43 @@ class InsertBuildParts(PydanticBaseModel):
default_accessory: Optional[str] = None
human_livable: Optional[bool] = False
part_direction_uu_id: Optional[str] = None
# current_owner_person_uu_id: Optional[str] = None
# current_tenant_person_uu_id: Optional[str] = None
ref_id: Optional[str] = None
class UpdateBuildParts(PydanticBaseModel):
class UpdateBuildPartsValidation:
tr = {
**PydanticBaseModelValidation.tr,
"address_gov_code": "Adres İl Kodu",
"part_no": "Daire No",
"part_level": "Daire Seviyesi",
"build_part_type_uu_id": "Bina Daire Tipi UUID'si",
"part_code": "Daire Kodu",
"part_gross_size": "Daire Brüt Alanı",
"part_net_size": "Daire Net Alanı",
"default_accessory": "Varsayılan Aksesuar",
"human_livable": "İnsan Yaşanabilir",
"part_direction": "Daire Yönü",
"current_owner_person_uu_id": "Mevcut Sahip Kişi UUID'si",
"current_tenant_person_uu_id": "Mevcut Kiracı Kişi UUID'si",
}
en = {
**PydanticBaseModelValidation.en,
"address_gov_code": "Address Gov Code",
"part_no": "Flat No",
"part_level": "Flat Level",
"build_part_type_uu_id": "Build Flat Type UUID",
"part_code": "Flat Code",
"part_gross_size": "Flat Gross Size",
"part_net_size": "Flat Net Size",
"default_accessory": "Default Accessory",
"human_livable": "Human Livable",
"part_direction": "Flat Direction",
"current_owner_person_uu_id": "Current Owner Person UUID",
"current_tenant_person_uu_id": "Current Tenant Person UUID",
}
class UpdateBuildParts(PydanticBaseModel, UpdateBuildPartsValidation):
address_gov_code: Optional[str] = None
part_no: Optional[int] = None
part_level: Optional[int] = None

View File

@@ -1,19 +1,66 @@
from typing import Optional
from datetime import datetime
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
ListOptions,
PydanticBaseModelValidation,
CrudRecordValidation,
)
class InsertBuild(PydanticBaseModel):
class BuildValidation:
tr = {
**CrudRecordValidation.tr,
"gov_address_code": "Devlet Adres Kodu",
"build_name": "Bina Adı",
"build_types_uu_id": "Bina Tipi",
"build_no": "Bina No",
"max_floor": "Kat Sayısı",
"underground_floor": "Bodrum Kat Sayısı",
"address_uu_id": "Adres",
"build_date": "Yapım Tarihi",
"decision_period_date": "Karar Tarihi",
"tax_no": "Vergi No",
"lift_count": "Asansör Sayısı",
"heating_system": "Isıtma Sistemi",
"cooling_system": "Soğutma Sistemi",
"hot_water_system": "Sıcak Su Sistemi",
"block_service_man_count": "Hizmet Görevlisi Sayısı",
"security_service_man_count": "Güvenlik Görevlisi Sayısı",
"garage_count": "Garaj Sayısı",
}
en = {
**CrudRecordValidation.en,
"gov_address_code": "Government Address Code",
"build_name": "Building Name",
"build_types_uu_id": "Building Type",
"build_no": "Building No",
"max_floor": "Number of Floors",
"underground_floor": "Number of Basement Floors",
"address_uu_id": "Address",
"build_date": "Construction Date",
"decision_period_date": "Decision Date",
"tax_no": "Tax No",
"lift_count": "Number of Elevators",
"heating_system": "Heating System",
"cooling_system": "Cooling System",
"hot_water_system": "Hot Water System",
"block_service_man_count": "Number of Service Officers",
"security_service_man_count": "Number of Security Officers",
"garage_count": "Number of Garages",
}
class InsertBuild(BaseModelRegular, BuildValidation):
gov_address_code: str
build_name: str
build_types_uu_id: str
max_floor: int
underground_floor: int
address_uu_id: str
build_date: str
decision_period_date: str
build_date: datetime
decision_period_date: datetime
tax_no: Optional[str] = None
lift_count: Optional[int] = None
@@ -25,14 +72,25 @@ class InsertBuild(PydanticBaseModel):
garage_count: Optional[int] = None
class UpdateBuild(PydanticBaseModel):
class BuildUpdateValidation:
tr = {
**BuildValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**BuildValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuild(PydanticBaseModel, BuildUpdateValidation):
gov_address_code: Optional[str] = None
build_name: Optional[str] = None
build_no: Optional[str] = None
build_types: Optional[str] = None
build_types_uu_id: Optional[str] = None
max_floor: Optional[int] = None
underground_floor: Optional[int] = None
build_date: Optional[str] = None
build_date: Optional[datetime] = None
tax_no: Optional[str] = None
lift_count: Optional[int] = None
heating_system: Optional[bool] = None

View File

@@ -2,10 +2,26 @@ from typing import Optional, List
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class InsertCompany(PydanticBaseModel):
class CompanyValidation:
tr = {
"formal_name": "Resmi Ad",
"company_type": "Şirket Tipi",
"commercial_type": "Ticari Tip",
"tax_no": "Vergi No",
"public_name": "Halka Açık Ad",
"company_tag": "Şirket Etiketi",
"default_lang_type": "Varsayılan Dil Tipi",
"default_money_type": "Varsayılan Para Tipi",
"official_address_uu_id": "Resmi Adres UU ID",
}
class InsertCompany(BaseModelRegular, CompanyValidation):
formal_name: str
company_type: str
commercial_type: str
@@ -14,11 +30,22 @@ class InsertCompany(PydanticBaseModel):
company_tag: Optional[str] = None
default_lang_type: Optional[str] = None
default_money_type: Optional[str] = None
official_address_uu_id: Optional[int] = None
official_address_uu_id: Optional[str] = None
# parent_uu_id: Optional[int] = None
class UpdateCompany(PydanticBaseModel):
class CompanyUpdateValidation:
tr = {
**CompanyValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**CompanyValidation.tr,
**PydanticBaseModelValidation.en,
}
class UpdateCompany(PydanticBaseModel, CompanyUpdateValidation):
company_uu_id: str
public_name: Optional[str] = None
formal_name: Optional[str] = None
@@ -26,9 +53,23 @@ class UpdateCompany(PydanticBaseModel):
company_tag: Optional[str] = None
default_lang_type: Optional[str] = None
default_money_type: Optional[str] = None
official_address_uu_id: Optional[int] = None
official_address_uu_id: Optional[str] = None
class MatchCompany2Company(PydanticBaseModel):
class MatchCompany2CompanyValidation:
tr = {
**PydanticBaseModelValidation.tr,
"match_company_uu_id": "Eşleşen Şirket UU ID",
"duty_uu_id": "Görev UU ID",
}
en = {
**PydanticBaseModelValidation.en,
"match_company_uu_id": "Match Company UU ID",
"duty_uu_id": "Duty UU ID",
}
class MatchCompany2Company(PydanticBaseModel, MatchCompany2CompanyValidation):
match_company_uu_id: List[str]
duty_uu_id: str
show_only: Optional[bool] = None

View File

@@ -3,28 +3,110 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
class ListOptions(BaseModelRegular):
class ListOptionsValidation:
tr = {
"page": "Sayfa",
"size": "Boyut",
"order_field": "Sıralama Alanı",
"order_type": "Sıralama Türü",
"include_joins": "Alt İçerikleri",
"query": "Sorgu",
}
en = {
"page": "Page",
"size": "Size",
"order_field": "Order Field",
"order_type": "Order Type",
"include_joins": "Include Joins",
"query": "Query",
}
class ListOptions(BaseModelRegular, ListOptionsValidation):
page: Optional[int] = 1
size: Optional[int] = 10
order_field: Optional[str] = "id"
order_type: Optional[str] = "asc"
include_joins: Optional[list] = []
query: Optional[dict] = {}
include_joins: Optional[list] = None
query: Optional[dict] = None
class CrudRecordValidation:
tr = {
"uu_id": "UUID",
"created_at": "Oluşturulma Tarihi",
"updated_at": "Güncellenme Tarihi",
"created_by": "Oluşturan",
"updated_by": "Güncelleyen",
"confirmed_by": "Onaylayan",
"is_confirmed": "Onay",
"expiry_starts": "Geçerlilik Başlangıç Tarihi",
"expiry_ends": "Geçerlilik Bitiş Tarihi",
"active": "Aktif",
"is_notification_send": "Bildirim Gönderildi",
"is_email_send": "E-posta Gönderildi",
}
en = {
"uu_id": "UUID",
"created_at": "Created At",
"updated_at": "Updated At",
"created_by": "Created By",
"updated_by": "Updated By",
"confirmed_by": "Confirmed By",
"is_confirmed": "Confirmed",
"expiry_starts": "Expiry Starts",
"expiry_ends": "Expiry Ends",
"active": "Active",
"is_notification_send": "Notification Send",
"is_email_send": "Email Send",
}
class CrudRecords:
uu_id: Optional[str] = None
created_at: Optional[str] = None
updated_at: Optional[str] = None
created_by: Optional[str] = None
updated_by: Optional[str] = None
confirmed_by: Optional[str] = None
is_confirmed: Optional[bool] = None
active: Optional[bool] = None
is_notification_send: Optional[bool] = None
is_email_send: Optional[bool] = None
class PydanticBaseModelValidation:
tr = {
"active": "Aktif",
"deleted": "Silinmiş",
"expiry_starts": "Geçerlilik Başlangıç Tarihi",
"expiry_ends": "Geçerlilik Bitiş Tarihi",
"is_confirmed": "Onay",
}
en = {
"active": "Active",
"deleted": "Deleted",
"expiry_starts": "Expiry Starts",
"expiry_ends": "Expiry Ends",
"is_confirmed": "Confirmed",
}
class PydanticBaseModel(BaseModelRegular):
active: Optional[bool] = None
deleted: Optional[bool] = None
is_confirmed: Optional[bool] = None
expiry_starts: Optional[str] = None
expiry_ends: Optional[str] = None
# expiry_ends: Optional[str] = None
is_confirmed: Optional[bool] = None
class EndpointPydantic(BaseModelRegular):
data: Optional[dict] = None
data: Optional[dict] = {}
class EndpointValidation(BaseModelRegular):
endpoint: Optional[str] = None
class PatchRecord(BaseModelRegular):

View File

@@ -38,6 +38,7 @@ class ConvertField:
default_value = getattr(self.default_val, "field_default_value", None)
return matches_with, default_value
#
# def create_model_from_database(model_id: typing.Union[int, str]):
# if isinstance(model_id, int):
@@ -57,7 +58,7 @@ class ConvertField:
# detail=f"Pydantic class {selected_model.model_type} not found in database. Please add model to api.",
# )
#
# model_entities_records = ModelEntities.filter_active(
# model_entities_records = ModelEntities.filter_all(
# ModelEntities.model_id == selected_model.id
# ).data
#

View File

@@ -2,37 +2,126 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class DecisionBookDecisionBookInvitations(PydanticBaseModel):
class DecisionBookDecisionBookInvitationsValidation:
tr = {
"build_decision_book_uu_id": "Karar Defteri UUID",
"message": "Mesaj",
"planned_date": "Planlanan Tarih",
}
en = {
"build_decision_book_uu_id": "Decision Book UUID",
"message": "Message",
"planned_date": "Planned Date",
}
class DecisionBookDecisionBookInvitations(
BaseModelRegular, DecisionBookDecisionBookInvitationsValidation
):
build_decision_book_uu_id: str
message: str
planned_date: str
class DecisionBookDecisionBookInvitationsAttend(PydanticBaseModel):
class DecisionBookDecisionBookInvitationsAttendValidation:
tr = {
"token": "Token",
"is_attend": "Katılacak mı?",
}
en = {
"token": "Token",
"is_attend": "Is Attend?",
}
class DecisionBookDecisionBookInvitationsAttend(
BaseModelRegular, DecisionBookDecisionBookInvitationsAttendValidation
):
token: str
is_attend: bool
class DecisionBookDecisionBookInvitationsAssign(PydanticBaseModel):
class DecisionBookDecisionBookInvitationsAssignValidation:
tr = {
"token": "Token",
"build_living_space_uu_id": "Yapı Yaşam Alanı UUID",
"occupant_type_uu_id": "Sakin Tipi UUID",
}
en = {
"token": "Token",
"build_living_space_uu_id": "Build Living Space UUID",
"occupant_type_uu_id": "Occupant Type UUID",
}
class DecisionBookDecisionBookInvitationsAssign(
BaseModelRegular, DecisionBookDecisionBookInvitationsAssignValidation
):
token: str
build_living_space_uu_id: str
occupant_type_uu_id: str
class DecisionBookDecisionBookInvitationsUpdate(PydanticBaseModel):
class DecisionBookDecisionBookInvitationsUpdateValidation:
tr = {
**PydanticBaseModelValidation.tr,
"token": "Token",
"occupant_type_uu_id": "Sakin Tipi UUID",
}
en = {
**PydanticBaseModelValidation.en,
"token": "Token",
"occupant_type_uu_id": "Occupant Type UUID",
}
class DecisionBookDecisionBookInvitationsUpdate(
PydanticBaseModel, DecisionBookDecisionBookInvitationsUpdateValidation
):
token: str
occupant_type_uu_id: Optional[str] = None
class ListDecisionBook(PydanticBaseModel):
class ListDecisionBookValidation:
tr = {
"build_decision_book_uu_id": "Karar Defteri UUID",
}
en = {
"build_decision_book_uu_id": "Decision Book UUID",
}
class ListDecisionBook(ListOptions, ListDecisionBookValidation):
build_decision_book_uu_id: Optional[str] = None
class InsertDecisionBook(PydanticBaseModel):
class InsertDecisionBookValidation:
tr = {
**PydanticBaseModelValidation.tr,
"build_uu_id": "Yapı UUID",
"decision_type": "Karar Tipi",
"meeting_date": "Toplantı Tarihi",
"is_out_sourced": "Dış Kaynak mı?",
"resp_company_fix_wage": "Firma Sabit Ücreti",
"resp_company_uu_id": "Firma UUID",
}
en = {
**PydanticBaseModelValidation.en,
"build_uu_id": "Build UUID",
"decision_type": "Decision Type",
"meeting_date": "Meeting Date",
"is_out_sourced": "Is Out Sourced?",
"resp_company_fix_wage": "Company Fixed Wage",
"resp_company_uu_id": "Company UUID",
}
class InsertDecisionBook(PydanticBaseModel, InsertDecisionBookValidation):
build_uu_id: str
decision_type: str
meeting_date: str
@@ -42,12 +131,44 @@ class InsertDecisionBook(PydanticBaseModel):
resp_company_uu_id: Optional[str] = None
class InsertDecisionBookCompleted(PydanticBaseModel):
class InsertDecisionBookCompletedValidation:
tr = {
"build_decision_book_uu_id": "Karar Defteri UUID",
"meeting_completed_date": "Toplantı Tamamlanma Tarihi",
}
en = {
"build_decision_book_uu_id": "Decision Book UUID",
"meeting_completed_date": "Meeting Completed Date",
}
class InsertDecisionBookCompleted(
BaseModelRegular, InsertDecisionBookCompletedValidation
):
build_decision_book_uu_id: str
meeting_completed_date: str
class InsertDecisionBookPerson(PydanticBaseModel):
class InsertDecisionBookPersonValidation:
tr = {
"person_uu_id": "Kişi UUID",
"build_decision_book_uu_id": "Karar Defteri UUID",
"management_typecode_uu_id": "Yönetim Tipi UUID",
"dues_discount_approval_date": "Aidat İndirim Onay Tarihi",
"dues_fix_discount": "Aidat Sabit İndirim",
"dues_percent_discount": "Aidat Yüzde İndirim",
}
en = {
"person_uu_id": "Person UUID",
"build_decision_book_uu_id": "Decision Book UUID",
"management_typecode_uu_id": "Management Type UUID",
"dues_discount_approval_date": "Dues Discount Approval Date",
"dues_fix_discount": "Dues Fix Discount",
"dues_percent_discount": "Dues Percent Discount",
}
class InsertDecisionBookPerson(BaseModelRegular, InsertDecisionBookPersonValidation):
person_uu_id: str
build_decision_book_uu_id: str
management_typecode_uu_id: str
@@ -57,12 +178,67 @@ class InsertDecisionBookPerson(PydanticBaseModel):
dues_percent_discount: Optional[int] = None
class RemoveDecisionBookPerson(PydanticBaseModel):
class UpdateDecisionBookPersonValidation:
tr = {
**PydanticBaseModelValidation.tr,
"dues_fix_discount": "Aidat Sabit İndirim",
"dues_percent_discount": "Aidat Yüzde İndirim",
}
en = {
**PydanticBaseModelValidation.en,
"dues_fix_discount": "Dues Fix Discount",
"dues_percent_discount": "Dues Percent Discount",
}
class UpdateDecisionBookPerson(PydanticBaseModel, UpdateDecisionBookPersonValidation):
dues_fix_discount: Optional[float] = None
dues_percent_discount: Optional[int] = None
class RemoveDecisionBookPersonValidation:
tr = {
"person_uu_id": "Kişi UUID",
"build_decision_book_person_uu_id": "Karar Defteri Kişi UUID",
}
en = {
"person_uu_id": "Person UUID",
"build_decision_book_person_uu_id": "Decision Book Person UUID",
}
class RemoveDecisionBookPerson(PydanticBaseModel, RemoveDecisionBookPersonValidation):
person_uu_id: str
build_decision_book_person_uu_id: str
class UpdateDecisionBook(PydanticBaseModel):
class UpdateDecisionBookValidation:
tr = {
**PydanticBaseModelValidation.tr,
"decision_book_pdf_path": "Karar Defteri PDF Yolu",
"is_out_sourced": "Dış Kaynak mı?",
"contact_agreement_path": "İletişim Anlaşma Yolu",
"contact_agreement_date": "İletişim Anlaşma Tarihi",
"meeting_date": "Toplantı Tarihi",
"decision_type": "Karar Tipi",
"resp_company_fix_wage": "Firma Sabit Ücreti",
"resp_company_uu_id": "Firma UUID",
}
en = {
**PydanticBaseModelValidation.en,
"decision_book_pdf_path": "Decision Book PDF Path",
"is_out_sourced": "Is Out Sourced?",
"contact_agreement_path": "Contact Agreement Path",
"contact_agreement_date": "Contact Agreement Date",
"meeting_date": "Meeting Date",
"decision_type": "Decision Type",
"resp_company_fix_wage": "Company Fixed Wage",
"resp_company_uu_id": "Company UUID",
}
class UpdateDecisionBook(PydanticBaseModel, UpdateDecisionBookValidation):
decision_book_pdf_path: Optional[str] = None
is_out_sourced: Optional[bool] = None
contact_agreement_path: Optional[str] = None
@@ -74,34 +250,107 @@ class UpdateDecisionBook(PydanticBaseModel):
resp_company_uu_id: Optional[str] = None
class InsertBuildDecisionBookItems(PydanticBaseModel):
class InsertBuildDecisionBookItemsValidation:
tr = {
"token": "Token",
"info_type_uu_id": "Bilgi Tipi UUID",
"item_comment": "Öğe Yorumu / Açıklama",
"currency": "Para Birimi",
"unit_type": "Birim Tipi",
"debit_start_date": "Borç Başlangıç Tarihi",
"debit_end_date": "Borç Bitiş Tarihi",
"unit_price_is_fixed": "Birim Fiyat Sabit mi?",
"unit_price": "Birim Fiyat",
}
en = {
"token": "Token",
"info_type_uu_id": "Info Type UUID",
"item_comment": "Item Comment",
"currency": "Currency",
"unit_type": "Unit Type",
"debit_start_date": "Debit Start Date",
"debit_end_date": "Debit End Date",
"unit_price_is_fixed": "Unit Price Is Fixed?",
"unit_price": "Unit Price",
}
class InsertBuildDecisionBookItems(
BaseModelRegular, InsertBuildDecisionBookItemsValidation
):
token: str
info_type_uu_id: str
unit_price: float
item_comment: str
currency: Optional[str] = "TL"
unit_type: Optional[str] = "M2"
debit_start_date: Optional[str] = None
debit_end_date: Optional[str] = None
unit_price_is_fixed: Optional[bool] = False
item_comment: Optional[str] = None
unit_price: Optional[float] = 0.00
# build_decision_book_uu_id: str
# item_objection: Optional[str] = None
class UpdateBuildDecisionBookItems(PydanticBaseModel):
class UpdateBuildDecisionBookItemsValidation:
tr = {
**PydanticBaseModelValidation.tr,
"item_comment": "Öğe Yorumu / Açıklama",
"item_objection": "Öğe İtirazı",
}
en = {
**PydanticBaseModelValidation.en,
"item_comment": "Item Comment",
"item_objection": "Item Objection",
}
class UpdateBuildDecisionBookItems(
PydanticBaseModel, UpdateBuildDecisionBookItemsValidation
):
item_comment: Optional[str] = None
item_objection: Optional[str] = None
class InsertBuildDecisionBookItemDebits(PydanticBaseModel):
class InsertBuildDecisionBookItemDebitsValidation:
tr = {
"build_decision_book_item_uu_id": "Karar Defteri Öğe UUID",
"dues_values": "Aidat Değerleri",
}
en = {
"build_decision_book_item_uu_id": "Decision Book Item UUID",
"dues_values": "Dues Values",
}
class InsertBuildDecisionBookItemDebits(
BaseModelRegular, InsertBuildDecisionBookItemDebitsValidation
):
build_decision_book_item_uu_id: str
dues_values: dict
# dues_types_uu_id: str
# decision_taken: Optional[bool] = None
class UpdateBuildDecisionBookItemDebits(PydanticBaseModel):
class UpdateBuildDecisionBookItemDebitsValidation:
tr = {
**PydanticBaseModelValidation.tr,
"dues_types_uu_id": "Aidat Tipi UUID",
"dues_values": "Aidat Değerleri",
"decision_taken": "Karar Alındı mı?",
}
en = {
**PydanticBaseModelValidation.en,
"dues_types_uu_id": "Dues Type UUID",
"dues_values": "Dues Values",
"decision_taken": "Decision Taken?",
}
class UpdateBuildDecisionBookItemDebits(
PydanticBaseModel, UpdateBuildDecisionBookItemDebitsValidation
):
dues_types_uu_id: Optional[str] = None
dues_values: Optional[dict] = None
decision_taken: Optional[bool] = None

View File

@@ -2,11 +2,29 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class DepartmentsPydantic(PydanticBaseModel):
class DepartmentsPydanticValidation:
tr = {
"department_code": "Department Kodu",
"department_name": "Departman Adı",
"department_description": "Departman Açıklaması",
"company_uu_id": "Şirket UUID",
"parent_department_uu_id": "Üst Departman UUID",
}
en = {
"department_code": "Department Code",
"department_name": "Department Name",
"department_description": "Department Description",
"company_uu_id": "Company UUID",
"parent_department_uu_id": "Parent Department UUID",
}
class DepartmentsPydantic(PydanticBaseModel, PydanticBaseModelValidation):
department_code: Optional[str]
department_name: Optional[str]

View File

@@ -2,55 +2,177 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class BindEmployees2People(PydanticBaseModel):
class BindEmployees2PeopleValidation:
tr = {
**PydanticBaseModelValidation.tr,
"staff_uu_id": "Kadro UUID",
"people_uu_id": "Kişi UUID",
"expiry_starts": "Başlangıç Tarihi",
}
en = {
**PydanticBaseModelValidation.en,
"staff_uu_id": "Staff UUID",
"people_uu_id": "People UUID",
"expiry_starts": "Start Date",
}
class BindEmployees2People(PydanticBaseModel, BindEmployees2PeopleValidation):
staff_uu_id: str
people_uu_id: str
expiry_starts: Optional[str] = None
class UnBindEmployees2People(PydanticBaseModel):
class UnBindEmployees2PeopleValidation:
tr = {
**PydanticBaseModelValidation.tr,
"people_uu_id": "Kişi UUID",
"expiry_ends": "Bitiş Tarihi",
}
en = {
**PydanticBaseModelValidation.en,
"people_uu_id": "People UUID",
"expiry_ends": "End Date",
}
class UnBindEmployees2People(PydanticBaseModel, UnBindEmployees2PeopleValidation):
people_uu_id: str
expiry_ends: str
class InsertEmployees(PydanticBaseModel):
class InsertEmployeesValidation:
tr = {
"staff_uu_id": "Kadro UUID",
"people_uu_id": "Kişi UUID",
}
en = {
"staff_uu_id": "Staff UUID",
"people_uu_id": "People UUID",
}
class InsertEmployees(BaseModelRegular, InsertEmployeesValidation):
staff_uu_id: str
people_uu_id: Optional[str] = None
class InsertCompanyDuty(PydanticBaseModel):
class InsertCompanyDutyValidation:
tr = {
"duty_code": "Görev Kodu",
"duty_name": "Görev Adı",
"duty_description": "Görev Açıklaması",
}
en = {
"duty_code": "Duty Code",
"duty_name": "Duty Name",
"duty_description": "Duty Description",
}
class InsertCompanyDuty(BaseModelRegular, InsertCompanyDutyValidation):
duty_code: str
duty_name: str
duty_description: Optional[str] = None
class SelectDuties(PydanticBaseModel):
class SelectDutiesValidation:
tr = {
"duty_uu_id": "Görev UUID",
}
en = {
"duty_uu_id": "Duty UUID",
}
class SelectDuties(BaseModelRegular, SelectDutiesValidation):
duty_uu_id: Optional[str] = None
class InsertDuties(PydanticBaseModel):
class InsertDutiesValidation:
tr = {
"duties_uu_id": "Görev UUID",
"department_uu_id": "Departman UUID",
"is_default_duty": "Varsayılan Görev",
}
en = {
"duties_uu_id": "Duty UUID",
"department_uu_id": "Department UUID",
"is_default_duty": "Default Duty",
}
class InsertDuties(BaseModelRegular, InsertDutiesValidation):
duties_uu_id: str
department_uu_id: str
is_default_duty: Optional[bool] = False
class UpdateDutiesValidation:
tr = {
**PydanticBaseModelValidation.tr,
"duties_uu_id": "Görev UUID",
"department_uu_id": "Departman UUID",
"is_default_duty": "Varsayılan Görev",
}
en = {
**PydanticBaseModelValidation.en,
"duties_uu_id": "Duty UUID",
"department_uu_id": "Department UUID",
"is_default_duty": "Default Duty",
}
class UpdateDuties(PydanticBaseModel):
duties_uu_id: Optional[str] = None
department_uu_id: Optional[str] = None
is_default_duty: Optional[bool] = None
class UpdateCompanyDutyValidation:
tr = {
**PydanticBaseModelValidation.tr,
"duty_code": "Görev Kodu",
"duty_name": "Görev Adı",
"duty_description": "Görev Açıklaması",
}
en = {
**PydanticBaseModelValidation.en,
"duty_code": "Duty Code",
"duty_name": "Duty Name",
"duty_description": "Duty Description",
}
class UpdateCompanyDuty(PydanticBaseModel):
duty_code: Optional[str] = None
duty_name: Optional[str] = None
duty_description: Optional[str] = None
class InsertCompanyEmployeesSalaries(PydanticBaseModel):
class InsertCompanyEmployeesSalariesValidation:
tr = {
"gross_salary": "Brüt Maaş",
"net_salary": "Net Maaş",
"start_date": "Başlangıç Tarihi",
"stop_date": "Bitiş Tarihi",
"people_id": "Kişi ID",
}
en = {
"gross_salary": "Gross Salary",
"net_salary": "Net Salary",
"start_date": "Start Date",
"stop_date": "Stop Date",
"people_id": "People ID",
}
class InsertCompanyEmployeesSalaries(BaseModelRegular):
gross_salary: float
net_salary: float
start_date: str
@@ -58,6 +180,25 @@ class InsertCompanyEmployeesSalaries(PydanticBaseModel):
people_id: int
class UpdateCompanyEmployeesSalariesValidation:
tr = {
**PydanticBaseModelValidation.tr,
"gross_salary": "Brüt Maaş",
"net_salary": "Net Maaş",
"start_date": "Başlangıç Tarihi",
"stop_date": "Bitiş Tarihi",
"people_id": "Kişi ID",
}
en = {
**PydanticBaseModelValidation.en,
"gross_salary": "Gross Salary",
"net_salary": "Net Salary",
"start_date": "Start Date",
"stop_date": "Stop Date",
"people_id": "People ID",
}
class UpdateCompanyEmployeesSalaries(PydanticBaseModel):
gross_salary: Optional[float] = None
net_salary: Optional[float] = None
@@ -66,7 +207,24 @@ class UpdateCompanyEmployeesSalaries(PydanticBaseModel):
people_id: Optional[int] = None
class InsertCompanyEmployees(PydanticBaseModel):
class InsertCompanyEmployeesValidation:
tr = {
"employee_description": "Çalışan Açıklaması",
"person_uu_id": "Kişi UUID",
"duty_uu_id": "Görev UUID",
"start_date": "Başlangıç Tarihi",
"stop_date": "Bitiş Tarihi",
}
en = {
"employee_description": "Employee Description",
"person_uu_id": "Person UUID",
"duty_uu_id": "Duty UUID",
"start_date": "Start Date",
"stop_date": "Stop Date",
}
class InsertCompanyEmployees(BaseModelRegular, InsertCompanyEmployeesValidation):
employee_description: Optional[str] = None
person_uu_id: str
@@ -76,6 +234,19 @@ class InsertCompanyEmployees(PydanticBaseModel):
stop_date: Optional[str] = None
class UpdateCompanyEmployees(PydanticBaseModel):
class UpdateCompanyEmployeesValidation:
tr = {
**PydanticBaseModelValidation.tr,
"stop_date": "Bitiş Tarihi",
"employee_description": "Çalışan Açıklaması",
}
en = {
**PydanticBaseModelValidation.en,
"stop_date": "Stop Date",
"employee_description": "Employee Description",
}
class UpdateCompanyEmployees(PydanticBaseModel, UpdateCompanyEmployeesValidation):
stop_date: Optional[str] = None
employee_description: Optional[str] = None

View File

@@ -6,19 +6,36 @@ from api_validations.validations_request import (
)
class CreateEvents(PydanticBaseModel):
event_name: Optional[str] = None
event_description: Optional[str] = None
event_date: Optional[str] = None
event_location: Optional[str] = None
class RegisterEvents2EmployeeValidation:
tr = {
"event_uu_id_list": "Etkinlikler Listesi",
"employee_uu_id": "Çalışan UU ID",
}
en = {
"event_uu_id_list": "Event List",
"employee_uu_id": "Employee UU ID",
}
class RegisterEvents2Employee(PydanticBaseModel):
event_uu_id_list: list[str] = []
class RegisterEvents2Employee(BaseModelRegular, RegisterEvents2EmployeeValidation):
event_uu_id_list: list[str] = None
employee_uu_id: Optional[str] = None
class RegisterEvents2Occupant(PydanticBaseModel):
event_uu_id_list: list[str] = []
class RegisterEvents2OccupantValidation:
tr = {
"event_uu_id_list": "Etkinlikler Listesi",
"build_part_uu_id": "Bina Parça UU ID",
"occupant_uu_id": "Apartman Sakini UU ID",
}
en = {
"event_uu_id_list": "Event List",
"build_part_uu_id": "Building Part UU ID",
"occupant_uu_id": "Occupant UU ID",
}
class RegisterEvents2Occupant(BaseModelRegular, RegisterEvents2OccupantValidation):
event_uu_id_list: list[str] = None
build_part_uu_id: Optional[str] = None
occupant_uu_id: Optional[str] = None

View File

@@ -4,15 +4,37 @@ from api_validations.validations_request import (
ListOptions,
)
class RegisterModules2Occupant(BaseModelRegular):
class RegisterModules2OccupantValidation:
tr = {
"modules_uu_id": "Modül Listesi",
"occupant_uu_id": "Mülk Sahibi",
"build_part_uu_id": "Daire UUID",
}
en = {
"modules_uu_id": "Module List",
"occupant_uu_id": "Occupant",
"build_part_uu_id": "Flat UUID",
}
class RegisterModules2Occupant(BaseModelRegular, RegisterModules2OccupantValidation):
modules_uu_id: str
occupant_uu_id: str
build_part_uu_id: str
class RegisterModules2Employee(BaseModelRegular):
class RegisterModules2EmployeeValidation:
tr = {
"modules_uu_id": "Modül Listesi",
"employee_uu_id": "Çalışan",
}
en = {
"modules_uu_id": "Module List",
"employee_uu_id": "Employee",
}
class RegisterModules2Employee(BaseModelRegular, RegisterModules2EmployeeValidation):
modules_uu_id: str
employee_uu_id: str

View File

@@ -2,11 +2,29 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions,
)
class InsertPerson(PydanticBaseModel):
class InsertPersonValidation:
tr = {
"firstname": "İsim",
"surname": "Soyisim",
"sex_code": "Cinsiyet",
"national_identity_id": "T.C. Kimlik Numarası",
"middle_name": "Orta İsim",
"father_name": "Baba Adı",
"mother_name": "Anne Adı",
"country_code": "Ülke Kodu",
"birth_place": "Doğum Yeri",
"birth_date": "Doğum Tarihi",
"tax_no": "Vergi Numarası",
"ref_id": "Referans ID",
}
class InsertPerson(BaseModelRegular, InsertPersonValidation):
firstname: str
surname: str
sex_code: str
@@ -18,19 +36,21 @@ class InsertPerson(PydanticBaseModel):
birth_place: Optional[str] = None
birth_date: Optional[str] = None
tax_no: Optional[str] = None
ref_id: Optional[str] = None
class ResponsePersonSalesMange(PydanticBaseModel):
uu_id: str
firstname: str
surname: str
national_identity_id: str
birth_place: Optional[str] = None
birth_date: Optional[str] = None
tax_no: Optional[str] = None
class UpdatePersonValidation:
tr = {
**PydanticBaseModelValidation.tr,
**InsertPersonValidation.tr,
}
en = {
**PydanticBaseModelValidation.en,
**InsertPersonValidation.tr,
}
class UpdatePerson(PydanticBaseModel):
class UpdatePerson(PydanticBaseModel, UpdatePersonValidation):
firstname: Optional[str] = None
surname: Optional[str] = None
middle_name: Optional[str]

View File

@@ -2,13 +2,156 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
ListOptions,
PydanticBaseModelValidation,
)
class InsertBuildDecisionBookProjects(PydanticBaseModel):
class InsertBuildDecisionBookProjectItemsValidation:
tr = {
"build_decision_book_project_uu_id": "Proje UUID",
"item_header": "Başlık",
"item_comment": "ıklama",
"attachment_pdf_path": "Ek Dosya Yolu",
"item_objection": "İtiraz",
}
en = {
"build_decision_book_project_uu_id": "Project UUID",
"item_header": "Header",
"item_comment": "Comment",
"attachment_pdf_path": "Attachment PDF Path",
"item_objection": "Objection",
}
class InsertBuildDecisionBookProjectItems(
BaseModelRegular, InsertBuildDecisionBookProjectItemsValidation
):
build_decision_book_project_uu_id: str
item_header: str
item_comment: str
attachment_pdf_path: Optional[str] = None
item_objection: Optional[str] = None
class UpdateBuildDecisionBookProjectItemsValidation:
tr = {
**InsertBuildDecisionBookProjectItemsValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectItemsValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuildDecisionBookProjectItems(PydanticBaseModel):
item_header: Optional[str] = None
item_comment: Optional[str] = None
attachment_pdf_path: Optional[str] = None
item_estimated_cost: Optional[float] = None
build_decision_book_project_uu_id: Optional[str] = None
class InsertBuildDecisionBookProjectPersonValidation:
tr = {
"dues_percent_discount": "İskonto Oranı",
"job_fix_wage": "Sabit Ücret",
"bid_price": "Teklif Fiyatı",
"decision_price": "Karar Fiyatı",
"build_decision_book_project_uu_id": "Proje UUID",
"living_space_uu_id": "Yaşam Alanı UUID",
"project_team_type_uu_id": "Proje Takım Tipi UUID",
}
en = {
"dues_percent_discount": "Discount Rate",
"job_fix_wage": "Fixed Wage",
"bid_price": "Bid Price",
"decision_price": "Decision Price",
"build_decision_book_project_uu_id": "Project UUID",
"living_space_uu_id": "Living Space UUID",
"project_team_type_uu_id": "Project Team Type UUID",
}
class InsertBuildDecisionBookProjectPerson(
BaseModelRegular, InsertBuildDecisionBookProjectPersonValidation
):
dues_percent_discount: Optional[int] = None
job_fix_wage: Optional[float] = None
bid_price: Optional[float] = None
decision_price: Optional[float] = None
build_decision_book_project_uu_id: str
living_space_uu_id: str
project_team_type_uu_id: str
class UpdateBuildDecisionBookProjectPersonValidation:
tr = {
**InsertBuildDecisionBookProjectPersonValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectPersonValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuildDecisionBookProjectPerson(
PydanticBaseModel, UpdateBuildDecisionBookProjectPersonValidation
):
dues_percent_discount: Optional[int] = None
job_fix_wage: Optional[float] = None
bid_price: Optional[float] = None
decision_price: Optional[float] = None
build_decision_book_project_uu_id: Optional[str] = None
living_space_uu_id: Optional[str] = None
project_team_type_uu_id: Optional[str] = None
class InsertBuildDecisionBookProjectsValidation:
tr = {
"build_decision_book_item_uu_id": "Karar Defteri UUID",
"project_responsible_person_uu_id": "Proje Sorumlu Kişi UUID",
"project_name": "Proje Adı",
"project_start_date": "Proje Başlangıç Tarihi",
"project_stop_date": "Proje Bitiş Tarihi",
"project_type": "Proje Tipi",
"is_out_sourced": "Dış Kaynak Kullanımı",
"project_note": "Proje Notu",
"decision_book_pdf_path": "Karar Defteri PDF Yolu",
"resp_company_fix_wage": "Firma Sabit Ücreti",
"contact_agreement_path": "İletişim Anlaşması Yolu",
"contact_agreement_date": "İletişim Anlaşması Tarihi",
"meeting_date": "Toplantı Tarihi",
"currency": "Para Birimi",
"bid_price": "Teklif Fiyatı",
"resp_company_uu_id": "Firma UUID",
}
en = {
"build_decision_book_item_uu_id": "Decision Book UUID",
"project_responsible_person_uu_id": "Project Responsible Person UUID",
"project_name": "Project Name",
"project_start_date": "Project Start Date",
"project_stop_date": "Project Stop Date",
"project_type": "Project Type",
"is_out_sourced": "Out Sourced",
"project_note": "Project Note",
"decision_book_pdf_path": "Decision Book PDF Path",
"resp_company_fix_wage": "Company Fixed Wage",
"contact_agreement_path": "Contact Agreement Path",
"contact_agreement_date": "Contact Agreement Date",
"meeting_date": "Meeting Date",
"currency": "Currency",
"bid_price": "Bid Price",
"resp_company_uu_id": "Company UUID",
}
class InsertBuildDecisionBookProjects(
BaseModelRegular, InsertBuildDecisionBookProjectsValidation
):
build_decision_book_item_uu_id: str
project_response_person_uu_id: str
project_responsible_person_uu_id: str
project_name: str
project_start_date: str
project_stop_date: str
@@ -21,43 +164,88 @@ class InsertBuildDecisionBookProjects(PydanticBaseModel):
contact_agreement_path: Optional[str] = None
contact_agreement_date: Optional[str] = None
meeting_date: Optional[str] = None
currency: Optional[str] = None
bid_price: Optional[float] = None
approved_price: Optional[float] = None
final_price: Optional[float] = None
resp_company_uu_id: Optional[str] = None
class UpdateBuildDecisionBookProjects(PydanticBaseModel):
resp_company_uu_id: Optional[str] = None
class UpdateBuildDecisionBookProjectsValidation:
tr = {
**InsertBuildDecisionBookProjectsValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectsValidation.en,
**PydanticBaseModelValidation.en,
}
project_response: Optional[str] = None
project_name: Optional[str] = None
project_type: Optional[str] = None
class UpdateBuildDecisionBookProjects(
PydanticBaseModel, UpdateBuildDecisionBookProjectsValidation
):
build_decision_book_project_uu_id: str
is_out_sourced: Optional[bool] = False
project_note: Optional[str] = None
decision_book_pdf_path: Optional[str] = None
# decision_book_pdf_path: Optional[str] = None
status_id: Optional[int] = None
resp_company_fix_wage: Optional[float] = None
is_out_sourced: Optional[bool] = None
contact_agreement_path: Optional[str] = None
contact_agreement_date: Optional[str] = None
meeting_date: Optional[str] = None
bid_price: Optional[float] = None
contact_uu_id: Optional[str] = None
resp_company_uu_id: Optional[str] = None
approved_price: Optional[float] = None
final_price: Optional[float] = None
class InsertBuildDecisionBookProjectItems(PydanticBaseModel):
item_order: int
item_comment: str
class ApprovalsBuildDecisionBookProjectsValidation:
tr = {
"build_decision_book_project_uu_id": "Karar Defteri Proje UUID",
"project_stop_date": "Proje Bitiş Tarihi",
"status_code": "Durum Kodu",
"final_price_list": "Son Fiyat Listesi",
}
en = {
"build_decision_book_project_uu_id": "Decision Book Project UUID",
"project_stop_date": "Project Stop Date",
"status_code": "Status Code",
"final_price_list": "Final Price List",
}
class ApprovalsBuildDecisionBookProjects(
PydanticBaseModel, ApprovalsBuildDecisionBookProjectsValidation
):
build_decision_book_project_uu_id: str
item_objection: Optional[str] = None
project_stop_date: str
status_code: Optional[int] = None
final_price_list: Optional[list[dict]] = (
None # {"date": "2021-01-01", "price": 1000}
)
class UpdateBuildDecisionBookProjectItems(PydanticBaseModel):
item_comment: Optional[str] = None
item_objection: Optional[str] = None
class InsertBuildDecisionBookProjectItemDebitsValidation:
tr = {
"build_decision_book_project_item_uu_id": "Karar Defteri Proje Öğe UUID",
"payment_date": "Ödeme Tarihi",
"dues_values": "Borç Değerleri",
"is_official": "Resmi Mi?",
"discount_value": "İskonto Oranı",
"discount_fix": "İskonto Sabit",
"decision_taken": "Karar Alındı Mı?",
}
en = {
"build_decision_book_project_item_uu_id": "Decision Book Project Item UUID",
"payment_date": "Payment Date",
"dues_values": "Dues Values",
"is_official": "Is Official?",
"discount_value": "Discount Rate",
"discount_fix": "Discount Fix",
"decision_taken": "Decision Taken?",
}
class InsertBuildDecisionBookProjectItemDebits(PydanticBaseModel):
class InsertBuildDecisionBookProjectItemDebits(
PydanticBaseModel, InsertBuildDecisionBookProjectItemDebitsValidation
):
build_decision_book_project_item_uu_id: str
payment_date: str
dues_values: dict
@@ -67,7 +255,20 @@ class InsertBuildDecisionBookProjectItemDebits(PydanticBaseModel):
decision_taken: Optional[bool] = None
class UpdateBuildDecisionBookProjectItemDebits(PydanticBaseModel):
class UpdateBuildDecisionBookProjectItemDebitsValidation:
tr = {
**InsertBuildDecisionBookProjectItemDebitsValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectItemDebitsValidation.en,
**PydanticBaseModelValidation.en,
}
class UpdateBuildDecisionBookProjectItemDebits(
PydanticBaseModel, UpdateBuildDecisionBookProjectItemDebitsValidation
):
dues_values: Optional[str] = None
discount_value: Optional[float] = None
discount_fix: Optional[float] = None

View File

@@ -6,6 +6,9 @@ from api_validations.validations_request import (
)
class CheckEndpointAccess(BaseModelRegular):
endpoint: str
class InsertEndpointAccess(PydanticBaseModel):
duty_uu_id: str
endpoint_restriction_list_uu_ids: list

View File

@@ -4,12 +4,37 @@ from api_validations.validations_request import (
ListOptions,
)
class RegisterServices2Occupant(BaseModelRegular):
class RegisterServices2OccupantValidation:
tr = {
"service_uu_id": "Hizmet UUID",
"occupant_uu_id": "Müşteri UUID",
"build_part_uu_id": "Bina Parça UUID",
}
en = {
"service_uu_id": "Service UUID",
"occupant_uu_id": "Occupant UUID",
"build_part_uu_id": "Building Part UUID",
}
class RegisterServices2Occupant(BaseModelRegular, RegisterServices2OccupantValidation):
service_uu_id: str
occupant_uu_id: str
build_part_uu_id: str
class RegisterServices2Employee(BaseModelRegular):
class RegisterServices2EmployeeValidation:
tr = {
"service_uu_id": "Hizmet UUID",
"employee_uu_id": "Personel UUID",
}
en = {
"service_uu_id": "Service UUID",
"employee_uu_id": "Employee UUID",
}
class RegisterServices2Employee(BaseModelRegular, RegisterServices2EmployeeValidation):
service_uu_id: str
employee_uu_id: str

View File

@@ -6,15 +6,38 @@ from api_validations.validations_request import (
)
class InsertStaff(PydanticBaseModel):
class InsertStaffValidation:
tr = {
"staff_name": "Kadro Adı",
"staff_description": "Kadro Açıklaması",
"staff_code": "Kadro Kodu",
"duties_uu_id": "Görev UUID",
}
en = {
"staff_name": "Staff Name",
"staff_description": "Staff Description",
"staff_code": "Staff Code",
"duties_uu_id": "Duties UUID",
}
class InsertStaff(BaseModelRegular, InsertStaffValidation):
staff_name: str
staff_description: Optional[str] = None
staff_code: Optional[str] = None
duties_uu_id: str
class SelectStaff(PydanticBaseModel):
class SelectStaffValidation:
tr = {
"duties_uu_id": "Görev UUID",
}
en = {
"duties_uu_id": "Duties UUID",
}
class SelectStaff(PydanticBaseModel, SelectStaffValidation):
duties_uu_id: str

View File

@@ -5,7 +5,25 @@ from api_validations.validations_request import (
ListOptions,
)
class InsertUsers(PydanticBaseModel):
class InsertUsersValidation:
tr = {
"people_uu_id": "Kişi UUID",
"user_tag": "Kullanıcı Etiketi",
"email": "E-posta",
"phone_number": "Telefon Numarası",
"avatar": "Avatar",
}
en = {
"people_uu_id": "People UUID",
"user_tag": "User Tag",
"email": "Email",
"phone_number": "Phone Number",
"avatar": "Avatar",
}
class InsertUsers(PydanticBaseModel, InsertUsersValidation):
people_uu_id: str
user_tag: str
email: Optional[str] = None
@@ -13,7 +31,26 @@ class InsertUsers(PydanticBaseModel):
avatar: Optional[str] = None
class UpdateUsers(PydanticBaseModel):
class UpdateUsersValidation:
tr = {
"people_uu_id": "Kişi UUID",
"nick_name": "Kullanıcı Etiketi",
"domain_name": "Domain Adı",
"email": "E-posta",
"phone_number": "Telefon Numarası",
"avatar": "Avatar",
}
en = {
"people_uu_id": "People UUID",
"nick_name": "User Tag",
"domain_name": "Domain Name",
"email": "Email",
"phone_number": "Phone Number",
"avatar": "Avatar",
}
class UpdateUsers(PydanticBaseModel, UpdateUsersValidation):
people_uu_id: Optional[str] = None
nick_name: Optional[str] = None
domain_name: Optional[str] = None
@@ -22,23 +59,14 @@ class UpdateUsers(PydanticBaseModel):
avatar: Optional[str] = None
class QueryUsersValidation:
tr = {
"uu_id": "UUID",
}
en = {
"uu_id": "UUID",
}
class QueryUsers(PydanticBaseModel):
uu_id: Optional[str] = None
class DeleteUsers(PydanticBaseModel):
key_id: Optional[str] = None
query: Optional[List[QueryUsers]] = None
data: Optional[dict] = None
class ListUsers(PydanticBaseModel):
key_id: Optional[str] = None
query: Optional[QueryUsers] = None
data: Optional[ListOptions] = None
class ActiveUsers(PydanticBaseModel):
key_id: Optional[str] = None
query: Optional[List[QueryUsers]] = None
data: Optional[dict] = None

View File

@@ -0,0 +1,5 @@
from .building import ListBuildingResponse
__all__ = [
"ListBuildingResponse",
]

View File

@@ -0,0 +1,138 @@
from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
class AccountListValidation:
tr = {
**CrudRecordValidation.tr,
"iban": "IBAN Numarası",
"bank_date": "Banka İşlem Tarihi",
"currency_value": "Para Birimi Değeri",
"bank_balance": "Banka Bakiyesi",
"currency": "Para Birimi Birimi",
"additional_balance": "Ek Bakiye",
"channel_branch": "Şube Banka",
"process_name": "Banka İşlem Türü Adı",
"process_type": "Banka İşlem Türü",
"process_comment": "İşlem Kayıt Yorumu",
"process_garbage": "İşlem Kayıt Çöpü",
"bank_reference_code": "Banka Referans Kodu",
"add_comment_note": "Yorum Not Ekle",
"is_receipt_mail_send": "Makbuz Posta Gönderildi",
"found_from": "Bulunduğu Yer",
"similarity": "Benzerlik",
"remainder_balance": "Kalan Bakiye",
"bank_date_y": "Banka İşlem Yılı",
"bank_date_m": "Banka İşlem Ayı",
"bank_date_w": "Banka İşlem Haftası",
"bank_date_d": "Banka İşlem Günü",
"approving_accounting_record": "Onaylayan Muhasebe Kaydı",
"accounting_receipt_date": "Muhasebe Makbuz Tarihi",
"accounting_receipt_number": "Muhasebe Makbuz Numarası",
"approved_record": "Onaylanmış Kayıt",
"import_file_name": "İçe Aktarım Dosya Adı",
"receive_debit": "Alacak Borç",
"receive_debit_uu_id": "Alacak Borç UU Kimliği",
"budget_type": "Bütçe Türü",
"budget_type_uu_id": "Bütçe Türü UU Kimliği",
"company_uu_id": "Şirket UU Kimliği",
"send_company_uu_id": "Şirket UU Kimliği Gönder",
"send_person_uu_id": "Kişi UU Kimliği Gönder",
"approving_accounting_person_uu_id": "Onaylayan Muhasebe Kişi UU Kimliği",
"living_space_uu_id": "Yaşam Alanı UU Kimliği",
"customer_uu_id": "Müşteri UU Kimliği",
"build_uu_id": "Yapı UU Kimliği",
"build_parts_uu_id": "Yapı Parça UU Kimliği",
"build_decision_book_uu_id": "Yapı Karar Defteri UU Kimliği",
}
en = {
**CrudRecordValidation.en,
"iban": "IBAN Number",
"bank_date": "Bank Transaction Date",
"currency_value": "Currency Value",
"bank_balance": "Bank Balance",
"currency": "Unit of Currency",
"additional_balance": "Additional Balance",
"channel_branch": "Branch Bank",
"process_name": "Bank Process Type Name",
"process_type": "Bank Process Type",
"process_comment": "Transaction Record Comment",
"process_garbage": "Transaction Record Garbage",
"bank_reference_code": "Bank Reference Code",
"add_comment_note": "Add Comment Note",
"is_receipt_mail_send": "Receipt Mail Send",
"found_from": "Found From",
"similarity": "Similarity",
"remainder_balance": "Remainder Balance",
"bank_date_y": "Bank Date Year",
"bank_date_m": "Bank Date Month",
"bank_date_w": "Bank Date Week",
"bank_date_d": "Bank Date Day",
"approving_accounting_record": "Approving Accounting Record",
"accounting_receipt_date": "Accounting Receipt Date",
"accounting_receipt_number": "Accounting Receipt Number",
"approved_record": "Approved Record",
"import_file_name": "Import File Name",
"receive_debit": "Receive Debit",
"receive_debit_uu_id": "Receive Debit UU ID",
"budget_type": "Budget Type",
"budget_type_uu_id": "Budget Type UU ID",
"company_uu_id": "Company UU ID",
"send_company_uu_id": "Send Company UU ID",
"send_person_uu_id": "Send Person UU ID",
"approving_accounting_person_uu_id": "Approving Accounting Person UU ID",
"living_space_uu_id": "Living Space UU ID",
"customer_uu_id": "Customer UU ID",
"build_uu_id": "Build UU ID",
"build_parts_uu_id": "Build Parts UU ID",
"build_decision_book_uu_id": "Build Decision Book UU ID",
}
class AccountListResponse(BaseModelRegular, CrudRecords, AccountListValidation):
iban: Optional[str] = None
bank_date: Optional[str] = None
currency_value: Optional[str] = None
bank_balance: Optional[str] = None
currency: Optional[str] = None
additional_balance: Optional[str] = None
channel_branch: Optional[str] = None
process_name: Optional[str] = None
process_type: Optional[str] = None
process_comment: Optional[str] = None
process_garbage: Optional[str] = None
bank_reference_code: Optional[str] = None
add_comment_note: Optional[str] = None
is_receipt_mail_send: Optional[str] = None
found_from: Optional[str] = None
similarity: Optional[str] = None
remainder_balance: Optional[str] = None
bank_date_y: Optional[str] = None
bank_date_m: Optional[str] = None
bank_date_w: Optional[str] = None
bank_date_d: Optional[str] = None
approving_accounting_record: Optional[str] = None
accounting_receipt_date: Optional[str] = None
accounting_receipt_number: Optional[str] = None
approved_record: Optional[str] = None
import_file_name: Optional[str] = None
receive_debit: Optional[str] = None
receive_debit_uu_id: Optional[str] = None
budget_type: Optional[str] = None
budget_type_uu_id: Optional[str] = None
company_uu_id: Optional[str] = None
send_company_uu_id: Optional[str] = None
send_person_uu_id: Optional[str] = None
approving_accounting_person_uu_id: Optional[str] = None
living_space_uu_id: Optional[str] = None
customer_uu_id: Optional[str] = None
build_uu_id: Optional[str] = None
build_parts_uu_id: Optional[str] = None
build_decision_book_uu_id: Optional[str] = None

View File

@@ -0,0 +1,30 @@
from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
class ListAddressResponse:
pass
"""
street_id: Mapped[int] = mapped_column(ForeignKey("address_street.id"))
street_uu_id: Mapped[str] = mapped_column(
String, server_default="", comment="Street UUID"
)
postcode: Mapped[str] = mapped_column(
String(32), nullable=False, comment="Postcode"
)
"""
class AddressPostCodeResponse:
street_id: Optional[int] = None
street_uu_id: Optional[str] = None
postcode: Optional[str] = None

View File

@@ -0,0 +1,125 @@
from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
class BuildListValidation:
tr = {
**CrudRecordValidation.tr,
"gov_address_code": "Devlet Adres Kodu",
"build_name": "Bina Adı",
"build_types_uu_id": "Bina Tipi",
"build_no": "Bina No",
"max_floor": "Kat Sayısı",
"underground_floor": "Bodrum Kat Sayısı",
"address_uu_id": "Adres",
"build_date": "Yapım Tarihi",
"decision_period_date": "Karar Tarihi",
"tax_no": "Vergi No",
"lift_count": "Asansör Sayısı",
"heating_system": "Isıtma Sistemi",
"cooling_system": "Soğutma Sistemi",
"hot_water_system": "Sıcak Su Sistemi",
"block_service_man_count": "Hizmet Görevlisi Sayısı",
"security_service_man_count": "Güvenlik Görevlisi Sayısı",
"garage_count": "Garaj Sayısı",
"site_uu_id": "Site UUID",
}
en = {
**CrudRecordValidation.en,
"gov_address_code": "Government Address Code",
"build_name": "Building Name",
"build_types_uu_id": "Building Type",
"build_no": "Building No",
"max_floor": "Number of Floors",
"underground_floor": "Number of Basement Floors",
"address_uu_id": "Address",
"build_date": "Construction Date",
"decision_period_date": "Decision Date",
"tax_no": "Tax No",
"lift_count": "Number of Elevators",
"heating_system": "Heating System",
"cooling_system": "Cooling System",
"hot_water_system": "Hot Water System",
"block_service_man_count": "Number of Service Officers",
"security_service_man_count": "Number of Security Officers",
"garage_count": "Number of Garages",
"site_uu_id": "Site UUID",
}
class ListBuildingResponse(BaseModelRegular, CrudRecords, BuildListValidation):
gov_address_code: Optional[str] = None
build_name: Optional[str] = None
build_types_uu_id: Optional[str] = None
build_no: Optional[str] = None
max_floor: Optional[int] = None
underground_floor: Optional[int] = None
address_uu_id: Optional[str] = None
build_date: Optional[str] = None
decision_period_date: Optional[str] = None
tax_no: Optional[str] = None
lift_count: Optional[int] = None
heating_system: Optional[bool] = None
cooling_system: Optional[bool] = None
hot_water_system: Optional[bool] = None
block_service_man_count: Optional[int] = None
security_service_man_count: Optional[int] = None
garage_count: Optional[int] = None
site_uu_id: Optional[str] = None
# class InsertBuild(BaseModelRegular, BuildValidation):
# gov_address_code: str
# build_name: str
# build_types_uu_id: str
# max_floor: int
# underground_floor: int
# address_uu_id: str
# build_date: str
# decision_period_date: str
#
# tax_no: Optional[str] = None
# lift_count: Optional[int] = None
# heating_system: Optional[bool] = None
# cooling_system: Optional[bool] = None
# hot_water_system: Optional[bool] = None
# block_service_man_count: Optional[int] = None
# security_service_man_count: Optional[int] = None
# garage_count: Optional[int] = None
#
#
# class BuildUpdateValidation:
# tr = {
# **BuildValidation.tr,
# **PydanticBaseModelValidation.tr,
# }
# en = {
# **BuildValidation.en,
# **PydanticBaseModelValidation.en,
# }
#
#
# class UpdateBuild(PydanticBaseModel, BuildUpdateValidation):
# gov_address_code: Optional[str] = None
# build_name: Optional[str] = None
# build_no: Optional[str] = None
# build_types: Optional[str] = None
# max_floor: Optional[int] = None
# underground_floor: Optional[int] = None
# build_date: Optional[str] = None
# tax_no: Optional[str] = None
# lift_count: Optional[int] = None
# heating_system: Optional[bool] = None
# cooling_system: Optional[bool] = None
# hot_water_system: Optional[bool] = None
# block_service_man_count: Optional[int] = None
# security_service_man_count: Optional[int] = None
# garage_count: Optional[int] = None
# address_uu_id: Optional[str] = None

View File

@@ -0,0 +1,54 @@
from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
class LivingSpaceListValidation:
tr = {
**CrudRecordValidation.tr,
"fix_value": "Sabit Değer",
"fix_percent": "Sabit Yüzde",
"agreement_no": "Anlaşma No",
"marketing_process": "Pazarlama Süreci",
"marketing_layer": "Pazarlama Katmanı",
"build_parts_id": "Bölüm ID",
"build_parts_uu_id": "Bölüm UUID",
"person_id": "Sorumlu Kişi ID",
"person_uu_id": "Sorumlu Kişi UUID",
"occupant_type": "Kiracı Tipi",
"occupant_type_uu_id": "Kiracı Tipi UUID",
}
en = {
**CrudRecordValidation.en,
"fix_value": "Fixed Value",
"fix_percent": "Fixed Percent",
"agreement_no": "Agreement No",
"marketing_process": "Marketing Process",
"marketing_layer": "Marketing Layer",
"build_parts_id": "Part ID",
"build_parts_uu_id": "Part UUID",
"person_id": "Responsible Person ID",
"person_uu_id": "Responsible Person UUID",
"occupant_type": "Occupant Type",
"occupant_type_uu_id": "Occupant Type UUID",
}
class LivingSpaceListResponse(BaseModelRegular, CrudRecords, LivingSpaceListValidation):
fix_value: Optional[float] = None
fix_percent: Optional[float] = None
agreement_no: Optional[str] = None
marketing_process: Optional[str] = None
marketing_layer: Optional[str] = None
build_parts_id: Optional[int] = None
build_parts_uu_id: Optional[str] = None
person_id: Optional[int] = None
person_uu_id: Optional[str] = None
occupant_type: Optional[str] = None
occupant_type_uu_id: Optional[str] = None

View File

@@ -0,0 +1,56 @@
from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
class BuildPartsListValidation:
tr = {
**CrudRecordValidation.tr,
"address_gov_code": "Adres Kapı Kodu",
"part_no": "Bölüm No",
"part_level": "Bölüm Seviyesi",
"part_code": "Bölüm Kodu",
"part_gross": "Bölüm Brüt",
"part_net": "Bölüm Net",
"default_accessory": "Varsayılan Aksesuar",
"human_livable": "İnsan Yaşamı",
"due_part_key": "Sabit Ödeme Grubu",
"build_uu_id": "Bina UUID",
"part_direction_uu_id": "Bölüm Yönü UUID",
"part_type_uu_id": "Bölüm Tipi UUID",
}
en = {
**CrudRecordValidation.en,
"address_gov_code": "Address Government Code",
"part_no": "Part Number",
"part_level": "Part Level",
"part_code": "Part Code",
"part_gross": "Part Gross",
"part_net": "Part Net",
"default_accessory": "Default Accessory",
"human_livable": "Human Livable",
"due_part_key": "Constant Payment Group",
"build_uu_id": "Building UUID",
"part_direction_uu_id": "Part Direction UUID",
"part_type_uu_id": "Part Type UUID",
}
class BuildPartsListResponse(BaseModelRegular, CrudRecords, BuildPartsListValidation):
address_gov_code: Optional[str] = None
part_no: Optional[int] = None
part_level: Optional[int] = None
part_code: Optional[str] = None
part_gross: Optional[int] = None
part_net: Optional[int] = None
default_accessory: Optional[str] = None
human_livable: Optional[bool] = None
due_part_key: Optional[str] = None
build_uu_id: Optional[str] = None
part_direction_uu_id: Optional[str] = None
part_type_uu_id: Optional[str] = None

View File

@@ -0,0 +1,59 @@
from typing import Optional
from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import (
PydanticBaseModel,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
class PeopleListValidation:
tr = {
**CrudRecordValidation.tr,
"firstname": "Ad",
"surname": "Soyad",
"middle_name": "Orta İsim",
"sex_code": "Cinsiyet Kodu",
"person_ref": "Kişi Referansı",
"person_tag": "Kişi Etiketi",
"father_name": "Baba Adı",
"mother_name": "Anne Adı",
"country_code": "Ülke Kodu",
"national_identity_id": "Kimlik Numarası",
"birth_place": "Doğum Yeri",
"birth_date": "Doğum Tarihi",
"tax_no": "Vergi Numarası",
}
en = {
**CrudRecordValidation.en,
"firstname": "First Name",
"surname": "Surname",
"middle_name": "Middle Name",
"sex_code": "Sex Code",
"person_ref": "Person Reference",
"person_tag": "Person Tag",
"father_name": "Father's Name",
"mother_name": "Mother's Name",
"country_code": "Country Code",
"national_identity_id": "National Identity ID",
"birth_place": "Birth Place",
"birth_date": "Birth Date",
"tax_no": "Tax Number",
}
class PeopleListResponse(BaseModelRegular, CrudRecords, PeopleListValidation):
firstname: Optional[str] = None
surname: Optional[str] = None
middle_name: Optional[str] = None
sex_code: Optional[str] = None
person_ref: Optional[str] = None
person_tag: Optional[str] = None
father_name: Optional[str] = None
mother_name: Optional[str] = None
country_code: Optional[str] = None
national_identity_id: Optional[str] = None
birth_place: Optional[str] = None
birth_date: Optional[str] = None
tax_no: Optional[str] = None

View File

@@ -6,14 +6,19 @@ from databases.sql_models.account.account import (
AccountCodes,
AccountDetail,
AccountMaster,
AccountRecordExchanges,
)
from databases.sql_models.building.budget import (
DecisionBookBudgetBooks,
DecisionBookBudgetCodes,
DecisionBookBudgetMaster,
DecisionBookBudgets,
)
from databases.sql_models.account.iban import (
BuildIbans,
BuildIbanDescription,
)
from databases.sql_models.api.encrypter import (
CrypterEngine
)
from databases.sql_models.api.encrypter import CrypterEngine
from databases.sql_models.building.build import (
Build,
BuildTypes,
@@ -36,6 +41,7 @@ from databases.sql_models.building.decision_book import (
BuildDecisionBookProjects,
BuildDecisionBookProjectPerson,
BuildDecisionBookPersonOccupants,
BuildDecisionBookProjectItems,
)
from databases.sql_models.company.company import (
Companies,
@@ -59,6 +65,8 @@ from databases.sql_models.event.event import (
Events,
Event2Occupant,
Event2Employee,
Event2OccupantExtra,
Event2EmployeeExtra,
)
from databases.sql_models.identity.identity import (
Addresses,
@@ -86,7 +94,7 @@ from databases.sql_models.rules.rules import (
EndpointRestriction,
)
#NO-SQL Models
# NO-SQL Models
from databases.no_sql_models.mongo_database import (
MongoQuery,
)
@@ -101,6 +109,7 @@ __all__ = [
"AccountCodes",
"AccountDetail",
"AccountMaster",
"AccountRecordExchanges",
"BuildIbans",
"BuildIbanDescription",
"CrypterEngine",
@@ -122,6 +131,11 @@ __all__ = [
"BuildDecisionBookProjects",
"BuildDecisionBookProjectPerson",
"BuildDecisionBookPersonOccupants",
"BuildDecisionBookProjectItems",
"DecisionBookBudgetBooks",
"DecisionBookBudgetCodes",
"DecisionBookBudgetMaster",
"DecisionBookBudgets",
"Companies",
"RelationshipDutyCompany",
"Employees",
@@ -137,6 +151,8 @@ __all__ = [
"Events",
"Event2Occupant",
"Event2Employee",
"Event2OccupantExtra",
"Event2EmployeeExtra",
"Addresses",
"AddressCity",
"AddressStreet",
@@ -161,5 +177,3 @@ __all__ = [
"MongoQuery",
"MongoQueryIdentity",
]

View File

@@ -0,0 +1,11 @@
from .selector_classes import (
Explanation,
SelectActionWithEmployee,
SelectAction,
)
__all__ = [
"Explanation",
"SelectAction",
"SelectActionWithEmployee",
]

View File

@@ -0,0 +1,361 @@
import uuid
import secrets
import hashlib
import requests
from sqlalchemy import or_
from datetime import timedelta
from fastapi.exceptions import HTTPException
from fastapi import status
from databases.no_sql_models.validations import (
PasswordHistoryViaUser,
AccessHistoryViaUser,
)
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
from api_configs import ApiStatic, Auth
class PasswordModule:
@classmethod
def generate_token(cls, length):
return secrets.token_urlsafe(length)
@classmethod
def create_hashed_password(cls, domain, id_, password):
salted_password = f"{domain}-{id_}-{password}"
return hashlib.sha256(salted_password.encode()).hexdigest()
@classmethod
def check_hashed_password(cls, domain, id_, password, password_hashed):
if not password_hashed:
raise HTTPException(
status_code=401,
detail="Password is not changed yet user has no password.",
)
return cls.create_hashed_password(domain, id_, password) == password_hashed
class AuthModule(PasswordModule):
@classmethod
def check_user_exits(cls, access_key, domain):
from databases import Users
found_user = Users.query.filter(
or_(
Users.email == str(access_key).lower(),
Users.phone_number == str(access_key).replace(" ", ""),
),
).first()
if not found_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Given access key or domain is not matching with the any user record.",
)
other_domains_list = found_user.get_main_domain_and_other_domains(
get_main_domain=False
)
if domain not in other_domains_list:
raise HTTPException(
status_code=401,
detail=dict(message="Unauthorized User attempts to connect api"),
)
return found_user
def generate_access_token(self):
return self.generate_token(Auth.ACCESS_TOKEN_LENGTH)
def remove_refresher_token(self, domain, disconnect: bool = False):
from databases import (
UsersTokens,
)
if disconnect:
registered_tokens = UsersTokens.filter_all(
UsersTokens.user_id == self.id, system=True
)
else:
registered_tokens = UsersTokens.filter_all(
UsersTokens.domain == domain,
UsersTokens.user_id == self.id,
system=True,
)
registered_tokens.query.delete()
UsersTokens.save()
def check_password(self, password):
main_domain = self.get_main_domain_and_other_domains(get_main_domain=True)
if check_password := self.check_hashed_password(
domain=main_domain,
id_=str(self.uu_id),
password_hashed=self.hash_password,
password=password,
):
return check_password
raise HTTPException(
status_code=401,
detail="Password is not correct.",
)
def check_password_is_different(self, password):
main_domain = self.get_main_domain_and_other_domains(get_main_domain=True)
if self.hash_password == self.create_hashed_password(
domain=main_domain, id_=self.uu_id, password=password
):
raise HTTPException(
status_code=401,
detail="New password is same with old password.",
)
@staticmethod
def create_password(found_user, password, password_token=None):
from databases import MongoQueryIdentity
if found_user.password_token:
replace_day = 0
try:
replace_day = int(
str(found_user.password_expires_day or 0)
.split(",")[0]
.replace(" days", "")
)
except Exception as e:
err = e
token_is_expired = system_arrow.now() >= system_arrow.get(
str(found_user.password_expiry_begins)
).shift(days=replace_day)
if not password_token == found_user.password_token and token_is_expired:
raise HTTPException(
status_code=401,
detail="Password token is not valid. Please request a new password token.",
)
query_engine = MongoQueryIdentity(company_uuid=found_user.related_company)
domain_via_user = query_engine.get_domain_via_user(
user_uu_id=str(found_user.uu_id)
)["main_domain"]
new_password_dict = {
"password": found_user.create_hashed_password(
domain=domain_via_user, id_=str(found_user.uu_id), password=password
),
"date": str(system_arrow.now().date()),
}
history_dict = PasswordHistoryViaUser(
user_uu_id=str(found_user.uu_id),
password_add=new_password_dict,
access_history_detail={
"request": "",
"ip": "",
},
)
found_user.password_expiry_begins = str(system_arrow.now())
found_user.hash_password = new_password_dict.get("password")
found_user.password_token = "" if found_user.password_token else ""
query_engine.refresh_password_history_via_user(payload=history_dict)
found_user.save()
return found_user
@staticmethod
def reset_password_token(found_user):
found_user.password_expiry_begins = str(system_arrow.now())
found_user.password_token = found_user.generate_token(
Auth.REFRESHER_TOKEN_LENGTH
)
found_user.save()
return found_user.password_token
def generate_refresher_token(self, domain: str, remember_me=False):
from databases import (
UsersTokens,
)
if remember_me:
refresh_token = self.generate_token(Auth.REFRESHER_TOKEN_LENGTH)
if already_token := UsersTokens.filter_by_one(
system=True, user_id=self.id, token_type="RememberMe", domain=domain
).data:
already_token.update(token=refresh_token)
already_token.expires_at = system_arrow.shift(days=3)
already_token.save()
return refresh_token
users_tokens = UsersTokens.filter_by_all(
user_id=self.id, token_type="RememberMe", domain=domain, system=True
).data
if users_tokens:
users_tokens.query.delete()
UsersTokens.save()
users_token = UsersTokens.find_or_create(
user_id=self.id,
token_type="RememberMe",
token=refresh_token,
domain=domain,
)
users_token.save_and_confirm()
return refresh_token
return None
def remainder_day(self):
join_list = [
_ for _ in str(self.password_expires_day).split(",")[0] if _.isdigit()
]
return float(timedelta(days=int("".join(join_list))).seconds)
class UserLoginModule(AuthModule):
@classmethod
def login_user_with_credentials(cls, data, request):
from api_services.redis.auth_actions.auth import save_access_token_to_redis
from databases import (
Users,
People,
MongoQueryIdentity,
)
found_user = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
)
access_token = found_user.generate_access_token()
query_engine = MongoQueryIdentity(company_uuid=found_user.related_company)
if found_user.check_password(password=data.password):
access_object_to_redis = save_access_token_to_redis(
request=request,
found_user=found_user,
domain=data.domain,
access_token=access_token,
)
refresher_token = found_user.generate_refresher_token(
domain=data.domain, remember_me=data.remember_me
)
headers_request = request.headers
headers_request = dict(headers_request)
headers_request["evyos-user-agent"] = headers_request.get("user-agent")
headers_request["evyos-platform"] = headers_request.get("user-agent")
headers_request["evyos-ip-ext"] = "94.54.68.158"
found_user.last_agent = headers_request.get("evyos-user-agent", None)
found_user.last_platform = headers_request.get("evyos-platform", None)
found_user.last_remote_addr = headers_request.get("evyos-ip-ext", None)
found_user.last_seen = str(system_arrow.now())
if ext_ip := headers_request.get("evyos-ip-ext"):
agent = headers_request.get("evyos-user-agent", "")
platform = headers_request.get("evyos-platform", "")
address = requests.get(f"http://ip-api.com/json/{ext_ip}").json()
address_package = {
"city": address["city"],
"zip": address["zip"],
"country": address["country"],
"countryCode": address["countryCode"],
"region": address["region"],
"regionName": address["regionName"],
}
mongo_db = MongoQueryIdentity(
company_uuid=str(found_user.related_company).replace(" ", ""),
storage_reasoning="AccessHistory",
)
filter_query = {
"agent": agent,
"platform": platform,
"address": address_package,
"user_id": found_user.id,
}
already_exits = mongo_db.mongo_engine.filter_by(filter_query) or None
no_address_validates = mongo_db.mongo_engine.get_all()[0] == 0
record_id = uuid.uuid4().__str__()
notice_link = ApiStatic.blacklist_login(record_id=record_id)
found_people = People.filter_one(People.id == found_user.person_id).data
access_via_user = query_engine.update_access_history_via_user(
AccessHistoryViaUser(
**{
"user_uu_id": found_user.uu_id.__str__(),
"access_history": {
"record_id": record_id,
"agent": agent,
"platform": platform,
"address": address_package,
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
# "is_confirmed": True if no_address_validates else False,
# "is_first": True if no_address_validates else False,
},
}
)
)
if already_exits:
update_mongo = mongo_db.mongo_engine.table.update_one(
filter=filter_query,
update={
"$set": {
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
}
},
)
else:
mongo_db.mongo_engine.insert(
payload={
"user_id": found_user.id,
"record_id": record_id,
"agent": agent,
"platform": platform,
"address": address_package,
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
"is_confirmed": True if no_address_validates else False,
"is_first": True if no_address_validates else False,
}
)
found_user.remember_me = bool(data.remember_me)
found_user.save()
return {
"access_token": access_token,
"refresher_token": refresher_token,
"user": found_user,
"access_object": access_object_to_redis,
}
raise HTTPException(
status_code=401,
detail="Login is not successful. Please check your credentials.",
)
# UserLogger.log_error(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=data.access_key,
# agent=found_user.last_agent,
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=found_user.last_platform,
# login_date=str(DateTimeLocal.now()),
# is_login=True,
# )
# )
# if (
# not str(found_people.country_code).lower()
# == str(address_package.get("countryCode")).lower()
# ):
# send_email_completed = send_email(
# subject=f"Dear {found_user.nick_name}, your password has been changed.",
# receivers=[str(found_user.email)],
# html=invalid_ip_or_address_found(
# user_name=found_user.nick_name,
# address=address_package,
# notice_link=notice_link,
# ),
# )
# if not send_email_completed:
# raise HTTPException(
# status_code=400,
# detail="An error occured at sending email. Please contact with support team.",
# )

View File

@@ -0,0 +1,79 @@
class Explanation: ...
class SelectorsBase:
@classmethod
def add_confirmed_filter(cls, first_table, second_table) -> tuple:
return (
first_table.active == True,
first_table.is_confirmed == True,
first_table.deleted == False,
second_table.active == True,
second_table.is_confirmed == True,
second_table.deleted == False,
)
class SelectActionWithEmployee:
@classmethod
def select_action(cls, employee_id, filter_expr: list = None):
if filter_expr is not None:
filter_expr = (cls.__many__table__.employee_id == employee_id, *filter_expr)
data = (
cls.session.query(cls.id)
.select_from(cls)
.join(cls.__many__table__, cls.__many__table__.member_id == cls.id)
.filter(
*filter_expr,
*SelectorsBase.add_confirmed_filter(
first_table=cls, second_table=cls.__many__table__
),
)
)
return cls.query.filter(cls.id.in_([comp[0] for comp in data.all()]))
data = (
cls.session.query(cls.id)
.select_from(cls)
.join(cls.__many__table__, cls.__many__table__.member_id == cls.id)
.filter(
cls.__many__table__.employee_id == employee_id,
*SelectorsBase.add_confirmed_filter(
first_table=cls, second_table=cls.__many__table__
),
)
)
return cls.query.filter(cls.id.in_([comp[0] for comp in data.all()]))
class SelectAction:
@classmethod
def select_action(cls, duty_id_list: list, filter_expr: list = None):
if filter_expr is not None:
data = (
cls.session.query(cls.id)
.select_from(cls)
.join(cls.__many__table__, cls.__many__table__.member_id == cls.id)
.filter(
cls.__many__table__.duties_id.in_(duty_id_list),
*SelectorsBase.add_confirmed_filter(
first_table=cls, second_table=cls.__many__table__
),
*filter_expr,
)
)
return cls.query.filter(cls.id.in_([comp[0] for comp in data.all()]))
data = (
cls.session.query(cls.id)
.select_from(cls)
.join(cls.__many__table__, cls.__many__table__.member_id == cls.id)
.filter(
cls.__many__table__.duties_id.in_(duty_id_list),
*SelectorsBase.add_confirmed_filter(
first_table=cls, second_table=cls.__many__table__
),
)
)
return cls.query.filter(cls.id.in_([comp[0] for comp in data.all()]))

View File

@@ -1,6 +1,8 @@
import datetime
from fastapi import HTTPException
from api_library.date_time_actions.date_functions import system_arrow
from .validations import PasswordHistoryViaUser, DomainViaUser, AccessHistoryViaUser
from .mongo_database import MongoQuery
@@ -69,15 +71,13 @@ class MongoQueryIdentity:
"password_history": [],
}
)
password_history_item = self.mongo_engine.get_one(
match=payload.user_uu_id, field="user_uu_id"
)
password_history_list = password_history_item.get("password_history", [])
hashed_password = payload.password_add.get("password")
for password_in_history in password_history_list:
if password_in_history.get("password") == str(hashed_password):
if str(password_in_history.get("password")) == str(hashed_password):
raise HTTPException(
status_code=400,
detail="Password already used. Please enter a new password that you have not used last 3 times.",
@@ -87,7 +87,6 @@ class MongoQueryIdentity:
password_history_list.pop(0)
password_history_list.append(payload.password_add)
return self.mongo_engine.update(
match=payload.user_uu_id,
payload={

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