Compare commits

...

95 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
330 changed files with 567071 additions and 4545 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 import typing
from typing import Union
from fastapi import status from fastapi import status
from fastapi.requests import Request from fastapi.requests import Request
@@ -35,7 +35,6 @@ from api_validations.validations_request import (
EmployeeSelection, EmployeeSelection,
) )
from api_services import ( from api_services import (
password_is_changed_template,
change_your_password_template, change_your_password_template,
save_access_token_to_redis, save_access_token_to_redis,
update_selected_to_redis, update_selected_to_redis,
@@ -54,6 +53,9 @@ from api_validations.core_response import AlchemyJsonResponse
class AuthenticationLoginEventMethods(MethodToEvent): class AuthenticationLoginEventMethods(MethodToEvent):
event_type = "LOGIN" event_type = "LOGIN"
event_description = "Login via domain and access key : [email] | [phone]"
event_category = "AUTHENTICATION"
__event_keys__ = { __event_keys__ = {
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds", "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( def authentication_login_with_domain_and_creds(
cls, cls,
data: Login, data: Login,
request, request: Request,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
): ):
access_dict = Users.login_user_with_credentials(data=data, request=request) access_dict = Users.login_user_with_credentials(data=data, request=request)
found_user = access_dict.get("user", None) if not access_dict.get("user", None):
if not found_user:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials" 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( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -79,7 +83,7 @@ class AuthenticationLoginEventMethods(MethodToEvent):
"access_token": access_dict.get("access_token"), "access_token": access_dict.get("access_token"),
"refresh_token": access_dict.get("refresher_token"), "refresh_token": access_dict.get("refresher_token"),
"access_object": access_dict.get("access_object"), "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, status_code=status.HTTP_200_OK,
) )
@@ -96,14 +100,13 @@ class AuthenticationSelectEventMethods(MethodToEvent):
def authentication_select_company_or_occupant_type( def authentication_select_company_or_occupant_type(
cls, cls,
request: Request, request: Request,
data: typing.Union[EmployeeSelection, OccupantSelection], data: Union[EmployeeSelection, OccupantSelection],
token_dict: dict = None, 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 isinstance(token_dict, EmployeeTokenObject):
if token_user.user_type == 1: if data.company_uu_id not in token_dict.companies_uu_id_list:
if data.company_uu_id not in token_user.companies_uu_id_list:
return JSONResponse( return JSONResponse(
content={ content={
"completed": False, "completed": False,
@@ -111,41 +114,49 @@ class AuthenticationSelectEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_401_UNAUTHORIZED, 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_ids = [
department.id department.id
for department in Departments.filter_by_active( for department in Departments.filter_all(
company_id=selected_company.id Departments.company_id == selected_company.id,
).data ).data
] ]
duties_ids = [ duties_ids = [
duties.id duties.id
for duties in Duties.filter_active( for duties in Duties.filter_all(
Duties.company_id == selected_company.id, Duties.company_id == selected_company.id,
Duties.department_id.in_(department_ids),
).data ).data
] ]
staff_ids = [ staff_ids = [
staff.id staff.id
for staff in Staff.filter_active( for staff in Staff.filter_all(
Staff.duties_id.in_(duties_ids) Staff.duties_id.in_(duties_ids),
).data ).data
] ]
employee = Employees.filter_active( employee = Employees.filter_one(
Employees.people_id == token_user.person_id, Employees.people_id == token_dict.person_id,
Employees.staff_id.in_(staff_ids), Employees.staff_id.in_(staff_ids),
).data[0] ).data
reachable_event_list_id = Event2Employee.get_event_id_by_employee_id(
reachable_event_list_id, reachable_event_list_uu_id = ( employee_id=employee.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
) )
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( update_selected_to_redis(
request=request, request=request,
add_payload=CompanyToken( add_payload=CompanyToken(
@@ -161,7 +172,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
employee_id=employee.id, employee_id=employee.id,
employee_uu_id=employee.uu_id.__str__(), employee_uu_id=employee.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id, reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
), ),
) )
return JSONResponse( return JSONResponse(
@@ -171,29 +181,41 @@ class AuthenticationSelectEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
) )
elif token_user.user_type == 2: elif isinstance(token_dict, OccupantTokenObject):
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id) occupant_type = OccupantTypes.filter_by_one(
system=True, uu_id=data.occupant_uu_id
).data
if not occupant_type: if not occupant_type:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, status_code=status.HTTP_401_UNAUTHORIZED,
detail="Occupant Type is not found", 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: if not build_part:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, status_code=status.HTTP_401_UNAUTHORIZED,
detail="Build Part is not found", detail="Build Part is not found",
) )
build = Build.find_one(id=build_part.build_id) build = Build.filter_one(
related_company = RelationshipEmployee2Build.find_one(member_id=build.id) Build.id == build_part.build_id,
company_related = Companies.find_one(id=related_company.company_id) ).data
responsible_employee = Employees.find_one(id=related_company.employee_id) related_company = RelationshipEmployee2Build.filter_one(
if selected_occupant_type := BuildLivingSpace.find_one( RelationshipEmployee2Build.member_id == build.id,
occupant_type=occupant_type.id, ).data
person_id=token_user.person_id, company_related = Companies.filter_one(
build_parts_id=build_part.id, Companies.id == related_company.company_id,
): ).data
reachable_event_list_id, reachable_event_list_uu_id = ( 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( Event2Occupant.get_event_id_by_build_living_space_id(
build_living_space_id=selected_occupant_type.id build_living_space_id=selected_occupant_type.id
) )
@@ -215,7 +237,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
responsible_company_id=company_related.id, responsible_company_id=company_related.id,
responsible_company_uuid=company_related.uu_id.__str__(), responsible_company_uuid=company_related.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id, reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
), ),
) )
return JSONResponse( return JSONResponse(
@@ -239,8 +260,9 @@ class AuthenticationCheckTokenEventMethods(MethodToEvent):
} }
@classmethod @classmethod
def authentication_login_with_domain_and_creds( def authentication_check_token_is_valid(
cls, request, token_dict: dict = None cls,
request,
): ):
if get_object_via_access_key(request=request): if get_object_via_access_key(request=request):
return JSONResponse( return JSONResponse(
@@ -261,16 +283,20 @@ class AuthenticationRefreshEventMethods(MethodToEvent):
} }
@classmethod @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)) access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
if token_user := get_object_via_access_key(request=request): if token_user := get_object_via_access_key(request=request):
if found_user := Users.find_one(uu_id=token_user.get("uu_id")): if found_user := Users.filter_one(
user_token = UsersTokens.find_one( Users.uu_id == token_user.get("uu_id"),
domain=found_user.domain_name, ).data:
user_id=found_user.id, user_token = UsersTokens.filter_one(
token_type="RememberMe", UsersTokens.domain == found_user.domain_name,
) UsersTokens.user_id == found_user.id,
UsersTokens.token_type == "RememberMe",
).data
access_dict = { access_dict = {
"access_token": access_token, "access_token": access_token,
"refresh_token": getattr(user_token, "token", None), "refresh_token": getattr(user_token, "token", None),
@@ -298,13 +324,17 @@ class AuthenticationChangePasswordEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_change_password( 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 found_user := Users.filter_one(
if token_user.user_type == 1: Users.id == token_dict.user_id,
if found_user := Users.find_one(uu_id=token_user.uu_id): ).data:
if found_user.check_password(data.old_password): if found_user.check_password(data.old_password):
found_user.set_password(data.new_password) found_user.create_password(
found_user=found_user, password=data.new_password
)
return JSONResponse( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -334,25 +364,35 @@ class AuthenticationCreatePasswordEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_create_password( def authentication_create_password(
cls, request, data: CreatePassword, token_dict: dict = None cls,
data: CreatePassword,
): ):
if not data.re_password == data.password: if not data.re_password == data.password:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match" status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
) )
if found_user := Users.find_one(password_token=data.password_token): found_user = Users.filter_one(
found_user.create_password(password=data.password) Users.password_token == data.password_token,
found_user.password_token = None ).data
found_user.save() if not found_user:
send_email_completed = send_email( return JSONResponse(
subject=f"Dear {found_user.user_tag}, your password has been changed.", content={
receivers=[str(found_user.email)], "completed": False,
html=password_is_changed_template(user_name=found_user.user_tag), "message": "Record not found",
) "data": {},
if not send_email_completed: },
raise HTTPException( status_code=status.HTTP_202_ACCEPTED,
status_code=400, detail="Email can not be sent. Try again later"
) )
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( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -361,13 +401,51 @@ class AuthenticationCreatePasswordEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_200_OK, 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( return JSONResponse(
content={ content={
"completed": False, "completed": True,
"message": "Record not found", "message": "Password change link is sent to your email or phone",
"data": {}, "data": found_user.get_dict(),
}, },
status_code=status.HTTP_202_ACCEPTED, status_code=status.HTTP_200_OK,
) )
@@ -380,10 +458,14 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_disconnect_user( 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.filter_one(
found_user = Users.find_one(uu_id=token_user.get("uu_id")) Users.uu_id == token_dict.person_uu_id,
).data
if not found_user: if not found_user:
return JSONResponse( return JSONResponse(
content={ content={
@@ -394,10 +476,11 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
status_code=status.HTTP_202_ACCEPTED, status_code=status.HTTP_202_ACCEPTED,
) )
if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id): if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id):
for key in already_tokens: for key, token_user in already_tokens.items():
token_user = json.loads(redis_cli.get(key) or {})
redis_cli.delete(key) 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"),
)
selected_user.remove_refresher_token( selected_user.remove_refresher_token(
domain=data.domain, disconnect=True domain=data.domain, disconnect=True
) )
@@ -438,15 +521,26 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_logout_user( def authentication_logout_user(
cls, request: Request, data: Logout, token_dict: dict = None cls, data: Logout, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
): ):
token_user = None from api_services.redis.functions import get_object_via_user_uu_id
if already_tokens := get_object_via_access_key(request=request):
for key in already_tokens: if not token_dict:
token_user = json.loads(redis_cli.get(key) or {}) return JSONResponse(
if token_user.get("domain") == data.domain: content={
redis_cli.delete(key) "completed": False,
selected_user = Users.find_one(uu_id=token_user.get("uu_id")) "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) selected_user.remove_refresher_token(domain=data.domain)
# UserLogger.log_error( # UserLogger.log_error(
# str( # str(
@@ -471,14 +565,6 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
) )
return JSONResponse(
content={
"completed": False,
"message": "Logout is not successfully completed",
"data": None,
},
status_code=status.HTTP_202_ACCEPTED,
)
class AuthenticationRefreshTokenEventMethods(MethodToEvent): class AuthenticationRefreshTokenEventMethods(MethodToEvent):
@@ -490,17 +576,23 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_refresher_token( 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_refresher = UsersTokens.filter_by_one(
token=data.refresh_token, domain=data.domain system=True, token=data.refresh_token, domain=data.domain
) )
if not token_refresher: if not token_refresher:
return JSONResponse( return JSONResponse(
content={"completed": False, "message": "Invalid data", "data": {}}, content={"completed": False, "message": "Invalid data", "data": {}},
status_code=status.HTTP_202_ACCEPTED, 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 found_user: Users = found_user
access_key = save_access_token_to_redis( access_key = save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain request=request, found_user=found_user, domain=data.domain
@@ -555,7 +647,10 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_forgot_password( 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( found_user: Users = Users.check_user_exits(
access_key=data.access_key, domain=data.domain access_key=data.access_key, domain=data.domain
@@ -614,7 +709,10 @@ class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_download_avatar( 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( found_user = Users.check_user_exits(
access_key=data.access_key, domain=data.domain access_key=data.access_key, domain=data.domain
@@ -663,6 +761,9 @@ AuthenticationChangePasswordEventMethod = AuthenticationChangePasswordEventMetho
AuthenticationCreatePasswordEventMethod = AuthenticationCreatePasswordEventMethods( AuthenticationCreatePasswordEventMethod = AuthenticationCreatePasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/create_password") action=ActionsSchema(endpoint="/authentication/create_password")
) )
AuthenticationResetPasswordEventMethod = AuthenticationResetPasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/reset_password")
)
AuthenticationDisconnectUserEventMethod = AuthenticationDisconnectUserEventMethods( AuthenticationDisconnectUserEventMethod = AuthenticationDisconnectUserEventMethods(
action=ActionsSchema(endpoint="/authentication/disconnect") action=ActionsSchema(endpoint="/authentication/disconnect")
) )

View File

@@ -19,10 +19,14 @@ from api_validations.core_response import AlchemyJsonResponse
class EventBindOccupantEventMethods(MethodToEvent): class EventBindOccupantEventMethods(MethodToEvent):
event_type = "UPDATE" event_type = "UPDATE"
__event_keys__ = { __event_keys__ = {
"5702f0a9-fe8f-4aae-922e-6e04b497ef6a": "bind_events_occupant_super_user", "5702f0a9-fe8f-4aae-922e-6e04b497ef6a": "bind_events_occupant_super_user",
} }
__event_validation__ = {
"5702f0a9-fe8f-4aae-922e-6e04b497ef6a": RegisterEvents2Occupant
}
@classmethod @classmethod
def bind_events_occupant_super_user( def bind_events_occupant_super_user(
@@ -37,7 +41,10 @@ class EventBindOccupantEventMethods(MethodToEvent):
detail="This employee is not authorized to add event to this occupant", 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: if not occupants_build_part:
return JSONResponse( return JSONResponse(
content={ content={
@@ -48,7 +55,9 @@ class EventBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND, 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: if not occupant_occupant_type:
return JSONResponse( return JSONResponse(
content={ content={
@@ -59,8 +68,8 @@ class EventBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
) )
events_to_add_to_occupant = Events.filter_active( events_to_add_to_occupant = Events.filter_all(
Events.uu_id.in_(list(data.event_uu_id_list)) Events.uu_id.in_(list(data.event_uu_id_list)),
) )
if not events_to_add_to_occupant.data: if not events_to_add_to_occupant.data:
return JSONResponse( return JSONResponse(
@@ -85,11 +94,11 @@ class EventBindOccupantEventMethods(MethodToEvent):
status_code=status.HTTP_401_UNAUTHORIZED, status_code=status.HTTP_401_UNAUTHORIZED,
) )
occupant_to_add_event = BuildLivingSpace.find_one( occupant_to_add_event = BuildLivingSpace.filter_one(
build_parts_id=occupants_build_part.id, BuildLivingSpace.build_parts_id == occupants_build_part.id,
occupant_type=occupant_occupant_type.id, BuildLivingSpace.occupant_type == occupant_occupant_type.id,
) BuildLivingSpace.active == True,
).data
if not occupant_to_add_event: if not occupant_to_add_event:
return JSONResponse( return JSONResponse(
content={ content={
@@ -137,6 +146,9 @@ class EventBindEmployeeEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"c93a3009-65a0-498d-9191-04484d5cde81": "bind_events_employee", "c93a3009-65a0-498d-9191-04484d5cde81": "bind_events_employee",
} }
__event_validation__ = {
"c93a3009-65a0-498d-9191-04484d5cde81": RegisterEvents2Occupant
}
@classmethod @classmethod
def bind_events_employee( def bind_events_employee(

View File

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

View File

@@ -19,17 +19,24 @@ class Config:
"/test/create/test/gateway", "/test/create/test/gateway",
"/test/create/test/company", "/test/create/test/company",
"/infos/current_date", "/infos/current_date",
"/authentication/select",
"/authentication/login", "/authentication/login",
"/authentication/logout", "/authentication/logout",
"/authentication/refresher", "/authentication/refresher",
"/authentication/refresh", "/authentication/refresh",
"/authentication/disconnect", "/authentication/disconnect",
"/authentication/create_password", "/authentication/create_password",
"/authentication/change_password", "/authentication/reset_password",
"/authentication/forgot", "/authentication/forgot",
"/authentication/avatar", "/authentication/valid",
"/api/Contact/Us/current_date", "/api/Contact/Us/current_date",
] ]
NOT_SECURE_PATHS = [
"/access/endpoints/available",
"/access/endpoint/available",
"/validations/endpoint",
"/authentication/avatar",
]
APP_NAME = "evyos-web-api-gateway" APP_NAME = "evyos-web-api-gateway"
TITLE = "WAG API Web Api Gateway" TITLE = "WAG API Web Api Gateway"
@@ -39,7 +46,7 @@ class Config:
class ApiStatic: class ApiStatic:
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg" 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/" BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/" APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
@@ -117,7 +124,7 @@ class TestDatabase:
SQL: str = "postgresql+psycopg2" SQL: str = "postgresql+psycopg2"
USERNAME: str = "berkay_wag_user" USERNAME: str = "berkay_wag_user"
PASSWORD: str = "berkay_wag_user_password" PASSWORD: str = "berkay_wag_user_password"
HOST: str = "10.10.2.44" HOST: str = "10.10.2.46"
PORT: str = "5434" PORT: str = "5434"
DATABASE_NAME: str = "wag_database" DATABASE_NAME: str = "wag_database"
DATABASE_URL = f"{SQL}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE_NAME}" DATABASE_URL = f"{SQL}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE_NAME}"

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,9 @@
import datetime
import json import json
import typing import typing
from typing import Union
import arrow
from fastapi import status from fastapi import status
from fastapi.requests import Request from fastapi.requests import Request
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
@@ -15,13 +18,13 @@ from databases import (
BuildLivingSpace, BuildLivingSpace,
BuildParts, BuildParts,
Build, Build,
RelationshipEmployee2PostCode,
Duty, Duty,
Event2Occupant, Event2Occupant,
Event2Employee, Event2Employee,
Users, Users,
UsersTokens, UsersTokens,
OccupantTypes, OccupantTypes,
RelationshipEmployee2Build,
) )
from api_services import ( from api_services import (
@@ -35,10 +38,16 @@ from api_services import (
change_your_password_template, 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_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 databases.no_sql_models.login_handlers import load_user_with_erp_details
from api_validations.validations_request import ( from api_validations.validations_request import (
@@ -56,16 +65,21 @@ from api_validations.validations_request import (
class AuthenticationLoginEventMethods(MethodToEvent): class AuthenticationLoginEventMethods(MethodToEvent):
event_type = "LOGIN" event_type = "LOGIN"
event_description = "Login via domain and access key : [email] | [phone]"
event_category = "AUTHENTICATION"
__event_keys__ = { __event_keys__ = {
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds", "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 @classmethod
def authentication_login_with_domain_and_creds( def authentication_login_with_domain_and_creds(
cls, cls,
data: Login, data: Login,
request, request,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
): ):
access_dict = Users.login_user_with_credentials(data=data, request=request) access_dict = Users.login_user_with_credentials(data=data, request=request)
found_user = access_dict.get("user", None) found_user = access_dict.get("user", None)
@@ -89,23 +103,28 @@ class AuthenticationLoginEventMethods(MethodToEvent):
class AuthenticationSelectEventMethods(MethodToEvent): class AuthenticationSelectEventMethods(MethodToEvent):
event_type = "SELECT" event_type = "LOGIN"
event_description = "Select Employee Duty or Occupant Type"
event_category = "AUTHENTICATION"
__event_keys__ = { __event_keys__ = {
"cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type", "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 @classmethod
def authentication_select_company_or_occupant_type( def authentication_select_company_or_occupant_type(
cls, cls,
request: Request, request: Request,
data: typing.Union[EmployeeSelection, OccupantSelection], data: Union[EmployeeSelection, OccupantSelection],
token_dict: dict = None, token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
): ):
from api_objects import OccupantToken, CompanyToken from api_objects import OccupantToken, CompanyToken
token_user = get_object_via_access_key(request=request) if isinstance(token_dict, EmployeeTokenObject):
if token_user.user_type == 1: if data.company_uu_id not in token_dict.companies_uu_id_list:
if data.company_uu_id not in token_user.companies_uu_id_list:
return JSONResponse( return JSONResponse(
content={ content={
"completed": False, "completed": False,
@@ -113,41 +132,49 @@ class AuthenticationSelectEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_401_UNAUTHORIZED, 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_ids = [
department.id department.id
for department in Departments.filter_by_active( for department in Departments.filter_all(
company_id=selected_company.id Departments.company_id == selected_company.id,
).data ).data
] ]
duties_ids = [ duties_ids = [
duties.id duties.id
for duties in Duties.filter_active( for duties in Duties.filter_all(
Duties.company_id == selected_company.id, Duties.company_id == selected_company.id,
Duties.department_id.in_(department_ids),
).data ).data
] ]
staff_ids = [ staff_ids = [
staff.id staff.id
for staff in Staff.filter_active( for staff in Staff.filter_all(
Staff.duties_id.in_(duties_ids) Staff.duties_id.in_(duties_ids),
).data ).data
] ]
employee = Employees.filter_active( employee = Employees.filter_one(
Employees.people_id == token_user.person_id, Employees.people_id == token_dict.person_id,
Employees.staff_id.in_(staff_ids), Employees.staff_id.in_(staff_ids),
).data[0] ).data
reachable_event_list_id = Event2Employee.get_event_id_by_employee_id(
reachable_event_list_id, reachable_event_list_uu_id = ( employee_id=employee.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
) )
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( update_selected_to_redis(
request=request, request=request,
add_payload=CompanyToken( add_payload=CompanyToken(
@@ -163,7 +190,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
employee_id=employee.id, employee_id=employee.id,
employee_uu_id=employee.uu_id.__str__(), employee_uu_id=employee.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id, reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
), ),
) )
return JSONResponse( return JSONResponse(
@@ -173,29 +199,41 @@ class AuthenticationSelectEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
) )
elif token_user.user_type == 2: elif isinstance(token_dict, OccupantTokenObject):
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id) occupant_type = OccupantTypes.filter_by_one(
system=True, uu_id=data.occupant_uu_id
).data
if not occupant_type: if not occupant_type:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, status_code=status.HTTP_401_UNAUTHORIZED,
detail="Occupant Type is not found", 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: if not build_part:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, status_code=status.HTTP_401_UNAUTHORIZED,
detail="Build Part is not found", detail="Build Part is not found",
) )
build = Build.find_one(id=build_part.build_id) build = Build.filter_one(
related_company = RelationshipEmployee2Build.find_one(member_id=build.id) Build.id == build_part.build_id,
company_related = Companies.find_one(id=related_company.company_id) ).data
responsible_employee = Employees.find_one(id=related_company.employee_id) related_company = RelationshipEmployee2Build.filter_one(
if selected_occupant_type := BuildLivingSpace.find_one( RelationshipEmployee2Build.member_id == build.id,
occupant_type=occupant_type.id, ).data
person_id=token_user.person_id, company_related = Companies.filter_one(
build_parts_id=build_part.id, Companies.id == related_company.company_id,
): ).data
reachable_event_list_id, reachable_event_list_uu_id = ( 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( Event2Occupant.get_event_id_by_build_living_space_id(
build_living_space_id=selected_occupant_type.id build_living_space_id=selected_occupant_type.id
) )
@@ -217,7 +255,6 @@ class AuthenticationSelectEventMethods(MethodToEvent):
responsible_company_id=company_related.id, responsible_company_id=company_related.id,
responsible_company_uuid=company_related.uu_id.__str__(), responsible_company_uuid=company_related.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id, reachable_event_list_id=reachable_event_list_id,
reachable_event_list_uu_id=reachable_event_list_uu_id,
), ),
) )
return JSONResponse( return JSONResponse(
@@ -235,14 +272,21 @@ class AuthenticationSelectEventMethods(MethodToEvent):
class AuthenticationCheckTokenEventMethods(MethodToEvent): class AuthenticationCheckTokenEventMethods(MethodToEvent):
event_type = "CHECK" event_type = "LOGIN"
event_description = "Check Token is valid for user"
event_category = "AUTHENTICATION"
__event_keys__ = { __event_keys__ = {
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid", "73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
} }
__event_validation__ = {
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
}
@classmethod @classmethod
def authentication_login_with_domain_and_creds( def authentication_check_token_is_valid(
cls, request, token_dict: dict = None cls,
request,
): ):
if get_object_via_access_key(request=request): if get_object_via_access_key(request=request):
return JSONResponse( return JSONResponse(
@@ -257,21 +301,35 @@ class AuthenticationCheckTokenEventMethods(MethodToEvent):
class AuthenticationRefreshEventMethods(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__ = { __event_keys__ = {
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info", "48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
} }
__event_validation__ = {
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
}
@classmethod @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)) access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
if token_user := get_object_via_access_key(request=request): if token_user := get_object_via_access_key(request=request):
if found_user := Users.find_one(uu_id=token_user.get("uu_id")): if found_user := Users.filter_one(
user_token = UsersTokens.find_one( Users.uu_id == token_user.get("uu_id")
domain=found_user.domain_name, ).data:
user_id=found_user.id, user_token = UsersTokens.filter_one(
token_type="RememberMe", UsersTokens.domain == found_user.domain_name,
) UsersTokens.user_id == found_user.id,
UsersTokens.token_type == "RememberMe",
).data
access_dict = { access_dict = {
"access_token": access_token, "access_token": access_token,
"refresh_token": getattr(user_token, "token", None), "refresh_token": getattr(user_token, "token", None),
@@ -292,18 +350,25 @@ class AuthenticationRefreshEventMethods(MethodToEvent):
class AuthenticationChangePasswordEventMethods(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__ = { __event_keys__ = {
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password", "f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
} }
__event_validation__ = {
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
}
@classmethod @classmethod
def authentication_change_password( 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 isinstance(token_dict, EmployeeTokenObject):
if token_user.user_type == 1: if found_user := Users.filter_one(Users.uu_id == token_dict.uu_id).data:
if found_user := Users.find_one(uu_id=token_user.uu_id):
if found_user.check_password(data.old_password): if found_user.check_password(data.old_password):
found_user.set_password(data.new_password) found_user.set_password(data.new_password)
return JSONResponse( return JSONResponse(
@@ -328,23 +393,29 @@ class AuthenticationChangePasswordEventMethods(MethodToEvent):
class AuthenticationCreatePasswordEventMethods(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__ = { __event_keys__ = {
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password", "c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
} }
__event_validation__ = {
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
}
@classmethod @classmethod
def authentication_create_password( def authentication_create_password(cls, data: CreatePassword):
cls, request, data: CreatePassword, token_dict: dict = None
):
if not data.re_password == data.password: if not data.re_password == data.password:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match" status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
) )
if found_user := Users.find_one(password_token=data.password_token): if found_user := Users.filter_one(
found_user.create_password(password=data.password) Users.password_token == data.password_token
found_user.password_token = None ).data:
found_user.create_password(found_user=found_user, password=data.password)
found_user.password_token = ""
found_user.save() found_user.save()
send_email_completed = send_email( send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, your password has been changed.", subject=f"Dear {found_user.user_tag}, your password has been changed.",
@@ -375,18 +446,22 @@ class AuthenticationCreatePasswordEventMethods(MethodToEvent):
class AuthenticationDisconnectUserEventMethods(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__ = { __event_keys__ = {
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user", "8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
} }
__event_validation__ = {
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
}
@classmethod @classmethod
def authentication_disconnect_user( def authentication_disconnect_user(
cls, request: Request, data: Logout, token_dict: dict = None cls, data: Logout, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
): ):
found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
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: if not found_user:
return JSONResponse( return JSONResponse(
content={ content={
@@ -396,34 +471,20 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_202_ACCEPTED, status_code=status.HTTP_202_ACCEPTED,
) )
if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id): if already_tokens := get_object_via_user_uu_id(user_id=str(found_user.uu_id)):
for key in already_tokens: for key, token_user in already_tokens.items():
token_user = json.loads(redis_cli.get(key) or {})
redis_cli.delete(key) 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( selected_user.remove_refresher_token(
domain=data.domain, disconnect=True 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( return JSONResponse(
content={ content={
"completed": True, "completed": True,
"message": "All sessions are disconnected", "message": "All sessions are disconnected",
"data": token_user, "data": selected_user.get_dict(),
}, },
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
) )
@@ -434,10 +495,17 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
class AuthenticationLogoutEventMethods(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__ = { __event_keys__ = {
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user", "5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
} }
__event_validation__ = {
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
}
@classmethod @classmethod
def authentication_logout_user( def authentication_logout_user(
@@ -449,23 +517,11 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
token_user = json.loads(redis_cli.get(key) or {}) token_user = json.loads(redis_cli.get(key) or {})
if token_user.get("domain") == data.domain: if token_user.get("domain") == data.domain:
redis_cli.delete(key) 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) 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( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -486,24 +542,34 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
class AuthenticationRefreshTokenEventMethods(MethodToEvent): class AuthenticationRefreshTokenEventMethods(MethodToEvent):
event_type = "UPDATE" event_type = "LOGIN"
event_description = "Refresh access token with refresher token"
event_category = "AUTHENTICATION"
__event_keys__ = { __event_keys__ = {
"c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token", "c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
} }
__event_validation__ = {
"c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
}
@classmethod @classmethod
def authentication_refresher_token( def authentication_refresher_token(
cls, request: Request, data: Remember, token_dict: dict = None cls, request: Request, data: Remember, token_dict: dict = None
): ):
token_refresher = UsersTokens.find_one( token_refresher = UsersTokens.filter_by_one(
token=data.refresh_token, domain=data.domain token=data.refresh_token,
) domain=data.domain,
**UsersTokens.valid_record_dict,
).data
if not token_refresher: if not token_refresher:
return JSONResponse( return JSONResponse(
content={"completed": False, "message": "Invalid data", "data": {}}, content={"completed": False, "message": "Invalid data", "data": {}},
status_code=status.HTTP_202_ACCEPTED, 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 found_user: Users = found_user
access_key = save_access_token_to_redis( access_key = save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain request=request, found_user=found_user, domain=data.domain
@@ -513,22 +579,7 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
found_user.last_remote_addr = getattr( found_user.last_remote_addr = getattr(
request, "remote_addr", None request, "remote_addr", None
) or request.headers.get("X-Forwarded-For", None) ) or request.headers.get("X-Forwarded-For", None)
found_user.last_seen = str(DateTimeLocal.now()) found_user.last_seen = str(system_arrow.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,
# )
# )
# )
return JSONResponse( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -551,14 +602,22 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
class AuthenticationForgotPasswordEventMethods(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__ = { __event_keys__ = {
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password", "e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
} }
__event_validation__ = {
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
}
@classmethod @classmethod
def authentication_forgot_password( 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( found_user: Users = Users.check_user_exits(
access_key=data.access_key, domain=data.domain access_key=data.access_key, domain=data.domain
@@ -566,21 +625,6 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
forgot_key = save_access_token_to_redis( forgot_key = save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain 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) forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key)
send_email_completed = send_email( send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, your forgot password link has been sent.", subject=f"Dear {found_user.user_tag}, your forgot password link has been sent.",
@@ -593,9 +637,8 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
raise HTTPException( raise HTTPException(
status_code=400, detail="Email can not be sent. Try again later" status_code=400, detail="Email can not be sent. Try again later"
) )
found_user.password_token = forgot_key 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() found_user.save()
return JSONResponse( return JSONResponse(
@@ -608,43 +651,97 @@ 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): class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
event_type = "SELECT" event_type = "LOGIN"
event_description = "Download avatar icon and profile info of user"
event_category = "AUTHENTICATION"
__event_keys__ = { __event_keys__ = {
"c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar", "c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
} }
__event_validation__ = {
"c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
}
@classmethod @classmethod
def authentication_download_avatar( 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( if found_user := Users.filter_one(Users.id == token_dict.user_id).data:
access_key=data.access_key, domain=data.domain 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( return JSONResponse(
content={ content={
"completed": True, "completed": True,
"message": "Avatar and profile is shared via user credentials", "message": "Avatar and profile is shared via user credentials",
"data": { "data": {
"last_seen": str(found_user.last_seen), "lang": token_dict.lang,
"full_name": found_user.person.full_name,
"avatar": found_user.avatar, "avatar": found_user.avatar,
"remember_me": found_user.remember_me, "remember_me": found_user.remember_me,
"expiry_ends": str(found_user.expiry_ends), "expiry_ends": str(found_user.expiry_ends),
"expired_str": str( "expired_str": expired_starts,
DateTimeLocal.now() "expired_int": int(expired_int),
- DateTimeLocal.get(str(found_user.expiry_ends))
),
"expired_int": int(
(
DateTimeLocal.now()
- DateTimeLocal.get(str(found_user.expiry_ends))
).days
),
}, },
}, },
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,
)
AuthenticationLoginEventMethod = AuthenticationLoginEventMethods( AuthenticationLoginEventMethod = AuthenticationLoginEventMethods(
@@ -680,3 +777,68 @@ AuthenticationForgotPasswordEventMethod = AuthenticationForgotPasswordEventMetho
AuthenticationDownloadAvatarEventMethod = AuthenticationDownloadAvatarEventMethods( AuthenticationDownloadAvatarEventMethod = AuthenticationDownloadAvatarEventMethods(
action=ActionsSchema(endpoint="/authentication/avatar") 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 import typing
from typing import Union
from fastapi import status, HTTPException from fastapi import status, HTTPException
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
@@ -18,9 +19,9 @@ from api_validations.validations_request import (
PatchRecord, PatchRecord,
ListOptions, ListOptions,
) )
from api_validations.validations_response import ListBuildingResponse
from api_validations.core_response import AlchemyJsonResponse from api_validations.core_response import AlchemyJsonResponse
from api_events.events.abstract_class import MethodToEvent, ActionsSchema 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, OccupantTokenObject
@@ -28,9 +29,15 @@ from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObj
class BuildListEventMethods(MethodToEvent): class BuildListEventMethods(MethodToEvent):
event_type = "SELECT" event_type = "SELECT"
event_description = ""
event_category = ""
__event_keys__ = { __event_keys__ = {
"68b3b5ed-b74c-4a27-820f-3959214e94e9": "build_list", "68b3b5ed-b74c-4a27-820f-3959214e94e9": "build_list",
} }
__event_validation__ = {
"68b3b5ed-b74c-4a27-820f-3959214e94e9": ListBuildingResponse,
}
@classmethod @classmethod
def build_list( def build_list(
@@ -39,31 +46,36 @@ class BuildListEventMethods(MethodToEvent):
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject], token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
): ):
if isinstance(token_dict, OccupantTokenObject): if isinstance(token_dict, OccupantTokenObject):
Build.pre_query = Build.filter_active( Build.pre_query = Build.filter_all(
Build.id == token_dict.selected_occupant.build_id Build.id == token_dict.selected_occupant.build_id,
).query ).query
elif isinstance(token_dict, EmployeeTokenObject): elif isinstance(token_dict, EmployeeTokenObject):
Build.pre_query = Build.select_action( Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id employee_id=token_dict.selected_company.employee_id
) )
Build.filter_attr = list_options Build.filter_attr = list_options
records = Build.filter_active( records = Build.filter_all()
*Build.get_smart_query(smart_query=list_options.query)
)
return AlchemyJsonResponse( return AlchemyJsonResponse(
completed=True, completed=True,
message="Building Records are listed", message="Building Records are listed",
result=records, result=records,
response_model=ListBuildingResponse,
) )
class BuildCreateEventMethods(MethodToEvent): class BuildCreateEventMethods(MethodToEvent):
event_type = "CREATE" event_type = "CREATE"
event_description = ""
event_category = ""
__event_keys__ = { __event_keys__ = {
"a2271854-6b90-43da-a440-a62b70d90528": "build_create", "a2271854-6b90-43da-a440-a62b70d90528": "build_create",
"b67ee709-0992-4604-9f90-fb1da10d5cf9": "create_building_employee", "b67ee709-0992-4604-9f90-fb1da10d5cf9": "create_building_employee",
} }
__event_validation__ = {
"a2271854-6b90-43da-a440-a62b70d90528": InsertBuild,
"b67ee709-0992-4604-9f90-fb1da10d5cf9": InsertBuild,
}
@classmethod @classmethod
def build_create(cls, data: InsertBuild, token_dict: EmployeeTokenObject): def build_create(cls, data: InsertBuild, token_dict: EmployeeTokenObject):
@@ -80,14 +92,15 @@ class BuildCreateEventMethods(MethodToEvent):
) )
created_build = Build.create_action(data=data, token=token_dict) created_build = Build.create_action(data=data, token=token_dict)
if not created_build.is_found: build_type = BuildTypes.filter_by_one(
build_type = BuildTypes.find_one(type_code="APT_YNT") **BuildTypes.valid_record_dict, type_code="APT_YNT"
).data
if not build_type: if not build_type:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail="Build type APT_YNT is not found. Please contact with your system administrator.", detail="Build type APT_YNT is not found. Please contact with your system administrator.",
) )
api_enum = ApiEnumDropdown.find_one(enum_class="Directions", key="NN") api_enum = ApiEnumDropdown.filter_by_one(enum_class="Directions", key="NN").data
if not api_enum: if not api_enum:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
@@ -104,11 +117,20 @@ class BuildCreateEventMethods(MethodToEvent):
part_direction_uu_id=str(api_enum.uu_id), part_direction_uu_id=str(api_enum.uu_id),
part_code="MAN-ROOM", part_code="MAN-ROOM",
human_livable=False, human_livable=False,
is_confirmed=True,
) )
man_build_part = BuildParts.find_or_create(**build_parts) man_build_part = BuildParts.find_or_create(**build_parts)
if not man_build_part.is_found: created_build.save()
created_build.update(management_room_id=man_build_part.id) 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( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -117,10 +139,6 @@ class BuildCreateEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
) )
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}",
)
@classmethod @classmethod
def create_building_employee( def create_building_employee(
@@ -128,8 +146,8 @@ class BuildCreateEventMethods(MethodToEvent):
): ):
records = Addresses.list_via_employee( records = Addresses.list_via_employee(
token_dict=token_dict, filter_expr=[Addresses.uu_id == data.address_uu_id] token_dict=token_dict, filter_expr=[Addresses.uu_id == data.address_uu_id]
) ).data
if not records.data: if not records:
raise HTTPException( raise HTTPException(
status_code=404, status_code=404,
detail=f"This address {data.address_uu_id} is not found in the user's address list.", detail=f"This address {data.address_uu_id} is not found in the user's address list.",
@@ -148,13 +166,13 @@ class BuildCreateEventMethods(MethodToEvent):
) )
created_build = Build.create_action(data=data, token=token_dict) created_build = Build.create_action(data=data, token=token_dict)
if not created_build.is_found:
RelationshipEmployee2Build.find_or_create( created_build_relation = RelationshipEmployee2Build.find_or_create(
company_id=token_dict.selected_company.company_id, company_id=token_dict.selected_company.company_id,
member_id=created_build.id, member_id=created_build.id,
employee_id=token_dict.selected_company.employee_id, employee_id=token_dict.selected_company.employee_id,
is_confirmed=True,
) )
created_build.save()
return JSONResponse( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -163,33 +181,62 @@ class BuildCreateEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_200_OK, 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}",
)
class BuildUpdateEventMethods(MethodToEvent): class BuildUpdateEventMethods(MethodToEvent):
event_type = "UPDATE" event_type = "UPDATE"
event_description = ""
event_category = ""
__class_key__ = ""
__event_keys__ = { __event_keys__ = {
"5ad38a66-1189-451e-babb-77de2d63d757": "build_update", "5ad38a66-1189-451e-babb-77de2d63d757": "build_update",
} }
__event_validation__ = {
"5ad38a66-1189-451e-babb-77de2d63d757": UpdateBuild,
}
@classmethod @classmethod
def build_update(cls, build_uu_id: str, data: UpdateBuild, token_dict): 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( Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id employee_id=token_dict.selected_company.employee_id
) )
if Build.filter_active(Build.person_id == token_dict.person_id): updated_build = Build.update_action(
if updated_build := Build.update_action(
data=data, token=token_dict, build_uu_id=build_uu_id data=data, token=token_dict, build_uu_id=build_uu_id
): )
Build.save()
return JSONResponse( return JSONResponse(
content={ content={
"completed": True, "completed": True,
"message": "Update Build record", "message": "Update Build record",
"data": updated_build, "data": updated_build.get_dict(),
},
status_code=status.HTTP_200_OK,
)
elif isinstance(token_dict, EmployeeTokenObject):
find_one_build = Build.filter_one(
Build.uu_id == build_uu_id,
).data
access_authorized_build = Build.select_action(
employee_id=token_dict.selected_company.employee_id,
filter_expr=[Build.id == find_one_build.id],
)
if access_authorized_build.count:
updated_build = Build.update_action(
data=data, token=token_dict, build_uu_id=build_uu_id
)
return JSONResponse(
content={
"completed": True,
"message": "Update Build record",
"data": updated_build.get_dict(),
}, },
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
) )
@@ -202,13 +249,21 @@ class BuildUpdateEventMethods(MethodToEvent):
class BuildPatchEventMethods(MethodToEvent): class BuildPatchEventMethods(MethodToEvent):
event_type = "PATCH" event_type = "PATCH"
event_description = ""
event_category = ""
__event_keys__ = { __event_keys__ = {
"e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch", "e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch",
} }
__event_validation__ = {
"e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch",
}
@classmethod @classmethod
def build_patch(cls, build_uu_id: str, data: PatchRecord, token_dict): 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( access_authorized_build = Build.select_action(
employee_id=token_dict.selected_company.employee_id, employee_id=token_dict.selected_company.employee_id,
filter_expr=[Build.id == find_one_build.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_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject 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,6 +1,9 @@
from typing import Union
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from fastapi import status from fastapi import status
from api_validations.validations_response.parts import BuildPartsListResponse
from databases import ( from databases import (
Build, Build,
BuildParts, BuildParts,
@@ -11,6 +14,7 @@ from api_validations.core_response import AlchemyJsonResponse
from api_validations.validations_request import ( from api_validations.validations_request import (
InsertBuildParts, InsertBuildParts,
UpdateBuildParts,
ListOptions, ListOptions,
) )
@@ -21,23 +25,32 @@ class BuildingBuildPartsListEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"b860e37a-e19b-4c45-9543-461241f7587c": "building_build_parts_list" "b860e37a-e19b-4c45-9543-461241f7587c": "building_build_parts_list"
} }
__event_validation__ = {
"b860e37a-e19b-4c45-9543-461241f7587c": BuildPartsListResponse
}
@classmethod @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( build_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id, employee_id=token_dict.selected_company.employee_id,
) )
build_list_ids = [build.id for build in build_list_query.all()] build_list_ids = [build.id for build in build_list_query.all()]
BuildParts.pre_query = BuildParts.query.filter( BuildParts.pre_query = BuildParts.filter_all(
BuildParts.build_id.in_(build_list_ids) BuildParts.build_id.in_(build_list_ids),
) ).query
records = BuildParts.filter_active( BuildParts.filter_attr = list_options
*BuildParts.get_smart_query(list_options.query) records = BuildParts.filter_all()
)
return AlchemyJsonResponse( return AlchemyJsonResponse(
completed=True, completed=True,
message="Building Parts Records are listed", message="Building Parts Records are listed",
result=records, result=records,
cls_object=BuildParts,
response_model=BuildPartsListResponse,
filter_attributes=list_options,
) )
@@ -47,19 +60,17 @@ class BuildingBuildPartsCreateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": "building_build_parts_create" "fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": "building_build_parts_create"
} }
__event_validation__ = {"fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": InsertBuildParts}
@classmethod @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) created_build = BuildParts.create_action(data=data, token=token_dict)
if not created_build: created_build.save()
return JSONResponse( created_build.update(is_confirmed=True)
content={
"completed": False,
"message": "Create Build Parts is not completed",
"data": {},
},
status_code=status.HTTP_406_NOT_ACCEPTABLE,
)
created_build.save() created_build.save()
return JSONResponse( return JSONResponse(
content={ content={
@@ -77,10 +88,15 @@ class BuildingBuildPartsUpdateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"58fdf95e-2110-4ed6-9c26-95f4be87eaee": "building_build_parts_update" "58fdf95e-2110-4ed6-9c26-95f4be87eaee": "building_build_parts_update"
} }
__event_validation__ = {"58fdf95e-2110-4ed6-9c26-95f4be87eaee": UpdateBuildParts}
@classmethod @classmethod
def building_build_parts_update(cls, data: InsertBuildParts, token_dict: dict): def building_build_parts_update(
if updated_build := BuildParts.update_action(data=data, token=token_dict): cls,
data: UpdateBuildParts,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
updated_build = BuildParts.update_action(data=data, token=token_dict)
updated_build.save() updated_build.save()
return JSONResponse( return JSONResponse(
content={ content={
@@ -90,14 +106,6 @@ class BuildingBuildPartsUpdateEventMethods(MethodToEvent):
}, },
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
) )
return JSONResponse(
content={
"completed": True,
"message": "Update Build Parts record",
"data": {},
},
status_code=status.HTTP_200_OK,
)
class BuildingBuildPartsPatchEventMethods(MethodToEvent): class BuildingBuildPartsPatchEventMethods(MethodToEvent):
@@ -106,10 +114,13 @@ class BuildingBuildPartsPatchEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"87a15ade-3474-4206-b574-bbf8580cbb14": "building_build_parts_patch" "87a15ade-3474-4206-b574-bbf8580cbb14": "building_build_parts_patch"
} }
__event_validation__ = {"87a15ade-3474-4206-b574-bbf8580cbb14": None}
@classmethod @classmethod
def building_build_parts_patch(cls, data, token_dict): 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( access_authorized_build = BuildParts.select_action(
duty_id=token_dict.selected_company.duty_id, duty_id=token_dict.selected_company.duty_id,
filter_expr=[BuildParts.id == find_one_build.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_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject 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_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject 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 ( from databases import (
Modules,
BuildParts, BuildParts,
Build, Build,
BuildLivingSpace, BuildLivingSpace,
@@ -12,119 +14,159 @@ from databases import (
) )
from api_events.events.abstract_class import MethodToEvent, ActionsSchema 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, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse from api_validations.core_response import AlchemyJsonResponse
from api_validations.validations_request import ( from api_validations.validations_request import (
InsertBuildLivingSpace, InsertBuildLivingSpace,
UpdateBuildLivingSpace,
ListOptions, 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_type = "SELECT"
event_description = ""
event_category = ""
__event_keys__ = { __event_keys__ = {
"8fd04d94-68fb-4a07-9549-8b47aee3a870": "building_build_parts_list", "36961d8a-cefa-46cc-9f7c-9d841d6351b6": "building_live_space_list",
"2f3041a9-6184-44c2-ac38-8ea934297ed1": "building_build_parts_list_with_expired", }
__event_validation__ = {
"36961d8a-cefa-46cc-9f7c-9d841d6351b6": LivingSpaceListResponse
} }
@classmethod @classmethod
def building_build_parts_list(cls, list_options: ListOptions, token_dict): def building_live_space_list(
build_id_list_query = Build.select_action( cls,
employee_id=token_dict.selected_company.employee_id list_options: ListOptions,
) token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
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 AlchemyJsonResponse(
completed=True,
message="Building Living Spaces are listed successfully",
result=records,
)
@classmethod
def building_build_parts_list_with_expired(
cls, list_options: ListOptions, token_dict
): ):
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( build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id employee_id=token_dict.selected_company.employee_id
) )
Build.filter_attr = list_options if not build_id_list_query:
build_part_id_list_query = BuildParts.filter_active( Build.raise_http_exception(
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]), 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(
records = BuildLivingSpace.filter_active( BuildParts.build_id.in_(
BuildLivingSpace.build_parts_id.in_( [build.id for build in build_id_list_query.all()]
[build_part.id for build_part in build_part_id_list_query.data]
), ),
*BuildLivingSpace.get_smart_query(smart_query=list_options.query), ).data
expired=False, 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( return AlchemyJsonResponse(
completed=True, completed=True,
message="Building Living Spaces are listed successfully", message="Building Living Spaces are listed successfully",
result=records, result=records,
response_model=LivingSpaceListResponse,
cls_object=BuildLivingSpace,
filter_attributes=list_options,
) )
class BuildingLivingSpacesPartsCreateEventMethods(MethodToEvent): class BuildingLivingSpacesCreateEventMethods(MethodToEvent):
event_type = "CREATE" event_type = "CREATE"
__event_keys__ = { __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 @classmethod
def building_live_space_create( def building_live_space_create(
cls, cls,
data: InsertBuildLivingSpace, 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 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( build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id employee_id=token_dict.selected_company.employee_id
) )
build_part = BuildParts.filter_one( build_part = BuildParts.filter_one(
BuildParts.uu_id == data.build_parts_uu_id, BuildParts.uu_id == data.build_parts_uu_id,
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]), BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
).data
if not build_part:
BuildLivingSpace.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
data={
"build_parts_uu_id": data.build_parts_uu_id,
},
) )
if not build_part.data: life_person = People.filter_one(
raise HTTPException( People.uu_id == data.person_uu_id,
status_code=status.HTTP_418_IM_A_TEAPOT, ).data
detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
)
build_part = build_part.data
life_person = People.find_one(uu_id=data.person_uu_id or "")
if not life_person: if not life_person:
raise HTTPException( BuildLivingSpace.raise_http_exception(
status_code=status.HTTP_418_IM_A_TEAPOT, status_code="HTTP_404_NOT_FOUND",
detail=f"{data.life_person_uu_id} - Living Person is not found in database. " error_case="UNAUTHORIZED",
f"Check build live person uu_id", message=f"{data.person_uu_id} - Living Person is not found in database.",
data={
"person_uu_id": data.person_uu_id,
},
) )
occupant_type = OccupantTypes.filter_by_one(uu_id=data.occupant_type_uu_id).data
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_type_uu_id)
if not occupant_type: if not occupant_type:
raise HTTPException( BuildLivingSpace.raise_http_exception(
status_code=status.HTTP_418_IM_A_TEAPOT, status_code="HTTP_404_NOT_FOUND",
detail=f"{data.occupant_type_uu_id} - Occupant Type is not found in database. " error_case="UNAUTHORIZED",
f"Check occupant type uu_id", message=f"{data.occupant_type_uu_id} - Occupant Type is not found in database. Check occupant type uu_id",
data={
"occupant_type_uu_id": data.occupant_type_uu_id,
},
) )
data_dict["occupant_type"] = occupant_type.id data_dict["occupant_type"] = occupant_type.id
@@ -134,89 +176,105 @@ class BuildingLivingSpacesPartsCreateEventMethods(MethodToEvent):
data_dict["person_id"] = life_person.id data_dict["person_id"] = life_person.id
data_dict["person_uu_id"] = str(life_person.uu_id) data_dict["person_uu_id"] = str(life_person.uu_id)
living_space_id = BuildLivingSpace.session.execute( living_space_id = BuildLivingSpace.select_only(
select(BuildLivingSpace.id)
.where(
*[
BuildLivingSpace.build_parts_id == build_part.id, BuildLivingSpace.build_parts_id == build_part.id,
BuildLivingSpace.person_id == life_person.id, BuildLivingSpace.person_id == life_person.id,
BuildLivingSpace.occupant_type == occupant_type.id, BuildLivingSpace.occupant_type == occupant_type.id,
BuildLivingSpace.active == True, select_args=[BuildLivingSpace.id],
BuildLivingSpace.is_confirmed == True, order_by=BuildLivingSpace.expiry_starts.desc(),
str(system_arrow.now()) < BuildLivingSpace.expiry_ends, limit=1,
str(system_arrow.now()) >= BuildLivingSpace.expiry_starts, ).data
]
)
.order_by(BuildLivingSpace.expiry_starts.desc())
).first()
last_living_space = BuildLivingSpace.filter_one( last_living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == living_space_id[0] if living_space_id else None BuildLivingSpace.id == living_space_id[0] if living_space_id else None,
) ).data
data_dict["expiry_starts"] = str(system_arrow.now())
created_living_space = BuildLivingSpace.create_action( created_living_space = BuildLivingSpace.create_action(
data=data_dict, token_dict=token_dict data=data_dict, token_dict=token_dict
) )
if last_living_space: if last_living_space:
if last_living_space.expiry_ends > system_arrow.now(): dt = system_arrow.get(last_living_space.expiry_ends)
last_living_space.expiry_ends = str(system_arrow.shift(minutes=-10)) 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() last_living_space.save()
user_module = Modules.filter_one(Modules.module_code == "USR-PUB") created_living_space.save_and_confirm()
ModulesBindOccupantEventMethods.modules_bind_occupant_system( occupants_service = Services.retrieve_service_via_occupant_code(
build_living_space_id=created_living_space.id, occupant_code=occupant_type.occupant_code
modules_id=user_module.id, )
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 return created_living_space
class BuildingLivingSpacesPartsUpdateEventMethods(MethodToEvent): class BuildingLivingSpacesUpdateEventMethods(MethodToEvent):
event_type = "UPDATE" event_type = "UPDATE"
__event_keys__ = { __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 @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 api_library.date_time_actions.date_functions import system_arrow
from sqlalchemy.sql import select
if isinstance(token_dict, OccupantTokenObject):
data_dict = data.dump() data_dict = data.dump()
build_id_list_query = Build.select_action( build_id_list_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id employee_id=token_dict.selected_company.employee_id
) )
build_part = BuildParts.filter_active( build_part = BuildParts.filter_one(
BuildParts.uu_id == data.build_parts_uu_id, BuildParts.uu_id == data.build_parts_uu_id,
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]), 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,
},
) )
if not build_part.get(1): life_person = People.filter_one(
raise HTTPException( People.uu_id == data.life_person_uu_id or ""
status_code=status.HTTP_418_IM_A_TEAPOT, ).data
detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
)
build_part = build_part.get(1)
life_person = People.find_one(uu_id=data.life_person_uu_id or "")
if not life_person: if not life_person:
raise HTTPException( BuildLivingSpace.raise_http_exception(
status_code=status.HTTP_418_IM_A_TEAPOT, status_code="HTTP_403_FORBIDDEN",
detail=f"{data.life_person_uu_id} - Living Person is not found in database. " error_case="UNAUTHORIZED",
f"Check build live person uu_id", message=f"{data.life_person_uu_id} - Living Person is not found in database.",
data={
"person_uu_id": data.life_person_uu_id,
},
) )
living_spaces = select(BuildLivingSpace.id).order_by( living_space_id = BuildLivingSpace.select_only(
BuildLivingSpace.expiry_starts.desc() *BuildLivingSpace.valid_record_args(BuildLivingSpace),
) select_args=[BuildLivingSpace.id],
living_space_id = BuildLivingSpace.session.execute(living_spaces).first() order_by=BuildLivingSpace.expiry_starts.desc(),
limit=1,
).get(1)
last_living_space = BuildLivingSpace.filter_one( last_living_space = BuildLivingSpace.filter_one(
BuildLivingSpace.id == getattr(living_space_id[0], "id", None) BuildLivingSpace.id == living_space_id if living_space_id else None,
if living_space_id ).data
else None
)
data_dict["expiry_starts"] = str(system_arrow.now()) data_dict["expiry_starts"] = str(system_arrow.now())
data_dict["is_tenant_live"] = bool(data.is_tenant_live) data_dict["is_tenant_live"] = bool(data.is_tenant_live)
@@ -224,12 +282,11 @@ class BuildingLivingSpacesPartsUpdateEventMethods(MethodToEvent):
if data_dict["is_tenant_live"]: if data_dict["is_tenant_live"]:
owner_person = getattr(last_living_space, "owner_person_id", None) owner_person = getattr(last_living_space, "owner_person_id", None)
if not owner_person: if not owner_person:
raise HTTPException( BuildLivingSpace.raise_http_exception(
status_code=status.HTTP_418_IM_A_TEAPOT, status_code="HTTP_403_FORBIDDEN",
detail=dict( error_case="UNAUTHORIZED",
message="Owner person of build part is not defined. Please register owner of part first.", message="Owner person of build part is not defined. Please register owner of part first.",
data=build_part.get_dict(), data=build_part.get_dict(),
),
) )
data_dict["life_person_id"] = life_person.id data_dict["life_person_id"] = life_person.id
data_dict["owner_person_id"] = owner_person data_dict["owner_person_id"] = owner_person
@@ -239,16 +296,12 @@ class BuildingLivingSpacesPartsUpdateEventMethods(MethodToEvent):
del data_dict["build_parts_uu_id"], data_dict["life_person_uu_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") action=ActionsSchema(endpoint="/building/living_space/list")
) )
BuildingLivingSpacesPartsCreateEventMethod = ( BuildingLivingSpacesCreateEventMethod = BuildingLivingSpacesCreateEventMethods(
BuildingLivingSpacesPartsCreateEventMethods(
action=ActionsSchema(endpoint="/building/living_space/create") action=ActionsSchema(endpoint="/building/living_space/create")
) )
) BuildingLivingSpacesUpdateEventMethod = BuildingLivingSpacesUpdateEventMethods(
BuildingLivingSpacesPartsUpdateEventMethod = (
BuildingLivingSpacesPartsUpdateEventMethods(
action=ActionsSchema(endpoint="/building/living_space/update") action=ActionsSchema(endpoint="/building/living_space/update")
) )
)

View File

@@ -23,6 +23,7 @@ class CompanyListEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": "company_list", "f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": "company_list",
} }
__event_validation__ = {"f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": None}
@classmethod @classmethod
def company_list( def company_list(
@@ -38,13 +39,11 @@ class CompanyListEventMethods(MethodToEvent):
] ]
) )
elif isinstance(token_dict, OccupantTokenObject): 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 Companies.id == token_dict.selected_occupant.responsible_company_id
).query ).query
Companies.filter_attr = list_options Companies.filter_attr = list_options
records = Companies.filter_active( records = Companies.filter_all()
*Companies.get_smart_query(list_options.query)
)
return AlchemyJsonResponse( return AlchemyJsonResponse(
completed=True, completed=True,
message="Building Living Spaces are listed successfully", message="Building Living Spaces are listed successfully",
@@ -58,29 +57,24 @@ class CompanyCreateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"76f11a08-5f4a-4e1f-961f-aaef21699acd": "company_create", "76f11a08-5f4a-4e1f-961f-aaef21699acd": "company_create",
} }
__event_validation__ = {"76f11a08-5f4a-4e1f-961f-aaef21699acd": InsertCompany}
@classmethod @classmethod
def company_create(cls, data: InsertCompany, token_dict): def company_create(
created_company = Companies.create_action( cls,
data=data, token=token_dict.companies_list 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() created_company.save()
return JSONResponse( return JSONResponse(
content={ content={
"completed": True, "completed": True,
"message": "Create Company record", "message": "Create Company record",
"data": created_company.get_dict(), "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, status_code=status.HTTP_200_OK,
) )
@@ -92,16 +86,33 @@ class CompanyUpdateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"41ea7f29-006a-4310-b5c4-b2a0e1a504bd": "company_update", "41ea7f29-006a-4310-b5c4-b2a0e1a504bd": "company_update",
} }
__event_validation__ = {
"41ea7f29-006a-4310-b5c4-b2a0e1a504bd": UpdateCompany,
}
@classmethod @classmethod
def company_update(cls, company_uu_id: str, data: UpdateCompany, token_dict): def company_update(
find_one_company = Companies.filter_one(Companies.uu_id == company_uu_id) cls, company_uu_id: str, data: UpdateCompany, token_dict: EmployeeTokenObject
access_authorized_company = Companies.select_action( ):
duty_id=getattr(token_dict, "duty_id", 5), Companies.pre_query = Companies.select_action(
filter_expr=[Companies.id == token_dict.get("")], duty_id_list=[
token_dict.selected_company.bulk_duties_id,
token_dict.selected_company.duty_id,
],
) )
if access_authorized_company.count: find_one_company = Companies.filter_one(
updated_company = find_one_company.data.update(**data.excluded_dump()) Companies.uu_id == company_uu_id,
).data
if not find_one_company:
return JSONResponse(
content={
"completed": True,
"message": "Update Company record",
"data": {},
},
status_code=200,
)
updated_company = find_one_company.update(**data.excluded_dump())
Companies.save() Companies.save()
return JSONResponse( return JSONResponse(
content={ content={
@@ -109,11 +120,7 @@ class CompanyUpdateEventMethods(MethodToEvent):
"message": "Update Company record", "message": "Update Company record",
"data": updated_company, "data": updated_company,
}, },
status_code=status.HTTP_200_OK, status_code=200,
)
return JSONResponse(
content={"completed": True, "message": "Update Company record", "data": {}},
status_code=status.HTTP_200_OK,
) )
@@ -123,13 +130,20 @@ class CompanyPatchEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"6320d696-1fd1-49f9-860a-8f22e5b8a68d": "company_patch", "6320d696-1fd1-49f9-860a-8f22e5b8a68d": "company_patch",
} }
__event_validation__ = {"6320d696-1fd1-49f9-860a-8f22e5b8a68d": None}
@classmethod @classmethod
def company_patch(cls, company_uu_id: str, data: PatchRecord, token_dict): def company_patch(
find_one_company = Companies.find_one_or_abort(uu_id=company_uu_id) 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( access_authorized_company = Companies.select_action(
duty_id=getattr(token_dict, "duty_id", 5), duty_id_list=[
filter_expr=[Companies.id == find_one_company.id], token_dict.selected_company.bulk_duties_id,
token_dict.selected_company.duty_id,
],
) )
if access_authorized_company.count: if access_authorized_company.count:
action = data.excluded_dump() 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 import status
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
@@ -12,7 +12,7 @@ from api_validations.validations_request import (
from databases import Departments from databases import Departments
from api_events.events.abstract_class import MethodToEvent, ActionsSchema 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
from api_validations.core_response import AlchemyJsonResponse from api_validations.core_response import AlchemyJsonResponse
@@ -22,16 +22,16 @@ class DepartmentListEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"2cb90331-c1b4-4923-8314-8111326b621a": "department_list", "2cb90331-c1b4-4923-8314-8111326b621a": "department_list",
} }
__event_validation__ = {"2cb90331-c1b4-4923-8314-8111326b621a": None}
@classmethod @classmethod
def department_list( def department_list(
cls, cls,
list_options: ListOptions, list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject], token_dict: EmployeeTokenObject,
): ):
Departments.filter_attr = list_options Departments.filter_attr = list_options
records = Departments.filter_active( records = Departments.filter_all(
*Departments.get_smart_query(smart_query=list_options.query),
Departments.company_id == token_dict.selected_company.company_id, Departments.company_id == token_dict.selected_company.company_id,
) )
return AlchemyJsonResponse( return AlchemyJsonResponse(
@@ -56,9 +56,14 @@ class DepartmentCreateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": "super_user_department_create", "d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": "super_user_department_create",
} }
__event_validation__ = {"d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": DepartmentsPydantic}
@classmethod @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 = data.excluded_dump()
data_dict["company_id"] = token_dict.selected_company.company_id data_dict["company_id"] = token_dict.selected_company.company_id
data_dict["company_uu_id"] = token_dict.selected_company.company_uu_id data_dict["company_uu_id"] = token_dict.selected_company.company_uu_id
@@ -80,10 +85,14 @@ class DepartmentUpdateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"4172706f-06c9-4c38-9ac8-59085a72f80a": "department_update", "4172706f-06c9-4c38-9ac8-59085a72f80a": "department_update",
} }
__event_validation__ = {"4172706f-06c9-4c38-9ac8-59085a72f80a": DepartmentsPydantic}
@classmethod @classmethod
def department_update( 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( access_authorized_company = Departments.select_action(
@@ -114,9 +123,12 @@ class DepartmentPatchEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"1e272e4f-6c1e-418b-91a7-be8b06c875da": "department_patch", "1e272e4f-6c1e-418b-91a7-be8b06c875da": "department_patch",
} }
__event_validation__ = {"1e272e4f-6c1e-418b-91a7-be8b06c875da": None}
@classmethod @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) find_one_company = Departments.find_one_or_abort(uu_id=company_uu_id)
access_authorized_company = Departments.select_action( access_authorized_company = Departments.select_action(
duty_id=getattr(token_dict, "duty_id", 5), duty_id=getattr(token_dict, "duty_id", 5),

View File

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

View File

@@ -1,5 +1,3 @@
from typing import Union
from fastapi import status from fastapi import status
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
@@ -22,16 +20,16 @@ class DutyListEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"23231c7d-4ff2-4b39-b71b-ea350d31fadf": "duty_list", "23231c7d-4ff2-4b39-b71b-ea350d31fadf": "duty_list",
} }
__event_validation__ = {"23231c7d-4ff2-4b39-b71b-ea350d31fadf": None}
@classmethod @classmethod
def duty_list( def duty_list(
cls, cls,
list_options: ListOptions, list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject], token_dict: EmployeeTokenObject,
): ):
records = Duty.filter_active( Duty.filter_attr = list_options
*Duty.get_smart_query(list_options.query), records = Duty.filter_all(system=True)
)
return AlchemyJsonResponse( return AlchemyJsonResponse(
completed=True, completed=True,
message="Duty list is brought successfully", message="Duty list is brought successfully",
@@ -45,12 +43,13 @@ class DutyCreateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"c6ea200e-fa17-4393-b390-37f5337c9c65": "duty_create", "c6ea200e-fa17-4393-b390-37f5337c9c65": "duty_create",
} }
__event_validation__ = {"c6ea200e-fa17-4393-b390-37f5337c9c65": InsertCompanyDuty}
@classmethod @classmethod
def duty_create( def duty_create(
cls, cls,
data: InsertCompanyDuty, data: InsertCompanyDuty,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject], token_dict: EmployeeTokenObject,
): ):
created_duty = Duty.find_or_create(**data.excluded_dump()) created_duty = Duty.find_or_create(**data.excluded_dump())
Duty.save() Duty.save()
@@ -70,13 +69,14 @@ class DutyUpdateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"ad952647-bcf8-482d-9e05-b2ee8086483f": "duty_update", "ad952647-bcf8-482d-9e05-b2ee8086483f": "duty_update",
} }
__event_validation__ = {"ad952647-bcf8-482d-9e05-b2ee8086483f": None}
@classmethod @classmethod
def duty_update( def duty_update(
cls, cls,
company_uu_id: str, company_uu_id: str,
data, data,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject], token_dict: EmployeeTokenObject,
): ):
find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id) find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
access_authorized_company = Duty.select_action( access_authorized_company = Duty.select_action(
@@ -107,9 +107,15 @@ class DutyPatchEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": "duty_patch", "d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": "duty_patch",
} }
__event_validation__ = {"d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": None}
@classmethod @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) find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
access_authorized_company = Duty.select_action( access_authorized_company = Duty.select_action(
duty_id=getattr(token_dict, "duty_id", 5), duty_id=getattr(token_dict, "duty_id", 5),

View File

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

View File

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

View File

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

View File

@@ -3,6 +3,9 @@ import typing
from fastapi import status, HTTPException from fastapi import status, HTTPException
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from api_events.events.events.events_bind_services import (
ServiceBindOccupantEventMethods,
)
from databases import ( from databases import (
Build, Build,
BuildParts, BuildParts,
@@ -25,8 +28,10 @@ from api_library.date_time_actions.date_functions import system_arrow, client_ar
from api_validations.validations_request import ( from api_validations.validations_request import (
InsertBuildDecisionBookItems, InsertBuildDecisionBookItems,
ListOptions,
ListDecisionBook, ListDecisionBook,
) )
from databases.sql_models.event.event import Services
class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent): class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
@@ -35,14 +40,17 @@ class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"eb36de59-8268-4d96-80b6-5d01c12bf0b1": "building_decision_book_items_list", "eb36de59-8268-4d96-80b6-5d01c12bf0b1": "building_decision_book_items_list",
} }
__event_validation__ = {"eb36de59-8268-4d96-80b6-5d01c12bf0b1": None}
@classmethod @classmethod
def building_decision_book_items_list( def building_decision_book_items_list(
cls, cls,
data: ListDecisionBook, data: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject], 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: if not decision_book:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
@@ -52,10 +60,10 @@ class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
Build.pre_query = Build.select_action( Build.pre_query = Build.select_action(
employee_id=token_dict.selected_company.employee_id, employee_id=token_dict.selected_company.employee_id,
filter_expr=[ 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: if not reachable_building.data:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
@@ -67,16 +75,18 @@ class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
token_dict.selected_company.duty_id, token_dict.selected_company.duty_id,
token_dict.selected_company.bulk_duties_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: if not reachable_companies.data:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}", detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
) )
BuildDecisionBookItems.filter_attr = BuildDecisionBookItems.FilterModel(**data.dump()) BuildDecisionBookItems.filter_attr = BuildDecisionBookItems.FilterModel(
records = BuildDecisionBookItems.filter_active( **data.dump()
)
records = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.build_decision_book_id == decision_book.id BuildDecisionBookItems.build_decision_book_id == decision_book.id
) )
return AlchemyJsonResponse( return AlchemyJsonResponse(
@@ -98,8 +108,8 @@ class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
# BuildDecisionBookItems.pre_query = BuildDecisionBookItems.select_action( # BuildDecisionBookItems.pre_query = BuildDecisionBookItems.select_action(
# occupant_id=token_dict.occupant_list["occupant_id"] # occupant_id=token_dict.occupant_list["occupant_id"]
# ) # )
# records = BuildDecisionBookItems.filter_active( # BuildDecisionBookItems.filter_attr = list_options
# *BuildDecisionBookItems.get_smart_query(list_options.query) # records = BuildDecisionBookItems.filter_all(
# ) # )
# return return_json_response_from_alchemy(response=records, pagination=list_options) # return return_json_response_from_alchemy(response=records, pagination=list_options)
return return
@@ -111,6 +121,9 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"dce10509-0da5-46fb-af3c-a81d54d5481c": "building_decision_book_items_create", "dce10509-0da5-46fb-af3c-a81d54d5481c": "building_decision_book_items_create",
} }
__event_validation__ = {
"dce10509-0da5-46fb-af3c-a81d54d5481c": InsertBuildDecisionBookItems
}
@classmethod @classmethod
def iterate_over_build_parts( def iterate_over_build_parts(
@@ -131,13 +144,12 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
local_date = system_arrow.find_last_day_of_month(local_date) local_date = system_arrow.find_last_day_of_month(local_date)
payment_amount = unit_price payment_amount = unit_price
if not unit_price_is_fixed: if not unit_price_is_fixed:
unit_amount = str(build_part_single.due_part_key).replace(" ", "") unit_amount = int(build_part_single.part_net_size)
unit_amount = unit_amount.replace(str(unit_type).upper(), "")
payment_amount = abs(unit_price * float(unit_amount)) * -1 payment_amount = abs(unit_price * float(unit_amount)) * -1
payment_amount = -1 * ( payment_amount = -1 * (
abs(payment_amount) + (50 - float(abs(payment_amount)) % 50) abs(payment_amount) + (50 - float(abs(payment_amount)) % 50)
) )
BuildDecisionBookPayments.create( created_book_payment = BuildDecisionBookPayments.find_or_create(
build_parts_id=build_part_single.id, build_parts_id=build_part_single.id,
build_parts_uu_id=str(build_part_single.uu_id), build_parts_uu_id=str(build_part_single.uu_id),
payment_amount=payment_amount, payment_amount=payment_amount,
@@ -149,11 +161,11 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}", 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) local_date = local_date.shift(days=2)
part_key = str(build_part_single.due_part_key).upper() part_key = str(build_part_single.due_part_key).upper()
if part_key not in payment_return_dict: if part_key not in payment_return_dict:
payment_return_dict[part_key] = payment_amount payment_return_dict[part_key] = payment_amount
return payment_return_dict return payment_return_dict
@classmethod @classmethod
@@ -170,15 +182,15 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
debit_start_date: str = None, debit_start_date: str = None,
debit_end_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.human_livable == True,
BuildParts.build_id == build_id, BuildParts.build_id == build_id,
) )
print("data_info_type.key", data_info_type.key)
book_payment_dict = dict( book_payment_dict = dict(
payment_plan_time_periods=str(data_info_type.key), payment_plan_time_periods=str(data_info_type.key),
build_decision_book_item_id=decision_book_item.id, build_decision_book_item_id=decision_book_item.id,
build_decision_book_item_uu_id=str(decision_book_item.uu_id), build_decision_book_item_uu_id=str(decision_book_item.uu_id),
is_confirmed=True,
currency=currency, currency=currency,
) )
payment_types = ApiEnumDropdown.get_debit_search(search_debit="DT-D") payment_types = ApiEnumDropdown.get_debit_search(search_debit="DT-D")
@@ -189,7 +201,7 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
end_date = system_arrow.get( end_date = system_arrow.get(
system_arrow.get(decision_book.expiry_ends).date() system_arrow.get(decision_book.expiry_ends).date()
) )
cls.iterate_over_build_parts( payment_return_dict = cls.iterate_over_build_parts(
build_parts_list=build_parts_list.data, build_parts_list=build_parts_list.data,
payment_types=payment_types, payment_types=payment_types,
local_date=local_date, local_date=local_date,
@@ -199,12 +211,11 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
unit_price_is_fixed=unit_price_is_fixed, unit_price_is_fixed=unit_price_is_fixed,
book_payment_dict=book_payment_dict, book_payment_dict=book_payment_dict,
) )
BuildDecisionBookProjects.save() return payment_return_dict
return
elif data_info_type.key == "BDT-A": elif data_info_type.key == "BDT-A":
local_date = system_arrow.get(system_arrow.get(debit_start_date).date()) local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
end_date = system_arrow.get(system_arrow.get(debit_end_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, build_parts_list=build_parts_list.data,
payment_types=payment_types, payment_types=payment_types,
local_date=local_date, local_date=local_date,
@@ -214,8 +225,7 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
unit_price_is_fixed=unit_price_is_fixed, unit_price_is_fixed=unit_price_is_fixed,
book_payment_dict=book_payment_dict, book_payment_dict=book_payment_dict,
) )
BuildDecisionBookProjects.save() return payment_return_dict
return
elif data_info_type.key == "BDT-R" or data_info_type.key == "BDT-L": 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()) local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
end_date = system_arrow.get(system_arrow.get(debit_end_date).date()) end_date = system_arrow.get(system_arrow.get(debit_end_date).date())
@@ -226,31 +236,31 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
BuildDecisionBookProjects.build_decision_book_id == decision_book.id, BuildDecisionBookProjects.build_decision_book_id == decision_book.id,
BuildDecisionBookProjects.project_type BuildDecisionBookProjects.project_type
== f"{decision_book.decision_type}_{data_info_type.key}", == f"{decision_book.decision_type}_{data_info_type.key}",
system=True,
) )
management_room = BuildParts.find_one( management_room = BuildParts.filter_one(
build_id=build_id, part_no=0, active=True, is_confirmed=True BuildParts.build_id == build_id, BuildParts.part_no == 0, system=True
) ).data
occupant_man = OccupantTypes.find_one( occupant_man = OccupantTypes.filter_by_one(
occupant_code="MT-VPR", occupant_category_type="MT" system=True, occupant_code="MT-VPR", occupant_category_type="MT"
) ).data
manager_living_space = BuildLivingSpace.filter_by_active( manager_living_space = BuildLivingSpace.filter_one(
build_parts_id=management_room.id, BuildLivingSpace.build_parts_id == management_room.id,
occupant_type=occupant_man.id, BuildLivingSpace.occupant_type == occupant_man.id,
) ).data
if not manager_living_space.data: if not manager_living_space:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, 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", 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 already_book_project_count = already_book_projects.count + 1
manager_living_space = manager_living_space.get(1)
book_project_dict = dict( book_project_dict = dict(
project_no=f"{data_info_type.key}_{decision_date.year}_{already_book_project_count}", 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_name=f"{str(meeting_date)}_{decision_book.decision_type} Project {already_book_projects.count + 1}",
project_start_date=str(local_date), project_start_date=str(local_date),
project_stop_date=str(end_date), project_stop_date=str(end_date),
project_type=f"{decision_book.decision_type}_{data_info_type.key}", 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_id=decision_book.id,
build_decision_book_uu_id=str(decision_book.uu_id), build_decision_book_uu_id=str(decision_book.uu_id),
build_decision_book_item_id=decision_book_item.id, build_decision_book_item_id=decision_book_item.id,
@@ -261,29 +271,69 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
book_project_created = BuildDecisionBookProjects.find_or_create( book_project_created = BuildDecisionBookProjects.find_or_create(
**book_project_dict **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( decision_book_item.update(
item_comment=f"{book_project_created.project_no}_{book_project_created.project_name} " item_comment=f"{book_project_created.project_no}_{book_project_created.project_name} "
f"is assigned to {occupant_man.occupant_description}" f"is assigned to {occupant_man.occupant_description} | {item_comment_at_database}"
) )
project_lead = ApiEnumDropdown.find_one( decision_book_item.save_and_confirm()
key="PTT-LDR", enum_class="ProjectTeamTypes" 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( project_person = BuildDecisionBookProjectPerson.find_or_create(
build_decision_book_project_id=book_project_created.id, build_decision_book_project_id=book_project_created.id,
build_decision_book_project_uu_id=str(book_project_created.uu_id), build_decision_book_project_uu_id=str(book_project_created.uu_id),
living_space_id=manager_living_space.id, living_space_id=project_leader.id,
living_space_uu_id=str(manager_living_space.uu_id), living_space_uu_id=str(project_leader.uu_id),
project_team_type_id=project_lead.id,
project_team_type_uu_id=str(project_lead.uu_id),
) )
BuildDecisionBookProjects.save() project_person.save_and_confirm()
return book_project_created.update(
project_response_living_space_id=project_leader.id,
elif data_info_type.key == "BDT-SF": 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( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, 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: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
@@ -304,9 +354,9 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
) )
elif isinstance(token_dict, OccupantTokenObject): elif isinstance(token_dict, OccupantTokenObject):
data_dict = data.dump() data_dict = data.dump()
occupant_wrt = OccupantTypes.find_one( occupant_wrt = OccupantTypes.filter_by_one(
occupant_code="MT-WRT", occupant_category_type="MT" system=True, occupant_code="MT-WRT", occupant_category_type="MT"
) ).data
if token_dict.selected_occupant.occupant_type_id != occupant_wrt.id: if token_dict.selected_occupant.occupant_type_id != occupant_wrt.id:
raise HTTPException( raise HTTPException(
@@ -314,36 +364,53 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
detail="Only WRITER can create decision book item. Check your occupant type and try again", 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_person = BuildDecisionBookPerson.filter_one(
decision_book = BuildDecisionBook.find_one( BuildDecisionBookPerson.token == data.token,
id=decision_book_person.build_decision_book_id ).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( BuildDecisionBookItems.check_meeting_is_valid_to_start_add_attendance(
decision_book=decision_book, decision_book=decision_book,
token_dict=token_dict, token_dict=token_dict,
) )
book_items = BuildDecisionBookItems.filter_active(
book_items = BuildDecisionBookItems.filter_all(
BuildDecisionBookItems.build_decision_book_id == decision_book.id, BuildDecisionBookItems.build_decision_book_id == decision_book.id,
system=True,
) )
data_dict["item_order"] = int(book_items.count) + 1 data_dict["item_order"] = int(book_items.count) + 1
data_dict["build_decision_book_id"] = decision_book.id data_dict["build_decision_book_id"] = decision_book.id
data_dict["build_decision_book_uu_id"] = str(decision_book.uu_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: for info_type in data_info_types:
if str(info_type.uu_id) == data_dict["info_type_uu_id"]: if str(info_type.uu_id) == data_dict["info_type_uu_id"]:
data_info_type = info_type data_info_type = info_type
break break
if not data_info_type:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Info Type is not valid. Check info type and try again",
)
if str(data_info_type.key).upper() in ["BDT-A", "BDT-R", "BDT-L", "BDT-SF"]: row_is_debit = str(data_info_type.key).upper() in ["BDT-A", "BDT-D"]
if not data_dict["debit_start_date"] or not data_dict["debit_end_date"]: 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( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Debit Start Date and Debit End Date is required for this payment type. " detail="Debit Start Date and Debit End Date is required for this payment type. "
@@ -355,6 +422,7 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
unit_price, unit_type = float(data_dict["unit_price"]), str( unit_price, unit_type = float(data_dict["unit_price"]), str(
data_dict["unit_type"] data_dict["unit_type"]
) )
debit_start_date, debit_end_date = ( debit_start_date, debit_end_date = (
data_dict["debit_start_date"], data_dict["debit_start_date"],
data_dict["debit_end_date"], data_dict["debit_end_date"],
@@ -370,18 +438,9 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
data_dict["currency"], data_dict["currency"],
) )
if new_decision_book_item := BuildDecisionBookItems.find_or_create( new_decision_book_item = BuildDecisionBookItems.find_or_create(**data_dict)
**data_dict new_decision_book_item.save_and_confirm()
): print("new_decision_book_item", new_decision_book_item)
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( if created_payment_records_dict := cls.create_payment_records_for_each_build_part(
data_info_type=data_info_type, data_info_type=data_info_type,
build_id=decision_book.build_id, build_id=decision_book.build_id,
@@ -394,7 +453,7 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
debit_end_date=debit_end_date, debit_end_date=debit_end_date,
currency=currency, currency=currency,
): ):
if data_info_type.key == "BDT-A" or data_info_type.key == "BDT-D": if row_is_debit:
if data_info_type.key == "BDT-D": if data_info_type.key == "BDT-D":
item_comment = "Regular Payment Plan : " item_comment = "Regular Payment Plan : "
else: else:
@@ -410,6 +469,15 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
item_comment = item_comment[:-2] item_comment = item_comment[:-2]
new_decision_book_item.update(item_comment=item_comment) new_decision_book_item.update(item_comment=item_comment)
new_decision_book_item.update(is_payment_created=True) 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( return JSONResponse(
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
content=dict( content=dict(
@@ -418,10 +486,10 @@ class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
data=new_decision_book_item.get_dict(), data=new_decision_book_item.get_dict(),
), ),
) )
raise HTTPException( # raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, # 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", # 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): class DecisionBookDecisionBookItemsUpdateEventMethods(MethodToEvent):
@@ -430,6 +498,7 @@ class DecisionBookDecisionBookItemsUpdateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": "building_decision_book_items_update", "f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": "building_decision_book_items_update",
} }
__event_validation__ = {"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": None}
@classmethod @classmethod
def building_decision_book_items_update( def building_decision_book_items_update(
@@ -446,6 +515,7 @@ class DecisionBookDecisionBookItemsPatchEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"42328809-b516-477b-82cc-2d6fadf28843": "building_decision_book_items_patch", "42328809-b516-477b-82cc-2d6fadf28843": "building_decision_book_items_patch",
} }
__event_validation__ = {"42328809-b516-477b-82cc-2d6fadf28843": None}
@classmethod @classmethod
def building_decision_book_items_patch( 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_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject 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

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

View File

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

View File

@@ -15,40 +15,80 @@ from api_events.events.events.events_bind_services import (
) )
from api_library.date_time_actions.date_functions import system_arrow from api_library.date_time_actions.date_functions import system_arrow
from api_validations.core_response import AlchemyJsonResponse 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): class ModulesBindOccupantEventMethods(MethodToEvent):
event_type = "UPDATE" event_type = "UPDATE"
__event_keys__ = { __event_keys__ = {
"": "modules_bind_occupant", "91003e90-8ead-4705-98a3-f8731c6ecb38": "modules_bind_occupant",
}
__event_validation__ = {
"91003e90-8ead-4705-98a3-f8731c6ecb38": None,
} }
@classmethod @classmethod
def modules_bind_occupant_system( def bind_default_module_for_first_init_occupant(
cls, build_living_space_id: int, modules_id: int, expires_at: str = None cls, build_living_space_id: int, expires_at: str = None
): ):
living_space = BuildLivingSpace.filter_one( living_space = BuildLivingSpace.filter_one(
Modules.id == build_living_space_id BuildLivingSpace.id == build_living_space_id, system=True
).data ).data
modules = Modules.filter_one(Modules.id == modules_id).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 = dict(build_living_space_id=living_space.id)
service_build_dict["expires_at"] = str( if expires_at:
system_arrow.get(living_space.expiry_ends)
)
if not expires_at:
service_build_dict["expires_at"] = str(system_arrow.get(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(): for module in modules:
ServiceBindOccupantEventMethods.bind_services_occupant_system( for service in module.retrieve_services():
**service_build_dict, event_occupant = Event2Occupant.find_or_create(
service_id=service.id, 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),
) )
BuildLivingSpace.save() event_occupant.save_and_confirm()
return True 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 @classmethod
def modules_bind_occupant( def modules_bind_occupant(
cls, cls,
@@ -63,8 +103,42 @@ class ModulesBindEmployeeEventMethods(MethodToEvent):
event_type = "UPDATE" event_type = "UPDATE"
__event_keys__ = { __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 @classmethod
def modules_bind_employee( def modules_bind_employee(

View File

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

View File

@@ -2,6 +2,7 @@ from typing import Union
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from api_events.events.events.events_services import ServicesEvents
from databases import ( from databases import (
Events, Events,
Employees, Employees,
@@ -14,7 +15,6 @@ from databases import (
from api_validations.validations_request import ( from api_validations.validations_request import (
RegisterEvents2Employee, RegisterEvents2Employee,
RegisterEvents2Occupant, RegisterEvents2Occupant,
CreateEvents,
ListOptions, ListOptions,
) )
@@ -29,6 +29,7 @@ class EventsListEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": "events_list", "9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": "events_list",
} }
__event_validation__ = {"9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": None}
@classmethod @classmethod
def events_list( def events_list(
@@ -36,100 +37,39 @@ class EventsListEventMethods(MethodToEvent):
list_options: ListOptions, list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject], token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
): ):
list_options.page = 1
list_options.size = 10000
Events.filter_attr = list_options Events.filter_attr = list_options
records = Events.filter_active( if isinstance(token_dict, OccupantTokenObject):
*Events.get_smart_query(list_options.query), occupant_events = Event2Occupant.filter_all(
Event2Occupant.build_living_space_id
== token_dict.selected_occupant.living_space_id
).data
records = Events.filter_all(
Events.id.in_([event.event_id for event in occupant_events])
) )
return AlchemyJsonResponse( return AlchemyJsonResponse(
completed=True, completed=True,
message="DecisionBook are listed successfully", message="Events are listed successfully",
result=records, result=records,
) )
elif isinstance(token_dict, EmployeeTokenObject):
employee_events = Event2Employee.filter_all(
class EventsCreateEventMethods(MethodToEvent): Event2Employee.employee_id == token_dict.selected_company.employee_id
).data
event_type = "CREATE" records = Events.filter_all(
__event_keys__ = { Events.id.in_([event.event_id for event in employee_events])
"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 AlchemyJsonResponse(
return { completed=True,
"status": "success", message="Events are listed successfully",
"message": "Event created successfully.", result=records,
"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.",
) )
event.update( return AlchemyJsonResponse(
**token_dict.user_creds, completed=False,
event_name=data.event_name, message="Events are NOT listed successfully",
event_description=data.event_description, result=[],
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.",
)
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,
}
class EventsBindEventToOccupantMethods(MethodToEvent): class EventsBindEventToOccupantMethods(MethodToEvent):
@@ -138,21 +78,31 @@ class EventsBindEventToOccupantMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"d9aa58aa-37f7-4c27-861d-3105f76f5cdc": "bind_events_employee", "d9aa58aa-37f7-4c27-861d-3105f76f5cdc": "bind_events_employee",
} }
__event_validation__ = {
"d9aa58aa-37f7-4c27-861d-3105f76f5cdc": RegisterEvents2Employee
}
@classmethod @classmethod
def bind_events_employee(cls, data: RegisterEvents2Employee, token_dict): 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: if not events:
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail="No event found. Please contact your super user.", 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_is_not_valid = False
employee = Employees.filter_one(
Employees.employee_uu_id == data.employee_uu_id,
).data
if employee: if employee:
staff = Staff.find_one(id=employee.staff_id) staff = Staff.filter_one(
duties = Duties.find_one(id=staff.duties_id) 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: if duties.company_id not in token_dict.companies_id_list:
employee_is_not_valid = True employee_is_not_valid = True
@@ -162,7 +112,7 @@ class EventsBindEventToOccupantMethods(MethodToEvent):
detail="This employee can not be reached by this user. Please contact your super user.", 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( employee = Event2Employee.find_or_create(
**token_dict.user_creds, employee_id=employee.id, event_id=event.id **token_dict.user_creds, employee_id=employee.id, event_id=event.id
) )
@@ -180,24 +130,29 @@ class EventsBindEventToEmployeeMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"8bb4f4fc-b474-427e-90b3-d8681f308bb5": "bind_events_occupant", "8bb4f4fc-b474-427e-90b3-d8681f308bb5": "bind_events_occupant",
} }
__event_validation__ = {
"8bb4f4fc-b474-427e-90b3-d8681f308bb5": RegisterEvents2Occupant
}
@classmethod @classmethod
def bind_events_occupant(cls, data: RegisterEvents2Occupant, token_dict): 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: if not events:
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail="No event found. Please contact your super user.", detail="No event found. Please contact your super user.",
) )
occupant = BuildLivingSpace.find_one(uu_id=data.build_living_space_uu_id) occupant = BuildLivingSpace.filter_one(
occupant_is_not_valid = False BuildLivingSpace.uu_id == data.build_living_space_uu_id,
if occupant_is_not_valid: ).data
if not occupant:
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail="This occupant can not be reached by this user. Please contact your super user.", detail="This occupant can not be reached by this user. Please contact your super user.",
) )
for event in events:
for event in events.data:
occupant = Event2Occupant.find_or_create( occupant = Event2Occupant.find_or_create(
**token_dict.user_creds, **token_dict.user_creds,
build_living_space_id=occupant.id, build_living_space_id=occupant.id,
@@ -211,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( EventsBindEventToOccupantMethod = EventsBindEventToOccupantMethods(
action=ActionsSchema(endpoint="/bind/events/occupant") action=ActionsSchema(endpoint="/bind/events/occupant")
) )
EventsBindEventToEmployeeMethod = EventsBindEventToEmployeeMethods( EventsBindEventToEmployeeMethod = EventsBindEventToEmployeeMethods(
action=ActionsSchema(endpoint="/bind/events/employee") 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,3 +1,5 @@
from typing import Union
from api_validations.validations_request import ( from api_validations.validations_request import (
DepartmentsPydantic, DepartmentsPydantic,
PatchRecord, PatchRecord,
@@ -12,27 +14,49 @@ from api_validations.core_response import AlchemyJsonResponse
class ServicesEvents(MethodToEvent): class ServicesEvents(MethodToEvent):
@classmethod @classmethod
def services_list(cls, list_options: ListOptions): def services_list(
cls,
list_options: ListOptions,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return return
@classmethod @classmethod
def services_create(cls, data: DepartmentsPydantic, token_dict): def services_create(
cls,
data: DepartmentsPydantic,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
return return
@classmethod @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 return
@classmethod @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 return
@classmethod @classmethod
def bind_service_to_action(cls, data, token_dict): def bind_service_to_action(
cls, data, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
return return
@classmethod @classmethod
def bind_module_to_service(cls, data, token_dict): def bind_module_to_service(
cls, data, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
return return
@classmethod @classmethod

View File

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

View File

@@ -3,15 +3,15 @@ import typing
from fastapi import status from fastapi import status
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from api_configs import ApiStatic
from databases import MongoQueryIdentity, Users, Companies, People from databases import MongoQueryIdentity, Users, Companies, People
from databases.no_sql_models.validations import DomainViaUser from databases.no_sql_models.validations import DomainViaUser
from api_events.events.abstract_class import MethodToEvent, ActionsSchema 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, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse 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 ( from api_validations.validations_request import (
InsertUsers, InsertUsers,
UpdateUsers, UpdateUsers,
@@ -27,6 +27,7 @@ class UserListEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": "user_list", "1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": "user_list",
} }
__event_validation__ = {"1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": None}
@classmethod @classmethod
def user_list( def user_list(
@@ -34,25 +35,30 @@ class UserListEventMethods(MethodToEvent):
list_options: ListOptions, list_options: ListOptions,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject], token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
): ):
# Users.pre_query = Users.select_action(duty_id_list=[ if isinstance(token_dict, OccupantTokenObject):
# token_dict.selected_company.duty_id, raise Users.raise_http_exception(
# token_dict.selected_company.bulk_duties_id 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: if "user_uu_id_list" in list_options.query:
people_ids = list_options.query.pop("user_uu_id_list") people_ids = list_options.query.pop("user_uu_id_list")
people_id_list = [ people_id_list = (
user.person_id user.person_id
for user in Users.filter_active(Users.uu_id.in_(people_ids)).data for user in Users.filter_all(Users.uu_id.in_(people_ids)).data
] )
People.filter_attr = list_options Users.filter_attr = list_options
records = People.filter_active(People.id.in_(people_id_list)) records = Users.filter_all(
Users.person_id.in_(people_id_list),
)
return AlchemyJsonResponse( return AlchemyJsonResponse(
completed=True, completed=True,
message="Users are listed successfully", message="Users are listed successfully",
result=records, result=records,
) )
People.filter_attr = list_options Users.filter_attr = list_options
records = Users.filter_active(*Users.get_smart_query(list_options.query)) records = Users.filter_all()
return AlchemyJsonResponse( return AlchemyJsonResponse(
completed=True, completed=True,
message="Users are listed successfully", message="Users are listed successfully",
@@ -66,6 +72,7 @@ class UserCreateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"8eb50c24-4bdc-4309-9836-f7048daee409": "user_create", "8eb50c24-4bdc-4309-9836-f7048daee409": "user_create",
} }
__event_validation__ = {"8eb50c24-4bdc-4309-9836-f7048daee409": InsertUsers}
@classmethod @classmethod
def user_create( def user_create(
@@ -73,16 +80,30 @@ class UserCreateEventMethods(MethodToEvent):
data: InsertUsers, data: InsertUsers,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject], token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
): ):
created_user = Users.create_action(create_user=data) created_user = Users.create_action(create_user=data, token_dict=token_dict)
created_user.related_company = token_dict.selected_company.company_uu_id
domain_via_user = DomainViaUser( domain_via_user = DomainViaUser(
**{"user_uu_id": str(created_user.uu_id), "main_domain": "evyos.com.tr"} **{"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( mongo_query_identity = MongoQueryIdentity(
company_uuid=created_user.related_company, company_uuid=created_user.related_company,
) )
mongo_query_identity.create_domain_via_user(payload=domain_via_user) 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( return JSONResponse(
content={ content={
"completed": True, "completed": True,
@@ -106,6 +127,7 @@ class UserUpdateEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"d08a9470-1eb0-4890-a9e8-b6686239d7e9": "user_update", "d08a9470-1eb0-4890-a9e8-b6686239d7e9": "user_update",
} }
__event_validation__ = {"d08a9470-1eb0-4890-a9e8-b6686239d7e9": UpdateUsers}
@classmethod @classmethod
def user_update( def user_update(
@@ -114,9 +136,12 @@ class UserUpdateEventMethods(MethodToEvent):
user_uu_id: str, user_uu_id: str,
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject], 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( 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("")], filter_expr=[Companies.id == token_dict.get("")],
) )
if access_authorized_company.count: if access_authorized_company.count:
@@ -143,12 +168,15 @@ class UserPatchEventMethods(MethodToEvent):
__event_keys__ = { __event_keys__ = {
"d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": "user_patch", "d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": "user_patch",
} }
__event_validation__ = {"d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": None}
@classmethod @classmethod
def user_patch(cls, data: PatchRecord, user_uu_id: str, token_dict): 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( 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], filter_expr=[Companies.id == find_one_user.id],
) )
if access_authorized_company.count: if access_authorized_company.count:

View File

@@ -17,6 +17,15 @@ from api_events.tasks2events.occupant_tasks.meeting_president import (
from api_events.tasks2events.occupant_tasks.meeting_voted_president import ( from api_events.tasks2events.occupant_tasks.meeting_voted_president import (
BuildMeetingVotedPresident, 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__ = [ __all__ = [
@@ -32,4 +41,9 @@ __all__ = [
"BuildMeetingAdvisor", "BuildMeetingAdvisor",
"BuildMeetingAttendance", "BuildMeetingAttendance",
"BuildMeetingVotedPresident", "BuildMeetingVotedPresident",
"ProjectLeader",
"ProjectFinanceResponsible",
"ProjectEmployee",
"ProjectTechnical",
"ProjectResponsible",
] ]

View File

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

View File

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

View File

@@ -48,10 +48,6 @@ class SuperUserEventBlock(AddEventFunctionality):
{"function_code": "ffdc445f-da10-4ce4-9531-d2bdb9a198ae"}, {"function_code": "ffdc445f-da10-4ce4-9531-d2bdb9a198ae"},
{"function_code": "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d"}, {"function_code": "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d"},
{"function_code": "1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27"}, {"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": "9c251d7d-da70-4d63-a72c-e69c26270442"},
{"function_code": "6f1406ac-577d-4f2c-8077-71fff2252c5f"}, {"function_code": "6f1406ac-577d-4f2c-8077-71fff2252c5f"},
{"function_code": "88d37b78-1ac4-4513-9d25-090ac3a24f31"}, {"function_code": "88d37b78-1ac4-4513-9d25-090ac3a24f31"},
@@ -77,6 +73,20 @@ class SuperUserEventBlock(AddEventFunctionality):
{"function_code": "7b58ed84-9a65-4588-994d-30df8366b050"}, {"function_code": "7b58ed84-9a65-4588-994d-30df8366b050"},
{"function_code": "5702f0a9-fe8f-4aae-922e-6e04b497ef6a"}, {"function_code": "5702f0a9-fe8f-4aae-922e-6e04b497ef6a"},
{"function_code": "c93a3009-65a0-498d-9191-04484d5cde81"}, {"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): def __new__(cls, *args, **kwargs):

View File

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

@@ -14,7 +14,7 @@ class DateTimeLocal:
def find_last_day_of_month(self, date_value): def find_last_day_of_month(self, date_value):
today = self.get(date_value).date() today = self.get(date_value).date()
_, last_day = calendar.monthrange(today.year, today.month) _, 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): def find_first_day_of_month(self, date_value):
today = self.get(date_value).date() today = self.get(date_value).date()
@@ -47,6 +47,3 @@ class DateTimeLocal:
client_arrow = DateTimeLocal(is_client=True) client_arrow = DateTimeLocal(is_client=True)
system_arrow = DateTimeLocal(is_client=False) 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" timezone: Optional[str] = "Europe/Istanbul"
user_type: int = UserType.occupant.value user_type: int = UserType.occupant.value
credentials: Credentials credentials: dict = {}
user_uu_id: str user_uu_id: str
user_id: int user_id: int
@@ -52,14 +52,14 @@ class OccupantToken(BaseModel):
build_part_id: int build_part_id: int
build_part_uuid: str 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_id: Optional[int] = None
responsible_company_uuid: Optional[str] = None responsible_company_uuid: Optional[str] = None
responsible_employee_id: Optional[int] = None responsible_employee_id: Optional[int] = None
responsible_employee_uuid: Optional[str] = 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 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 bulk_duties_id: int
reachable_event_list_id: Optional[list] = None # ID list of reachable modules 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): class OccupantTokenObject(ApplicationToken):

View File

@@ -1,3 +1,6 @@
import re
from gc import garbage
import textdistance import textdistance
from unidecode import unidecode from unidecode import unidecode
from datetime import datetime from datetime import datetime
@@ -11,6 +14,9 @@ from databases import (
from typing import Optional from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel
from databases.sql_models.company.company import Companies
from databases.sql_models.identity.identity import People
class InsertBudgetRecord(BaseModel): class InsertBudgetRecord(BaseModel):
iban: str iban: str
@@ -53,14 +59,12 @@ def strip_date_to_valid(date_str):
return datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S") return datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
def find_iban_in_comment(iban: str, comment: str): def find_iban_in_comment(iban: str, comment: str, living_space_dict: dict = None):
iban_results, iban_count = BuildIbanDescription.filter_by(iban=iban) iban_results = BuildIbanDescription.filter_all(
BuildIbanDescription.iban == iban, system=True
).data
sm_dict_extended, sm_dict_digit = {}, {} sm_dict_extended, sm_dict_digit = {}, {}
# is_reference_build = any( for iban_result in iban_results or []:
# letter in comment.lower() for letter in ["no", "daire", "nolu"]
# )
if iban_count:
for iban_result in iban_results:
candidate_parts = comment.split(" ") candidate_parts = comment.split(" ")
extended_candidate_parts, digit_part = [], [] extended_candidate_parts, digit_part = [], []
for part in candidate_parts: for part in candidate_parts:
@@ -78,9 +82,7 @@ def find_iban_in_comment(iban: str, comment: str):
) )
found = False found = False
name_list = ( name_list = (
unidecode(str(iban_result.search_word)) unidecode(str(iban_result.search_word)).replace(".", " ").split(" ")
.replace(".", " ")
.split(" ")
) )
for name in name_list: for name in name_list:
if len(name) > 3 and name.lower() in comment.lower(): if len(name) > 3 and name.lower() in comment.lower():
@@ -90,113 +92,494 @@ def find_iban_in_comment(iban: str, comment: str):
if not found: if not found:
similarity_ratio = 0.1 similarity_ratio = 0.1
sm_dict_extended[f"{iban_result.id}"] = similarity_ratio sm_dict_extended[f"{iban_result.id}"] = similarity_ratio
if sm_dict_extended: if sm_dict_extended:
result = sorted( result = sorted(
sm_dict_extended.items(), key=lambda item: item[1], reverse=True sm_dict_extended.items(), key=lambda item: item[1], reverse=True
)[0] )[0]
if float(result[1]) >= 0.5: if float(result[1]) >= 0.5:
iban_result = BuildIbanDescription.find_one(id=int(result[0])) iban_result = BuildIbanDescription.filter_one(
BuildIbanDescription.id == int(result[0]), system=True
).data
return { return {
"decision_book_project_id": iban_result.decision_book_project_id, # "decision_book_project_id": iban_result.decision_book_project_id,
# "build_parts_id": iban_result.build_parts_id,
"company_id": iban_result.company_id, "company_id": iban_result.company_id,
"customer_id": iban_result.customer_id, "customer_id": iban_result.customer_id,
"build_parts_id": iban_result.build_parts_id,
"found_from": "Name", "found_from": "Name",
"similarity": result[1], "similarity": result[1],
} }
return { return {
"decision_book_project_id": None, # "decision_book_project_id": None,
# "build_parts_id": None,
"company_id": None, "company_id": None,
"customer_id": None, "customer_id": None,
"build_parts_id": None,
"found_from": None, "found_from": None,
"similarity": 0.0, "similarity": 0.0,
} }
def parse_comment_with_name(iban: str, comment: str): def remove_spaces_from_string(remove_string: str):
if "*" in comment: letter_list = []
b_comment, a_comment = ( for letter in remove_string.split(" "):
unidecode(str(comment)).split("*")[0], if letter_ := "".join(i for i in letter if not i == " "):
unidecode(str(comment)).split("*")[1], letter_list.append(letter_)
) return " ".join(letter_list).upper()
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
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
def wag_insert_budget_record(data): def get_garbage_words(comment: str, search_word: str):
similarity_result = parse_comment_with_name(data["iban"], data["process_comment"]) garbage_words = unidecode(remove_spaces_from_string(comment))
build_iban = BuildIbans.find_one(iban=data["iban"]) search_word = unidecode(remove_spaces_from_string(search_word))
if payload := InsertBudgetRecord(**data): for word in search_word.split(" "):
payload_dict = payload.model_dump(exclude_unset=True, exclude_none=True) garbage_words = garbage_words.replace(
decision_book, count = BuildDecisionBook.filter( remove_spaces_from_string(unidecode(word)), ""
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( if cleaned_from_spaces := remove_spaces_from_string(garbage_words):
BuildIbans.find_one(iban=data["iban"]), "build_id", None 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), ""
) )
living_space, count = BuildLivingSpace.find_living_from_customer_id( return str(remove_spaces_from_string(cleaned_comment)).upper()
similarity_result.get("customer_id", None),
strip_date_to_valid(payload_dict["bank_date"]),
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()
) )
# living_space, count = BuildLivingSpace.filter( if number_digit:
# or_( rt_dict = {
# BuildLivingSpace.owner_person_id "garbage": candidate_parts[st:et],
# == similarity_result.get("customer_id", None), "number": int(number_digit) if number_digit else None,
# BuildLivingSpace.life_person_id }
# == similarity_result.get("customer_id", None), build_words.append(rt_dict)
# ), return build_words
# BuildLivingSpace.start_date
# < strip_date_to_valid(payload_dict["bank_date"]) - timedelta(days=30),
# BuildLivingSpace.stop_date def generate_pattern(word):
# > strip_date_to_valid(payload_dict["bank_date"]) + timedelta(days=30), if len(word) < 1:
# BuildLivingSpace.active == True, raise ValueError("The word must have at least 1 character.")
# BuildLivingSpace.deleted == False, 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:
print(f"'{test}' does NOT match the pattern.")
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}")
)
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
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
# ) # )
payload_dict["build_decision_book_id"] = ( return best_similarity
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)
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( def parse_comment_to_split_with_star(account_record: AccountRecords):
payload_dict["bank_date"] if "*" in account_record.process_comment:
).year process_comment = str(account_record.process_comment.replace("**", "*"))
payload_dict["bank_date_m"] = strip_date_to_valid( process_comments = process_comment.split("*")
payload_dict["bank_date"] return len(process_comments), *process_comments
).month return 1, account_record.process_comment
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"] def check_build_living_space_matches_with_build_parts(
).isocalendar()[2] living_space_dict: dict, best_similarity: dict, iban: str, whole_comment: str
payload_dict["build_id"] = build_iban.build_id if build_iban else None ):
payload_dict["replication_id"] = 55 if 0.6 < float(best_similarity["similarity"]) < 0.8:
payload_dict["receive_debit"] = ( build_parts = living_space_dict[iban]["build_parts"]
"R" if payload_dict["currency_value"] < 0 else "D" 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)
) )
data, found = AccountRecords.find_or_create( print("build parts similarity", best_similarity, "parser_dict", parser_dict)
**payload_dict, results_list = parse_comment_for_build_parts(**parser_dict)
found_from=similarity_result.get("found_from", None), print("results_list", results_list)
similarity=similarity_result.get("similarity", 0.0), 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.payment_budget_record_close() if comments_length == 1:
return data, found 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
)
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: ) -> bool:
try: try:
email_sender.connect() email_sender.connect()
receivers = ["karatay@mehmetkaratay.com.tr"]
email_sender.send( email_sender.send(
subject=subject, subject=subject,
receivers=receivers, receivers=receivers,
text=text, text=text + f" : Gonderilen [{str(receivers)}]",
html=html, html=html,
cc=cc, cc=cc,
bcc=bcc, bcc=bcc,

View File

@@ -5,16 +5,6 @@ from fastapi import status
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from api_configs import Auth from api_configs import Auth
from databases import (
BuildLivingSpace,
BuildParts,
Companies,
Duties,
Departments,
Duty,
Employees,
Staff,
)
from api_objects import ( from api_objects import (
OccupantTokenObject, OccupantTokenObject,
EmployeeTokenObject, EmployeeTokenObject,
@@ -26,6 +16,8 @@ from api_services.redis.functions import (
get_object_via_user_uu_id, get_object_via_user_uu_id,
get_object_via_access_key, 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( def save_object_to_redis(
@@ -50,28 +42,36 @@ def save_object_to_redis(
def save_access_token_to_redis( def save_access_token_to_redis(
request, found_user, domain: str, access_token: str = None request, found_user, domain: str, access_token: str = None
): ):
from databases import (
BuildLivingSpace,
BuildParts,
Companies,
Duties,
Departments,
Duty,
Employees,
Staff,
)
if not found_user: if not found_user:
raise HTTPException( raise HTTPException(
status_code=400, status_code=400,
detail=dict(message="User is not found."), detail=dict(message="User is not found."),
headers=request.headers,
) )
# Check user is already logged in or has a previous session # 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) already_tokens = get_object_via_user_uu_id(user_id=found_user.uu_id)
for key in already_tokens or []: for key, token_user in already_tokens.items():
token_user = json.loads(redis_cli.get(key).decode() or {})
if token_user.get("domain", "") == domain: if token_user.get("domain", "") == domain:
redis_cli.delete(key) redis_cli.delete(key)
access_token = ( access_token = (
found_user.generate_access_token() if not access_token else access_token found_user.generate_access_token() if not access_token else access_token
) )
# Prepare the user's details to save in Redis Session # Prepare the user's details to save in Redis Session
if found_user.is_occupant: # Check if user is NOT an occupant if found_user.is_occupant: # Check if user is NOT an occupant
living_spaces: list[BuildLivingSpace] = BuildLivingSpace.filter_active( living_spaces: list[BuildLivingSpace] = BuildLivingSpace.filter_all(
BuildLivingSpace.person_id == found_user.person_id, filter_records=False BuildLivingSpace.person_id == found_user.person_id
).data ).data
if not living_spaces: if not living_spaces:
raise HTTPException( raise HTTPException(
@@ -79,13 +79,11 @@ def save_access_token_to_redis(
detail=dict( detail=dict(
message="NO Living Space is found. This user has no proper account set please contact the admin." message="NO Living Space is found. This user has no proper account set please contact the admin."
), ),
headers=request.headers,
) )
occupants_selection_dict = {} occupants_selection_dict = {}
for living_space in living_spaces: for living_space in living_spaces:
build_parts_selection = BuildParts.filter_active( build_parts_selection = BuildParts.filter_all(
BuildParts.id == living_space.build_parts_id BuildParts.id == living_space.build_parts_id,
) )
if not build_parts_selection.data: if not build_parts_selection.data:
raise HTTPException( raise HTTPException(
@@ -93,19 +91,40 @@ def save_access_token_to_redis(
detail=dict( detail=dict(
message="No build Part is found for the living space. Please contact the admin." message="No build Part is found for the living space. Please contact the admin."
), ),
headers=request.headers,
) )
build_part = build_parts_selection.get(1) build_part = build_parts_selection.get(1)
build = build_part.buildings
occupant_dict = { occupant_type = OccupantTypes.filter_by_one(
"uu_id": str(living_space.occupant_type_uu_id), id=living_space.occupant_type,
"id": living_space.occupant_type, system=True,
} ).data
if not str(build_part.uu_id) in occupants_selection_dict: if not str(build.uu_id) in occupants_selection_dict:
occupants_selection_dict[str(build_part.uu_id)] = [occupant_dict] occupants_selection_dict[str(build.uu_id)] = dict(
elif str(build_part.uu_id) in occupants_selection_dict: build_uu_id=str(build.uu_id),
occupants_selection_dict[str(build_part.uu_id)].append(occupant_dict) 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( save_object_to_redis(
access_token=access_token, access_token=access_token,
model_object=OccupantTokenObject( model_object=OccupantTokenObject(
@@ -120,32 +139,42 @@ def save_access_token_to_redis(
available_occupants=occupants_selection_dict, 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( return dict(
user_type=UserType.occupant.name, 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) list_employee = Employees.filter_all(
companies_uu_id_list, companies_id_list = [], [] Employees.people_id == found_user.person_id,
).data
companies_uu_id_list, companies_id_list, companies_list = [], [], []
duty_uu_id_list, duty_id_list = [], [] duty_uu_id_list, duty_id_list = [], []
for employee in list_employee.data: for employee in list_employee:
staff = Staff.find_one(id=employee.staff_id) staff = Staff.filter_one(Staff.id == employee.staff_id).data
if duties := Duties.find_one(id=staff.duties_id): if duties := Duties.filter_one(Duties.id == staff.duties_id).data:
if duty_found := Duty.find_one(id=duties.duties_id): if duty_found := Duty.filter_by_one(id=duties.duties_id).data:
duty_uu_id_list.append(str(duty_found.uu_id)) duty_uu_id_list.append(str(duty_found.uu_id))
duty_id_list.append(duty_found.id) duty_id_list.append(duty_found.id)
department = Departments.find_one(id=duties.department_id) department = Departments.filter_one(
if company := Companies.find_one(id=department.company_id): 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_uu_id_list.append(str(company.uu_id))
companies_id_list.append(company.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( save_object_to_redis(
access_token=access_token, access_token=access_token,
model_object=EmployeeTokenObject( model_object=EmployeeTokenObject(
@@ -165,7 +194,7 @@ def save_access_token_to_redis(
) )
return dict( return dict(
user_type=UserType.employee.name, 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 import HTTPException, status
from fastapi.requests import Request
from databases import Events
def parse_token_object_to_dict(request: Request): # from requests import Request def parse_token_object_to_dict(request): # from requests import Request
from api_services.redis.functions import get_object_via_access_key
from databases import EndpointRestriction
import api_events.events as events 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): if valid_token := get_object_via_access_key(request=request):
endpoint_name = str(request.url).replace(str(request.base_url), "/") endpoint_name = str(request.url).replace(str(request.base_url), "/")
endpoint_active = EndpointRestriction.filter_active( if (
EndpointRestriction.endpoint_name.ilike(f"%{endpoint_name}%") str(endpoint_name) in Config.INSECURE_PATHS
).data[0] 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: if not endpoint_active:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, 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 valid_token.user_type == 1:
if not valid_token.selected_company: if not valid_token.selected_company:
raise HTTPException( 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.", 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.endpoint_id == endpoint_active.id,
Events.id.in_(valid_token.selected_company.reachable_event_list_id), Events.id.in_(valid_token.selected_company.reachable_event_list_id),
) ).data
if not selected_event.data: if not selected_event:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, status_code=status.HTTP_401_UNAUTHORIZED,
detail="This endpoint requires event validation. Please contact your responsible company to use this event.", 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_class = getattr(selected_event, "function_class", None)
event_function_code = getattr(selected_event, "function_code", None) event_function_code = getattr(selected_event, "function_code", None)
function_class = getattr(events, event_function_class, 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, status_code=status.HTTP_418_IM_A_TEAPOT,
detail="Selected occupant is not found in the token object.", 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.endpoint_id == endpoint_active.id,
Events.id.in_(valid_token.selected_occupant.reachable_event_list_id), Events.id.in_(valid_token.selected_occupant.reachable_event_list_id),
) )
if not selected_event.data: if not selected_event.data:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, 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] selected_event = selected_event.data[0]
event_function_class = getattr(selected_event, "function_class", None) 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: if not active_function:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, 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 valid_token.available_event = active_function
return valid_token return valid_token

View File

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

View File

@@ -12,81 +12,132 @@ class AlchemyJsonResponse:
completed: bool completed: bool
filter_attributes: Any = None filter_attributes: Any = None
response_model: 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__( def __new__(
cls, cls,
message: str, message: str,
status_code: str = 'HTTP_200_OK', status_code: str = "HTTP_200_OK",
result: Union[Any, list] = None, result: Union[Any, list] = None,
completed: bool = True 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.status_code = getattr(status, status_code, "HTTP_200_OK")
cls.message = message cls.message = message
cls.result = result cls.result = result
cls.completed = completed cls.completed = completed
cls.response_model = response_model
first_item = cls.result.get(1) pagination_dict = {
"size/total_count": [10, 10],
"page/total_page": [1, 1],
"order_field": "id",
"order_type": "asc",
}
if filter_attributes:
total_page_number = cls.get_total_count(cls_object, filter_attributes)
pagination_dict = {
"size/total_count": [filter_attributes.size, cls_object.total_count],
"page/total_page": [filter_attributes.page, total_page_number],
"order_field": filter_attributes.order_field,
"order_type": filter_attributes.order_type,
}
if isinstance(cls.result, dict) or isinstance(cls.result, list):
return JSONResponse(
status_code=cls.status_code,
content=dict(
total_count=len(cls.result),
count=len(cls.result),
pagination=pagination_dict,
completed=cls.completed,
message=cls.message,
data=cls.result,
),
)
first_item = getattr(cls.result, "data", None)
if not first_item: if not first_item:
return JSONResponse( return JSONResponse(
status_code=cls.status_code, status_code=cls.status_code,
content=dict( content=dict(
total_count=0, total_count=0,
count=0, count=0,
pagination=None, pagination=pagination_dict,
completed=cls.completed, completed=cls.completed,
message=cls.message, message=cls.message,
data=[], data=[],
), ),
) )
if cls.result.first: if cls.result.first:
return JSONResponse( return JSONResponse(
status_code=cls.status_code, status_code=cls.status_code,
content=dict( content=dict(
total_count=1, total_count=1,
count=1, count=1,
pagination=None, pagination=pagination_dict,
completed=cls.completed, completed=cls.completed,
message=cls.message, message=cls.message,
data=cls.result.data.get_dict(), data=cls.result.data.get_dict(),
), ),
) )
if not first_item.filter_attr: if not cls.result.get(1).filter_attr and isinstance(cls.result.data, list):
counts = cls.result.count counts = cls.result.count
return JSONResponse( return JSONResponse(
status_code=cls.status_code, status_code=cls.status_code,
content=dict( content=dict(
total_count=counts, total_count=counts,
count=counts, count=counts,
pagination=None, pagination=pagination_dict,
completed=cls.completed, completed=cls.completed,
message=cls.message, message=cls.message,
data=[result_data.get_dict() for result_data in cls.result.data], data=[result_data.get_dict() for result_data in cls.result.data],
), ),
) )
filter_model = first_item.filter_attr # filter_model = cls.result.get(1).filter_attr
total_count = cls.result.query.limit(None).offset(None).count() total_count = cls.result.get(1).query.limit(None).offset(None).count()
total_page_number = round(total_count / int(first_item.filter_attr.size), 0) + 1 total_page_number = cls.get_total_count(cls_object, filter_attributes)
pagination_dict = { pagination_dict = {
"size/total_count": [cls.result.count, total_count], "size/total_count": [filter_attributes.size, cls_object.total_count],
"page/total_page": [filter_model.page, total_page_number], "page/total_page": [filter_attributes.page, total_page_number],
"order_field": filter_model.order_field, "order_field": filter_attributes.order_field,
"order_type": filter_model.order_type, "order_type": filter_attributes.order_type,
} }
include_joins = dict( include_joins = dict(
include_joins=filter_model.include_joins if filter_model.include_joins else [] include_joins=(
filter_attributes.include_joins
if filter_attributes.include_joins
else []
)
) )
data = [] data = []
for data_object in cls.result.data: for data_object in cls.result.data:
data_dict = data_object.get_dict(include_joins=include_joins) data_dict = data_object.get_dict(include_joins=include_joins)
if cls.response_model: if cls.response_model:
data_dict = cls.response_model(**data_object.get_dict(include_joins=include_joins)).dump() data_dict = cls.response_model(
**data_object.get_dict(include_joins=include_joins)
).dump()
data.append(data_dict) data.append(data_dict)
return JSONResponse( return JSONResponse(
status_code=cls.status_code, status_code=cls.status_code,
content=dict( content=dict(
total_count=total_count, total_count=total_count or 1,
count=cls.result.count, count=cls.result.count,
pagination=pagination_dict, pagination=pagination_dict,
message=cls.message, message=cls.message,

View File

@@ -1,11 +1,21 @@
from .core_request_validations import ( from .core_request_validations import (
ListOptions, ListOptions,
EndpointValidation,
PydanticBaseModel, PydanticBaseModel,
PatchRecord, PatchRecord,
EndpointPydantic, EndpointPydantic,
BaseModelRegular, BaseModelRegular,
PydanticBaseModelValidation,
CrudRecordValidation,
CrudRecords,
)
from .address import (
InsertAddress,
UpdateAddress,
UpdatePostCode,
InsertPostCode,
SearchAddress,
) )
from .address import InsertAddress, InsertPostCode, SearchAddress
from .application import ( from .application import (
SingleEnumUUID, SingleEnumUUID,
SingleEnumClassKey, SingleEnumClassKey,
@@ -29,6 +39,11 @@ from .authentication import (
OccupantSelection, OccupantSelection,
EmployeeSelection, EmployeeSelection,
) )
from .account_records import (
InsertAccountRecord,
UpdateAccountRecord,
)
from .build_living_space import ( from .build_living_space import (
InsertBuildLivingSpace, InsertBuildLivingSpace,
UpdateBuildLivingSpace, UpdateBuildLivingSpace,
@@ -82,27 +97,30 @@ from .employee import (
UpdateCompanyDuty, UpdateCompanyDuty,
) )
from .events import ( from .events import (
CreateEvents, # CreateEvents,
RegisterEvents2Employee, RegisterEvents2Employee,
RegisterEvents2Occupant, RegisterEvents2Occupant,
) )
from .people import ( from .people import (
UpdatePerson, UpdatePerson,
InsertPerson, InsertPerson,
ResponsePersonSalesMange,
) )
from .project_decision_book import ( from .project_decision_book import (
InsertBuildDecisionBookProjectItems,
UpdateBuildDecisionBookProjectItems,
InsertBuildDecisionBookProjectItemDebits, InsertBuildDecisionBookProjectItemDebits,
UpdateBuildDecisionBookProjectItemDebits, UpdateBuildDecisionBookProjectItemDebits,
InsertBuildDecisionBookProjects, InsertBuildDecisionBookProjects,
UpdateBuildDecisionBookProjects, UpdateBuildDecisionBookProjects,
InsertBuildDecisionBookProjectPerson,
UpdateBuildDecisionBookProjectPerson,
InsertBuildDecisionBookProjectItems,
UpdateBuildDecisionBookProjectItems,
ApprovalsBuildDecisionBookProjects,
) )
from .rules import ( from .rules import (
UpdateEndpointAccess, UpdateEndpointAccess,
UpdateEndpointAccessList, UpdateEndpointAccessList,
InsertEndpointAccess, InsertEndpointAccess,
CheckEndpointAccess,
) )
from .services import ( from .services import (
RegisterServices2Employee, RegisterServices2Employee,
@@ -116,9 +134,9 @@ from .user import (
InsertUsers, InsertUsers,
UpdateUsers, UpdateUsers,
QueryUsers, QueryUsers,
ActiveUsers, # ActiveUsers,
ListUsers, # ListUsers,
DeleteUsers, # DeleteUsers,
) )
from .modules import ( from .modules import (
RegisterModules2Occupant, RegisterModules2Occupant,
@@ -128,11 +146,17 @@ from .modules import (
__all__ = [ __all__ = [
"ListOptions", "ListOptions",
"EndpointValidation",
"PydanticBaseModelValidation",
"CrudRecordValidation",
"CrudRecords",
"PydanticBaseModel", "PydanticBaseModel",
"PatchRecord", "PatchRecord",
"EndpointPydantic", "EndpointPydantic",
"BaseModelRegular", "BaseModelRegular",
"InsertAddress", "InsertAddress",
"UpdateAddress",
"UpdatePostCode",
"InsertPostCode", "InsertPostCode",
"SearchAddress", "SearchAddress",
"SingleEnumUUID", "SingleEnumUUID",
@@ -152,6 +176,8 @@ __all__ = [
"CreatePassword", "CreatePassword",
"OccupantSelection", "OccupantSelection",
"EmployeeSelection", "EmployeeSelection",
"InsertAccountRecord",
"UpdateAccountRecord",
"InsertBuildLivingSpace", "InsertBuildLivingSpace",
"UpdateBuildLivingSpace", "UpdateBuildLivingSpace",
"InsertBuildParts", "InsertBuildParts",
@@ -190,21 +216,23 @@ __all__ = [
"InsertCompanyDuty", "InsertCompanyDuty",
"UpdateCompanyEmployeesSalaries", "UpdateCompanyEmployeesSalaries",
"UpdateCompanyDuty", "UpdateCompanyDuty",
"CreateEvents",
"RegisterEvents2Employee", "RegisterEvents2Employee",
"RegisterEvents2Occupant", "RegisterEvents2Occupant",
"UpdatePerson", "UpdatePerson",
"InsertPerson", "InsertPerson",
"ResponsePersonSalesMange",
"InsertBuildDecisionBookProjectItems", "InsertBuildDecisionBookProjectItems",
"UpdateBuildDecisionBookProjectItems", "UpdateBuildDecisionBookProjectItems",
"ApprovalsBuildDecisionBookProjects",
"InsertBuildDecisionBookProjectItemDebits", "InsertBuildDecisionBookProjectItemDebits",
"UpdateBuildDecisionBookProjectItemDebits", "UpdateBuildDecisionBookProjectItemDebits",
"InsertBuildDecisionBookProjects", "InsertBuildDecisionBookProjects",
"UpdateBuildDecisionBookProjects", "UpdateBuildDecisionBookProjects",
"InsertBuildDecisionBookProjectPerson",
"UpdateBuildDecisionBookProjectPerson",
"UpdateEndpointAccess", "UpdateEndpointAccess",
"UpdateEndpointAccessList", "UpdateEndpointAccessList",
"InsertEndpointAccess", "InsertEndpointAccess",
"CheckEndpointAccess",
"RegisterServices2Employee", "RegisterServices2Employee",
"RegisterServices2Occupant", "RegisterServices2Occupant",
"InsertStaff", "InsertStaff",
@@ -212,9 +240,6 @@ __all__ = [
"InsertUsers", "InsertUsers",
"UpdateUsers", "UpdateUsers",
"QueryUsers", "QueryUsers",
"ActiveUsers",
"ListUsers",
"DeleteUsers",
"RegisterModules2Occupant", "RegisterModules2Occupant",
"RegisterModules2Employee", "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 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 street_uu_id: str
post_code: 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 search: str
list_options: ListOptions 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_code: str
street_name: str street_name: str
postcode: str postcode: str
@@ -27,7 +75,32 @@ class InsertStreet(PydanticBaseModel):
address_geographic_uu_id: Optional[str] = None 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 post_code_uu_id: str
comment_address: Optional[str] = None comment_address: Optional[str] = None
@@ -42,14 +115,16 @@ class InsertAddress(PydanticBaseModel):
longitude: Optional[float] = None longitude: Optional[float] = None
class _UpdateAddress(PydanticBaseModel): class UpdateAddress(PydanticBaseModel, AddressValidation):
... post_code_uu_id: Optional[str] = None
# country_code: Optional[str] = None
# city: Optional[str] = None comment_address: Optional[str] = None
# district: Optional[str] = None letter_address: Optional[str] = None
# b_state: Optional[str] = None
# neighborhood: Optional[str] = None build_number: Optional[str] = None
# street: Optional[str] = None door_number: Optional[str] = None
# postcode: Optional[str] = None floor_number: Optional[str] = None
# latitude: Optional[float] = None
# longitude: Optional[float] = 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 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 SingleEnumClassKey(BaseModelRegular):
class_name: str class_name: str
key_name: str key_name: str
class SingleEnumUUIDValidation:
tr = {
"uu_id": "UUID",
}
en = {
"uu_id": "UUID",
}
class SingleEnumUUID(BaseModelRegular): class SingleEnumUUID(BaseModelRegular):
uu_id: str uu_id: str
class SingleEnumOnlyClassValidation:
tr = {
"class_name": "Sınıf Adı",
}
en = {
"class_name": "Class Name",
}
class SingleEnumOnlyClass(BaseModelRegular): class SingleEnumOnlyClass(BaseModelRegular):
class_name: str class_name: str
class SingleOccupantTypeClassKeyValidation:
tr = {
"type_code": "Tip Kodu",
}
en = {
"type_code": "Type Code",
}
class SingleOccupantTypeClassKey(BaseModelRegular): class SingleOccupantTypeClassKey(BaseModelRegular):
type_code: str type_code: str
class SingleOccupantTypeUUIDValidation:
tr = {
"uu_id": "Görev UUID",
}
en = {
"uu_id": "Occupant UUID",
}
class SingleOccupantTypeUUID(BaseModelRegular): class SingleOccupantTypeUUID(BaseModelRegular):
uu_id: str uu_id: str

View File

@@ -6,7 +6,32 @@ from api_validations.validations_request import (
) )
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 build_uu_id: str
area_name: str area_name: str
area_code: str area_code: str
@@ -18,7 +43,8 @@ class InsertBuildArea(BaseModelRegular):
size: Optional[int] = None size: Optional[int] = None
class UpdateBuildArea(PydanticBaseModel): class UpdateBuildArea(PydanticBaseModel, BuildAreaValidation):
area_name: Optional[str] = None area_name: Optional[str] = None
area_code: Optional[str] = None area_code: Optional[str] = None
area_type: Optional[str] = None area_type: Optional[str] = None
@@ -29,12 +55,23 @@ class UpdateBuildArea(PydanticBaseModel):
size: Optional[int] = None 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 address_uu_id: str
site_name: str site_name: str
site_no: str site_no: str
class UpdateBuildSites(PydanticBaseModel): class UpdateBuildSites(PydanticBaseModel, BuildSites):
site_name: Optional[str] = None site_name: Optional[str] = None
site_no: Optional[str] = None site_no: Optional[str] = None

View File

@@ -7,44 +7,102 @@ from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel
class ChangePassword(BaseModelRegular): class ChangePasswordValidation:
domain_name: str tr = {"old_password": "Eski Şifre", "new_password": "Yeni Şifre"}
access_key: str en = {"old_password": "Old Password", "new_password": "New Password"}
class ChangePassword(BaseModelRegular, ChangePasswordValidation):
old_password: str old_password: str
new_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_token: str
password: str password: str
re_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 occupant_uu_id: str
build_part_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 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 domain: str
access_key: str access_key: str
password: str password: str
remember_me: Optional[bool] = False remember_me: Optional[bool] = False
class Logout(BaseModelRegular): class LogoutValidation:
tr = {"domain": "Domain"}
en = {"domain": "Domain"}
class Logout(BaseModelRegular, LogoutValidation):
domain: str 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 domain: str
refresh_token: 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 domain: str
access_key: str access_key: str

View File

@@ -2,17 +2,52 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions, 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 person_uu_id: str
build_parts_uu_id: str build_parts_uu_id: str
occupant_type_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 is_tenant_live: Optional[bool] = None
build_parts_uu_id: Optional[str] = None build_parts_uu_id: Optional[str] = None
person_uu_id: Optional[str] = None person_uu_id: Optional[str] = None

View File

@@ -2,21 +2,81 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions, 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 function_code: str
type_code: str type_code: str
lang: str lang: str
type_name: 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 build_uu_id: str
address_gov_code: str address_gov_code: str
part_no: int part_no: int
@@ -28,12 +88,43 @@ class InsertBuildParts(PydanticBaseModel):
default_accessory: Optional[str] = None default_accessory: Optional[str] = None
human_livable: Optional[bool] = False human_livable: Optional[bool] = False
part_direction_uu_id: Optional[str] = None part_direction_uu_id: Optional[str] = None
ref_id: Optional[str] = None
# current_owner_person_uu_id: Optional[str] = None
# current_tenant_person_uu_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 address_gov_code: Optional[str] = None
part_no: Optional[int] = None part_no: Optional[int] = None
part_level: Optional[int] = None part_level: Optional[int] = None

View File

@@ -1,20 +1,66 @@
from typing import Optional from typing import Optional
from datetime import datetime
from api_validations.core_validations import BaseModelRegular from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, 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 gov_address_code: str
build_name: str build_name: str
build_types_uu_id: str build_types_uu_id: str
max_floor: int max_floor: int
underground_floor: int underground_floor: int
address_uu_id: str address_uu_id: str
build_date: str build_date: datetime
decision_period_date: str decision_period_date: datetime
tax_no: Optional[str] = None tax_no: Optional[str] = None
lift_count: Optional[int] = None lift_count: Optional[int] = None
@@ -26,14 +72,25 @@ class InsertBuild(PydanticBaseModel):
garage_count: Optional[int] = None 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 gov_address_code: Optional[str] = None
build_name: Optional[str] = None build_name: Optional[str] = None
build_no: 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 max_floor: Optional[int] = None
underground_floor: Optional[int] = None underground_floor: Optional[int] = None
build_date: Optional[str] = None build_date: Optional[datetime] = None
tax_no: Optional[str] = None tax_no: Optional[str] = None
lift_count: Optional[int] = None lift_count: Optional[int] = None
heating_system: Optional[bool] = None heating_system: Optional[bool] = None

View File

@@ -2,11 +2,26 @@ from typing import Optional, List
from api_validations.core_validations import BaseModelRegular from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions, 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 formal_name: str
company_type: str company_type: str
commercial_type: str commercial_type: str
@@ -15,11 +30,22 @@ class InsertCompany(PydanticBaseModel):
company_tag: Optional[str] = None company_tag: Optional[str] = None
default_lang_type: Optional[str] = None default_lang_type: Optional[str] = None
default_money_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 # 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 company_uu_id: str
public_name: Optional[str] = None public_name: Optional[str] = None
formal_name: Optional[str] = None formal_name: Optional[str] = None
@@ -27,9 +53,23 @@ class UpdateCompany(PydanticBaseModel):
company_tag: Optional[str] = None company_tag: Optional[str] = None
default_lang_type: Optional[str] = None default_lang_type: Optional[str] = None
default_money_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] match_company_uu_id: List[str]
duty_uu_id: 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 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 page: Optional[int] = 1
size: Optional[int] = 10 size: Optional[int] = 10
order_field: Optional[str] = "id" order_field: Optional[str] = "id"
order_type: Optional[str] = "asc" order_type: Optional[str] = "asc"
include_joins: Optional[list] = [] include_joins: Optional[list] = None
query: Optional[dict] = {} 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): class PydanticBaseModel(BaseModelRegular):
active: Optional[bool] = None active: Optional[bool] = None
deleted: Optional[bool] = None deleted: Optional[bool] = None
is_confirmed: Optional[bool] = None
expiry_starts: Optional[str] = None expiry_starts: Optional[str] = None
expiry_ends: Optional[str] = None # expiry_ends: Optional[str] = None
is_confirmed: Optional[bool] = None
class EndpointPydantic(BaseModelRegular): class EndpointPydantic(BaseModelRegular):
data: Optional[dict] = None
data: Optional[dict] = {}
class EndpointValidation(BaseModelRegular):
endpoint: Optional[str] = None
class PatchRecord(BaseModelRegular): class PatchRecord(BaseModelRegular):

View File

@@ -58,7 +58,7 @@ class ConvertField:
# detail=f"Pydantic class {selected_model.model_type} not found in database. Please add model to api.", # 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 # ModelEntities.model_id == selected_model.id
# ).data # ).data
# #

View File

@@ -2,37 +2,126 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions, ListOptions,
) )
class DecisionBookDecisionBookInvitations(BaseModelRegular): 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 build_decision_book_uu_id: str
message: str message: str
planned_date: str planned_date: str
class DecisionBookDecisionBookInvitationsAttend(BaseModelRegular): class DecisionBookDecisionBookInvitationsAttendValidation:
tr = {
"token": "Token",
"is_attend": "Katılacak mı?",
}
en = {
"token": "Token",
"is_attend": "Is Attend?",
}
class DecisionBookDecisionBookInvitationsAttend(
BaseModelRegular, DecisionBookDecisionBookInvitationsAttendValidation
):
token: str token: str
is_attend: bool is_attend: bool
class DecisionBookDecisionBookInvitationsAssign(BaseModelRegular): 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 token: str
build_living_space_uu_id: str build_living_space_uu_id: str
occupant_type_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 token: str
occupant_type_uu_id: Optional[str] = None occupant_type_uu_id: Optional[str] = None
class ListDecisionBook(ListOptions, 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 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 build_uu_id: str
decision_type: str decision_type: str
meeting_date: str meeting_date: str
@@ -42,12 +131,44 @@ class InsertDecisionBook(PydanticBaseModel):
resp_company_uu_id: Optional[str] = None resp_company_uu_id: Optional[str] = None
class InsertDecisionBookCompleted(BaseModelRegular): 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 build_decision_book_uu_id: str
meeting_completed_date: str meeting_completed_date: str
class InsertDecisionBookPerson(BaseModelRegular): 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 person_uu_id: str
build_decision_book_uu_id: str build_decision_book_uu_id: str
management_typecode_uu_id: str management_typecode_uu_id: str
@@ -57,12 +178,67 @@ class InsertDecisionBookPerson(BaseModelRegular):
dues_percent_discount: Optional[int] = None 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 person_uu_id: str
build_decision_book_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 decision_book_pdf_path: Optional[str] = None
is_out_sourced: Optional[bool] = None is_out_sourced: Optional[bool] = None
contact_agreement_path: Optional[str] = None contact_agreement_path: Optional[str] = None
@@ -74,34 +250,107 @@ class UpdateDecisionBook(PydanticBaseModel):
resp_company_uu_id: Optional[str] = None resp_company_uu_id: Optional[str] = None
class InsertBuildDecisionBookItems(BaseModelRegular): 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 token: str
info_type_uu_id: str info_type_uu_id: str
unit_price: float item_comment: str
currency: Optional[str] = "TL" currency: Optional[str] = "TL"
unit_type: Optional[str] = "M2" unit_type: Optional[str] = "M2"
debit_start_date: Optional[str] = None debit_start_date: Optional[str] = None
debit_end_date: Optional[str] = None debit_end_date: Optional[str] = None
unit_price_is_fixed: Optional[bool] = False unit_price_is_fixed: Optional[bool] = False
item_comment: Optional[str] = None unit_price: Optional[float] = 0.00
# build_decision_book_uu_id: str # build_decision_book_uu_id: str
# item_objection: Optional[str] = None # 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_comment: Optional[str] = None
item_objection: Optional[str] = None item_objection: Optional[str] = None
class InsertBuildDecisionBookItemDebits(BaseModelRegular): 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 build_decision_book_item_uu_id: str
dues_values: dict dues_values: dict
# dues_types_uu_id: str # dues_types_uu_id: str
# decision_taken: Optional[bool] = None # 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_types_uu_id: Optional[str] = None
dues_values: Optional[dict] = None dues_values: Optional[dict] = None
decision_taken: Optional[bool] = 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.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions, 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_code: Optional[str]
department_name: 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.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions, 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 staff_uu_id: str
people_uu_id: str people_uu_id: str
expiry_starts: Optional[str] = None 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 people_uu_id: str
expiry_ends: 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 staff_uu_id: str
people_uu_id: Optional[str] = None 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_code: str
duty_name: str duty_name: str
duty_description: Optional[str] = None 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 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 duties_uu_id: str
department_uu_id: str department_uu_id: str
is_default_duty: Optional[bool] = False 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): class UpdateDuties(PydanticBaseModel):
duties_uu_id: Optional[str] = None duties_uu_id: Optional[str] = None
department_uu_id: Optional[str] = None department_uu_id: Optional[str] = None
is_default_duty: Optional[bool] = 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): class UpdateCompanyDuty(PydanticBaseModel):
duty_code: Optional[str] = None duty_code: Optional[str] = None
duty_name: Optional[str] = None duty_name: Optional[str] = None
duty_description: 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 gross_salary: float
net_salary: float net_salary: float
start_date: str start_date: str
@@ -58,6 +180,25 @@ class InsertCompanyEmployeesSalaries(PydanticBaseModel):
people_id: int 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): class UpdateCompanyEmployeesSalaries(PydanticBaseModel):
gross_salary: Optional[float] = None gross_salary: Optional[float] = None
net_salary: Optional[float] = None net_salary: Optional[float] = None
@@ -66,7 +207,24 @@ class UpdateCompanyEmployeesSalaries(PydanticBaseModel):
people_id: Optional[int] = None 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 employee_description: Optional[str] = None
person_uu_id: str person_uu_id: str
@@ -76,6 +234,19 @@ class InsertCompanyEmployees(PydanticBaseModel):
stop_date: Optional[str] = None 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 stop_date: Optional[str] = None
employee_description: Optional[str] = None employee_description: Optional[str] = None

View File

@@ -6,19 +6,36 @@ from api_validations.validations_request import (
) )
class CreateEvents(PydanticBaseModel): class RegisterEvents2EmployeeValidation:
event_name: Optional[str] = None tr = {
event_description: Optional[str] = None "event_uu_id_list": "Etkinlikler Listesi",
event_date: Optional[str] = None "employee_uu_id": "Çalışan UU ID",
event_location: Optional[str] = None }
en = {
"event_uu_id_list": "Event List",
"employee_uu_id": "Employee UU ID",
}
class RegisterEvents2Employee(PydanticBaseModel): class RegisterEvents2Employee(BaseModelRegular, RegisterEvents2EmployeeValidation):
event_uu_id_list: list[str] = [] event_uu_id_list: list[str] = None
employee_uu_id: Optional[str] = None employee_uu_id: Optional[str] = None
class RegisterEvents2Occupant(PydanticBaseModel): class RegisterEvents2OccupantValidation:
event_uu_id_list: list[str] = [] 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 build_part_uu_id: Optional[str] = None
occupant_uu_id: Optional[str] = None occupant_uu_id: Optional[str] = None

View File

@@ -5,12 +5,36 @@ from api_validations.validations_request import (
) )
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 modules_uu_id: str
occupant_uu_id: str occupant_uu_id: str
build_part_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 modules_uu_id: str
employee_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.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, PydanticBaseModel,
PydanticBaseModelValidation,
ListOptions, 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 firstname: str
surname: str surname: str
sex_code: str sex_code: str
@@ -18,19 +36,21 @@ class InsertPerson(PydanticBaseModel):
birth_place: Optional[str] = None birth_place: Optional[str] = None
birth_date: Optional[str] = None birth_date: Optional[str] = None
tax_no: Optional[str] = None tax_no: Optional[str] = None
ref_id: Optional[str] = None
class ResponsePersonSalesMange(PydanticBaseModel): class UpdatePersonValidation:
uu_id: str tr = {
firstname: str **PydanticBaseModelValidation.tr,
surname: str **InsertPersonValidation.tr,
national_identity_id: str }
birth_place: Optional[str] = None en = {
birth_date: Optional[str] = None **PydanticBaseModelValidation.en,
tax_no: Optional[str] = None **InsertPersonValidation.tr,
}
class UpdatePerson(PydanticBaseModel): class UpdatePerson(PydanticBaseModel, UpdatePersonValidation):
firstname: Optional[str] = None firstname: Optional[str] = None
surname: Optional[str] = None surname: Optional[str] = None
middle_name: Optional[str] middle_name: Optional[str]

View File

@@ -2,13 +2,156 @@ from typing import Optional
from api_validations.core_validations import BaseModelRegular from api_validations.core_validations import BaseModelRegular
from api_validations.validations_request import ( from api_validations.validations_request import (
PydanticBaseModel, 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 build_decision_book_item_uu_id: str
project_response_person_uu_id: str project_responsible_person_uu_id: str
project_name: str project_name: str
project_start_date: str project_start_date: str
project_stop_date: str project_stop_date: str
@@ -21,43 +164,88 @@ class InsertBuildDecisionBookProjects(PydanticBaseModel):
contact_agreement_path: Optional[str] = None contact_agreement_path: Optional[str] = None
contact_agreement_date: Optional[str] = None contact_agreement_date: Optional[str] = None
meeting_date: Optional[str] = None meeting_date: Optional[str] = None
currency: Optional[str] = None
bid_price: Optional[float] = None bid_price: Optional[float] = None
approved_price: Optional[float] = None
final_price: Optional[float] = None
resp_company_uu_id: Optional[str] = None resp_company_uu_id: Optional[str] = None
class UpdateBuildDecisionBookProjects(PydanticBaseModel): class UpdateBuildDecisionBookProjectsValidation:
resp_company_uu_id: Optional[str] = None tr = {
**InsertBuildDecisionBookProjectsValidation.tr,
**PydanticBaseModelValidation.tr,
}
en = {
**InsertBuildDecisionBookProjectsValidation.en,
**PydanticBaseModelValidation.en,
}
project_response: Optional[str] = None
project_name: Optional[str] = None class UpdateBuildDecisionBookProjects(
project_type: Optional[str] = None PydanticBaseModel, UpdateBuildDecisionBookProjectsValidation
):
build_decision_book_project_uu_id: str
is_out_sourced: Optional[bool] = False
project_note: Optional[str] = None 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 resp_company_fix_wage: Optional[float] = None
is_out_sourced: Optional[bool] = None
contact_agreement_path: Optional[str] = None contact_agreement_path: Optional[str] = None
contact_agreement_date: Optional[str] = None contact_agreement_date: Optional[str] = None
meeting_date: Optional[str] = None contact_uu_id: Optional[str] = None
bid_price: Optional[float] = None resp_company_uu_id: Optional[str] = None
approved_price: Optional[float] = None approved_price: Optional[float] = None
final_price: Optional[float] = None
class InsertBuildDecisionBookProjectItems(PydanticBaseModel): class ApprovalsBuildDecisionBookProjectsValidation:
item_order: int tr = {
item_comment: str "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 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): class InsertBuildDecisionBookProjectItemDebitsValidation:
item_comment: Optional[str] = None tr = {
item_objection: Optional[str] = None "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 build_decision_book_project_item_uu_id: str
payment_date: str payment_date: str
dues_values: dict dues_values: dict
@@ -67,7 +255,20 @@ class InsertBuildDecisionBookProjectItemDebits(PydanticBaseModel):
decision_taken: Optional[bool] = None 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 dues_values: Optional[str] = None
discount_value: Optional[float] = None discount_value: Optional[float] = None
discount_fix: 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): class InsertEndpointAccess(PydanticBaseModel):
duty_uu_id: str duty_uu_id: str
endpoint_restriction_list_uu_ids: list endpoint_restriction_list_uu_ids: list

View File

@@ -5,12 +5,36 @@ from api_validations.validations_request import (
) )
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 service_uu_id: str
occupant_uu_id: str occupant_uu_id: str
build_part_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 service_uu_id: str
employee_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_name: str
staff_description: Optional[str] = None staff_description: Optional[str] = None
staff_code: Optional[str] = None staff_code: Optional[str] = None
duties_uu_id: str 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 duties_uu_id: str

View File

@@ -6,7 +6,24 @@ from api_validations.validations_request import (
) )
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 people_uu_id: str
user_tag: str user_tag: str
email: Optional[str] = None email: Optional[str] = None
@@ -14,7 +31,26 @@ class InsertUsers(PydanticBaseModel):
avatar: Optional[str] = None 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 people_uu_id: Optional[str] = None
nick_name: Optional[str] = None nick_name: Optional[str] = None
domain_name: Optional[str] = None domain_name: Optional[str] = None
@@ -23,23 +59,14 @@ class UpdateUsers(PydanticBaseModel):
avatar: Optional[str] = None avatar: Optional[str] = None
class QueryUsersValidation:
tr = {
"uu_id": "UUID",
}
en = {
"uu_id": "UUID",
}
class QueryUsers(PydanticBaseModel): class QueryUsers(PydanticBaseModel):
uu_id: Optional[str] = None 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,6 +6,13 @@ from databases.sql_models.account.account import (
AccountCodes, AccountCodes,
AccountDetail, AccountDetail,
AccountMaster, AccountMaster,
AccountRecordExchanges,
)
from databases.sql_models.building.budget import (
DecisionBookBudgetBooks,
DecisionBookBudgetCodes,
DecisionBookBudgetMaster,
DecisionBookBudgets,
) )
from databases.sql_models.account.iban import ( from databases.sql_models.account.iban import (
BuildIbans, BuildIbans,
@@ -34,6 +41,7 @@ from databases.sql_models.building.decision_book import (
BuildDecisionBookProjects, BuildDecisionBookProjects,
BuildDecisionBookProjectPerson, BuildDecisionBookProjectPerson,
BuildDecisionBookPersonOccupants, BuildDecisionBookPersonOccupants,
BuildDecisionBookProjectItems,
) )
from databases.sql_models.company.company import ( from databases.sql_models.company.company import (
Companies, Companies,
@@ -57,6 +65,8 @@ from databases.sql_models.event.event import (
Events, Events,
Event2Occupant, Event2Occupant,
Event2Employee, Event2Employee,
Event2OccupantExtra,
Event2EmployeeExtra,
) )
from databases.sql_models.identity.identity import ( from databases.sql_models.identity.identity import (
Addresses, Addresses,
@@ -99,6 +109,7 @@ __all__ = [
"AccountCodes", "AccountCodes",
"AccountDetail", "AccountDetail",
"AccountMaster", "AccountMaster",
"AccountRecordExchanges",
"BuildIbans", "BuildIbans",
"BuildIbanDescription", "BuildIbanDescription",
"CrypterEngine", "CrypterEngine",
@@ -120,6 +131,11 @@ __all__ = [
"BuildDecisionBookProjects", "BuildDecisionBookProjects",
"BuildDecisionBookProjectPerson", "BuildDecisionBookProjectPerson",
"BuildDecisionBookPersonOccupants", "BuildDecisionBookPersonOccupants",
"BuildDecisionBookProjectItems",
"DecisionBookBudgetBooks",
"DecisionBookBudgetCodes",
"DecisionBookBudgetMaster",
"DecisionBookBudgets",
"Companies", "Companies",
"RelationshipDutyCompany", "RelationshipDutyCompany",
"Employees", "Employees",
@@ -135,6 +151,8 @@ __all__ = [
"Events", "Events",
"Event2Occupant", "Event2Occupant",
"Event2Employee", "Event2Employee",
"Event2OccupantExtra",
"Event2EmployeeExtra",
"Addresses", "Addresses",
"AddressCity", "AddressCity",
"AddressStreet", "AddressStreet",

View File

@@ -8,13 +8,6 @@ from datetime import timedelta
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from fastapi import status from fastapi import status
from databases import (
Users,
People,
Companies,
UsersTokens,
MongoQueryIdentity,
)
from databases.no_sql_models.validations import ( from databases.no_sql_models.validations import (
PasswordHistoryViaUser, PasswordHistoryViaUser,
AccessHistoryViaUser, AccessHistoryViaUser,
@@ -23,8 +16,6 @@ from databases.no_sql_models.validations import (
from api_library.date_time_actions.date_functions import system_arrow, client_arrow from api_library.date_time_actions.date_functions import system_arrow, client_arrow
from api_configs import ApiStatic, Auth from api_configs import ApiStatic, Auth
from api_services.redis.auth_actions.auth import save_access_token_to_redis
class PasswordModule: class PasswordModule:
@@ -39,6 +30,11 @@ class PasswordModule:
@classmethod @classmethod
def check_hashed_password(cls, domain, id_, password, password_hashed): 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 return cls.create_hashed_password(domain, id_, password) == password_hashed
@@ -46,56 +42,56 @@ class AuthModule(PasswordModule):
@classmethod @classmethod
def check_user_exits(cls, access_key, domain): def check_user_exits(cls, access_key, domain):
from databases import Users
found_user: Users = cls.filter_active( found_user = Users.query.filter(
or_( or_(
cls.email == str(access_key).lower(), Users.email == str(access_key).lower(),
cls.phone_number == str(access_key).replace(" ", ""), Users.phone_number == str(access_key).replace(" ", ""),
), ),
filter_records=False, ).first()
) if not found_user:
if not found_user.data:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Given access key or domain is not matching with the any user record.", detail="Given access key or domain is not matching with the any user record.",
) )
found_user = found_user.data[0]
other_domains_list = found_user.get_main_domain_and_other_domains( other_domains_list = found_user.get_main_domain_and_other_domains(
get_main_domain=False get_main_domain=False
) )
if domain not in other_domains_list: if domain not in other_domains_list:
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail=dict(message="Unauthorized User attempts to connect api"), detail=dict(message="Unauthorized User attempts to connect api"),
) )
if not found_user:
raise HTTPException(
status_code=401,
detail="Given access key or domain is not matching with the any user record.",
)
return found_user return found_user
def generate_access_token(self): def generate_access_token(self):
return self.generate_token(Auth.ACCESS_TOKEN_LENGTH) return self.generate_token(Auth.ACCESS_TOKEN_LENGTH)
def remove_refresher_token(self, domain, disconnect: bool = False): def remove_refresher_token(self, domain, disconnect: bool = False):
registered_tokens = ([], 0) from databases import (
UsersTokens,
)
if disconnect: if disconnect:
registered_tokens = UsersTokens.filter_by(user_id=self.id) registered_tokens = UsersTokens.filter_all(
UsersTokens.user_id == self.id, system=True
)
else: else:
registered_tokens = UsersTokens.filter_by(domain=domain, user_id=self.id) registered_tokens = UsersTokens.filter_all(
for token in registered_tokens[0]: UsersTokens.domain == domain,
token.session.delete(token) UsersTokens.user_id == self.id,
token.session.commit() system=True,
token.session.flush() )
registered_tokens.query.delete()
UsersTokens.save()
def check_password(self, password): def check_password(self, password):
main_domain = self.get_main_domain_and_other_domains(get_main_domain=True) main_domain = self.get_main_domain_and_other_domains(get_main_domain=True)
if check_password := self.check_hashed_password( if check_password := self.check_hashed_password(
domain=main_domain, domain=main_domain,
id_=self.uu_id, id_=str(self.uu_id),
password_hashed=self.hash_password, password_hashed=self.hash_password,
password=password, password=password,
): ):
@@ -115,103 +111,118 @@ class AuthModule(PasswordModule):
detail="New password is same with old password.", detail="New password is same with old password.",
) )
def create_password(self, password, password_token=None): @staticmethod
if self.password_token: def create_password(found_user, password, password_token=None):
from databases import MongoQueryIdentity
if found_user.password_token:
replace_day = 0 replace_day = 0
try: try:
replace_day = int( replace_day = int(
str(self.password_expires_day or 0) str(found_user.password_expires_day or 0)
.split(",")[0] .split(",")[0]
.replace(" days", "") .replace(" days", "")
) )
except Exception as e: except Exception as e:
err = e err = e
token_is_expired = system_arrow.now() >= system_arrow.get( token_is_expired = system_arrow.now() >= system_arrow.get(
self.password_expiry_begins str(found_user.password_expiry_begins)
).shift(days=replace_day) ).shift(days=replace_day)
if not password_token == self.password_token and token_is_expired: if not password_token == found_user.password_token and token_is_expired:
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail="Password token is not valid. Please request a new password token.", detail="Password token is not valid. Please request a new password token.",
) )
query_engine = MongoQueryIdentity(company_uuid=found_user.related_company)
query_engine = MongoQueryIdentity(company_uuid=self.related_company) domain_via_user = query_engine.get_domain_via_user(
domain_via_user = query_engine.get_domain_via_user(user_uu_id=str(self.uu_id))[ user_uu_id=str(found_user.uu_id)
"main_domain" )["main_domain"]
]
new_password_dict = { new_password_dict = {
"password": self.create_hashed_password( "password": found_user.create_hashed_password(
domain=domain_via_user, id_=self.uu_id, password=password domain=domain_via_user, id_=str(found_user.uu_id), password=password
), ),
"date": str(system_arrow.now()), "date": str(system_arrow.now().date()),
} }
history_dict = PasswordHistoryViaUser( history_dict = PasswordHistoryViaUser(
user_uu_id=str(self.uu_id), user_uu_id=str(found_user.uu_id),
password_add=new_password_dict, password_add=new_password_dict,
access_history_detail={ access_history_detail={
"request": "", "request": "",
"ip": "", "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) query_engine.refresh_password_history_via_user(payload=history_dict)
self.password_expiry_begins = str(system_arrow.now()) found_user.save()
self.hash_password = new_password_dict.get("password") return found_user
if self.password_token:
self.password_token = None
self.save()
def reset_password_token(self): @staticmethod
self.password_expiry_begins = str(system_arrow.now()) def reset_password_token(found_user):
self.password_token = self.generate_token(127) found_user.password_expiry_begins = str(system_arrow.now())
self.save() 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): def generate_refresher_token(self, domain: str, remember_me=False):
from databases import (
UsersTokens,
)
if remember_me: if remember_me:
refresh_token = self.generate_token(Auth.REFRESHER_TOKEN_LENGTH) refresh_token = self.generate_token(Auth.REFRESHER_TOKEN_LENGTH)
if already_token := UsersTokens.find_one( if already_token := UsersTokens.filter_by_one(
user_id=self.id, token_type="RememberMe", domain=domain system=True, user_id=self.id, token_type="RememberMe", domain=domain
): ).data:
already_token.update(token=refresh_token) already_token.update(token=refresh_token)
already_token.expires_at = system_arrow.shift(days=3) already_token.expires_at = system_arrow.shift(days=3)
already_token.save() already_token.save()
return refresh_token return refresh_token
UsersTokens.create( 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, user_id=self.id,
token_type="RememberMe", token_type="RememberMe",
token=refresh_token, token=refresh_token,
domain=domain, domain=domain,
) )
users_token.save_and_confirm()
return refresh_token return refresh_token
return None return None
def remainder_day(self): def remainder_day(self):
return float( join_list = [
timedelta( _ for _ in str(self.password_expires_day).split(",")[0] if _.isdigit()
days=int(
"".join(
[
_
for _ in str(self.password_expires_day).split(",")[0]
if _.isdigit()
] ]
) return float(timedelta(days=int("".join(join_list))).seconds)
)
).seconds
)
class UserLoginModule(AuthModule): class UserLoginModule(AuthModule):
@classmethod @classmethod
def login_user_with_credentials(cls, data, request): 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( found_user = Users.check_user_exits(
access_key=data.access_key, domain=data.domain access_key=data.access_key, domain=data.domain
) )
access_token = found_user.generate_access_token() access_token = found_user.generate_access_token()
query_engine = MongoQueryIdentity(company_uuid=found_user.related_company) query_engine = MongoQueryIdentity(company_uuid=found_user.related_company)
if found_user.check_password(password=data.password): if found_user.check_password(password=data.password):
access_object_to_redis = save_access_token_to_redis( access_object_to_redis = save_access_token_to_redis(
request=request, request=request,
@@ -231,7 +242,6 @@ class UserLoginModule(AuthModule):
found_user.last_platform = headers_request.get("evyos-platform", 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_remote_addr = headers_request.get("evyos-ip-ext", None)
found_user.last_seen = str(system_arrow.now()) found_user.last_seen = str(system_arrow.now())
if ext_ip := headers_request.get("evyos-ip-ext"): if ext_ip := headers_request.get("evyos-ip-ext"):
agent = headers_request.get("evyos-user-agent", "") agent = headers_request.get("evyos-user-agent", "")
platform = headers_request.get("evyos-platform", "") platform = headers_request.get("evyos-platform", "")
@@ -258,7 +268,7 @@ class UserLoginModule(AuthModule):
no_address_validates = mongo_db.mongo_engine.get_all()[0] == 0 no_address_validates = mongo_db.mongo_engine.get_all()[0] == 0
record_id = uuid.uuid4().__str__() record_id = uuid.uuid4().__str__()
notice_link = ApiStatic.blacklist_login(record_id=record_id) notice_link = ApiStatic.blacklist_login(record_id=record_id)
found_people = People.find_one(id=found_user.person_id) found_people = People.filter_one(People.id == found_user.person_id).data
access_via_user = query_engine.update_access_history_via_user( access_via_user = query_engine.update_access_history_via_user(
AccessHistoryViaUser( AccessHistoryViaUser(
**{ **{

View File

@@ -70,7 +70,7 @@ class SelectAction:
.select_from(cls) .select_from(cls)
.join(cls.__many__table__, cls.__many__table__.member_id == cls.id) .join(cls.__many__table__, cls.__many__table__.member_id == cls.id)
.filter( .filter(
cls.__many__table__.duties_id.in_(duty_id_list) cls.__many__table__.duties_id.in_(duty_id_list),
*SelectorsBase.add_confirmed_filter( *SelectorsBase.add_confirmed_filter(
first_table=cls, second_table=cls.__many__table__ first_table=cls, second_table=cls.__many__table__
), ),

View File

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

View File

@@ -40,8 +40,8 @@ class MongoQuery:
def __init__(self, table_name: str, database_name: str): def __init__(self, table_name: str, database_name: str):
database = MongoClient(MongoConfig.url)[database_name] database = MongoClient(MongoConfig.url)[database_name]
if table_name not in database.collection_names(): # if table_name not in database.collection_names():
database.create_collection(name=table_name) # database.create_collection(name=table_name)
self.table: Collection = database[table_name] self.table: Collection = database[table_name]
@staticmethod @staticmethod

View File

@@ -10,7 +10,6 @@ from sqlalchemy import (
Boolean, Boolean,
TIMESTAMP, TIMESTAMP,
Numeric, Numeric,
Identity,
UUID, UUID,
) )
@@ -23,12 +22,10 @@ class AccountBooks(CrudCollection):
country: Mapped[str] = mapped_column(String, nullable=False) country: Mapped[str] = mapped_column(String, nullable=False)
branch_type: Mapped[str] = mapped_column(SmallInteger, server_default="0") branch_type: Mapped[str] = mapped_column(SmallInteger, server_default="0")
company_id: Mapped[Identity] = mapped_column( company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=False)
ForeignKey("companies.id"), nullable=False company_uu_id: Mapped[str] = mapped_column(String, nullable=False)
) branch_id: Mapped[int] = mapped_column(ForeignKey("companies.id"))
company_uu_id: Mapped[UUID] = mapped_column(String, nullable=False) branch_uu_id: Mapped[str] = mapped_column(String, comment="Branch UU ID")
branch_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id"))
branch_uu_id: Mapped[UUID] = mapped_column(String, comment="Branch UU ID")
# company: Mapped["Companies"] = relationship( # company: Mapped["Companies"] = relationship(
# "Company", back_populates="company_account_books", foreign_keys=[company_id] # "Company", back_populates="company_account_books", foreign_keys=[company_id]
@@ -48,9 +45,7 @@ class AccountBooks(CrudCollection):
# ) # )
__table_args__ = ( __table_args__ = (
Index( Index("account_companies_book_ndx_00", company_id, "expiry_starts"),
"account_companies_book_ndx_00", company_id, CrudCollection.expiry_starts
),
{"comment": "Account Book Information"}, {"comment": "Account Book Information"},
) )
@@ -68,7 +63,7 @@ class AccountCodes(CrudCollection):
) )
is_receive_or_debit: Mapped[bool] = mapped_column(Boolean) is_receive_or_debit: Mapped[bool] = mapped_column(Boolean)
product_id: Mapped[Identity] = mapped_column(Integer, server_default="0") product_id: Mapped[int] = mapped_column(Integer, server_default="0")
nvi_id: Mapped[str] = mapped_column(String(48), server_default="") nvi_id: Mapped[str] = mapped_column(String(48), server_default="")
status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0")
account_code_seperator: Mapped[str] = mapped_column(String(1), server_default=".") account_code_seperator: Mapped[str] = mapped_column(String(1), server_default=".")
@@ -76,16 +71,16 @@ class AccountCodes(CrudCollection):
system_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") system_id: Mapped[int] = mapped_column(SmallInteger, server_default="0")
locked: Mapped[bool] = mapped_column(SmallInteger, server_default="0") locked: Mapped[bool] = mapped_column(SmallInteger, server_default="0")
company_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id")) company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"))
company_uu_id: Mapped[UUID] = mapped_column( company_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Company UU ID" String, nullable=False, comment="Company UU ID"
) )
customer_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id")) customer_id: Mapped[int] = mapped_column(ForeignKey("companies.id"))
customer_uu_id: Mapped[UUID] = mapped_column( customer_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Customer UU ID" String, nullable=False, comment="Customer UU ID"
) )
person_id: Mapped[Identity] = mapped_column(ForeignKey("people.id")) person_id: Mapped[int] = mapped_column(ForeignKey("people.id"))
person_uu_id: Mapped[UUID] = mapped_column( person_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Person UU ID" String, nullable=False, comment="Person UU ID"
) )
@@ -123,10 +118,10 @@ class AccountCodeParser(CrudCollection):
account_code_5: Mapped[str] = mapped_column(String, server_default="") account_code_5: Mapped[str] = mapped_column(String, server_default="")
account_code_6: Mapped[str] = mapped_column(String, server_default="") account_code_6: Mapped[str] = mapped_column(String, server_default="")
account_code_id: Mapped[Identity] = mapped_column( account_code_id: Mapped[int] = mapped_column(
ForeignKey("account_codes.id"), nullable=False ForeignKey("account_codes.id"), nullable=False
) )
account_code_uu_id: Mapped[UUID] = mapped_column( account_code_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Account Code UU ID" String, nullable=False, comment="Account Code UU ID"
) )
@@ -161,7 +156,7 @@ class AccountMaster(CrudCollection):
__exclude__fields__ = [] __exclude__fields__ = []
doc_date: Mapped[TIMESTAMP] = mapped_column( doc_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP, nullable=False, comment="Document Date" TIMESTAMP(timezone=True), nullable=False, comment="Document Date"
) )
plug_type: Mapped[str] = mapped_column(String, nullable=False, comment="Plug Type") plug_type: Mapped[str] = mapped_column(String, nullable=False, comment="Plug Type")
plug_number: Mapped[int] = mapped_column( plug_number: Mapped[int] = mapped_column(
@@ -201,20 +196,20 @@ class AccountMaster(CrudCollection):
data_center_id: Mapped[str] = mapped_column(String, server_default="") data_center_id: Mapped[str] = mapped_column(String, server_default="")
data_center_rec_num: Mapped[int] = mapped_column(Integer, server_default="0") data_center_rec_num: Mapped[int] = mapped_column(Integer, server_default="0")
account_header_id: Mapped[Identity] = mapped_column( account_header_id: Mapped[int] = mapped_column(
ForeignKey("account_books.id"), nullable=False ForeignKey("account_books.id"), nullable=False
) )
account_header_uu_id: Mapped[UUID] = mapped_column( account_header_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Account Header UU ID" String, nullable=False, comment="Account Header UU ID"
) )
project_item_id: Mapped[Identity] = mapped_column( project_item_id: Mapped[int] = mapped_column(
ForeignKey("build_decision_book_projects.id") ForeignKey("build_decision_book_projects.id")
) )
project_item_uu_id: Mapped[UUID] = mapped_column( project_item_uu_id: Mapped[str] = mapped_column(
String, comment="Project Item UU ID" String, comment="Project Item UU ID"
) )
department_id: Mapped[Identity] = mapped_column(ForeignKey("departments.id")) department_id: Mapped[int] = mapped_column(ForeignKey("departments.id"))
department_uu_id: Mapped[UUID] = mapped_column(String, comment="Department UU ID") department_uu_id: Mapped[str] = mapped_column(String, comment="Department UU ID")
# account_header: Mapped["AccountBooks"] = relationship( # account_header: Mapped["AccountBooks"] = relationship(
# "AccountBooks", # "AccountBooks",
@@ -248,7 +243,7 @@ class AccountDetail(CrudCollection):
__enum_list__ = [("plug_type", "AccountingReceiptTypes", "M")] __enum_list__ = [("plug_type", "AccountingReceiptTypes", "M")]
doc_date: Mapped[TIMESTAMP] = mapped_column( doc_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP, nullable=False, comment="Document Date" TIMESTAMP(timezone=True), nullable=False, comment="Document Date"
) )
line_no: Mapped[int] = mapped_column( line_no: Mapped[int] = mapped_column(
SmallInteger, nullable=False, comment="Line Number" SmallInteger, nullable=False, comment="Line Number"
@@ -292,32 +287,32 @@ class AccountDetail(CrudCollection):
data_center_rec_num: Mapped[str] = mapped_column(Integer, server_default="0") data_center_rec_num: Mapped[str] = mapped_column(Integer, server_default="0")
status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0")
plug_type_id: Mapped[Identity] = mapped_column( plug_type_id: Mapped[int] = mapped_column(
ForeignKey("api_enum_dropdown.id"), nullable=True ForeignKey("api_enum_dropdown.id"), nullable=True
) )
plug_type_uu_id = mapped_column(String, nullable=False, comment="Plug Type UU ID") plug_type_uu_id = mapped_column(String, nullable=False, comment="Plug Type UU ID")
account_header_id: Mapped[Identity] = mapped_column( account_header_id: Mapped[int] = mapped_column(
ForeignKey("account_books.id"), nullable=False ForeignKey("account_books.id"), nullable=False
) )
account_header_uu_id: Mapped[UUID] = mapped_column( account_header_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Account Header UU ID" String, nullable=False, comment="Account Header UU ID"
) )
account_code_id: Mapped[Identity] = mapped_column( account_code_id: Mapped[int] = mapped_column(
ForeignKey("account_codes.id"), nullable=False ForeignKey("account_codes.id"), nullable=False
) )
account_code_uu_id: Mapped[UUID] = mapped_column( account_code_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Account Code UU ID" String, nullable=False, comment="Account Code UU ID"
) )
account_master_id: Mapped[Identity] = mapped_column( account_master_id: Mapped[int] = mapped_column(
ForeignKey("account_master.id"), nullable=False ForeignKey("account_master.id"), nullable=False
) )
account_master_uu_id: Mapped[UUID] = mapped_column( account_master_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Account Master UU ID" String, nullable=False, comment="Account Master UU ID"
) )
project_id: Mapped[Identity] = mapped_column( project_id: Mapped[int] = mapped_column(
ForeignKey("build_decision_book_projects.id") ForeignKey("build_decision_book_projects.id")
) )
project_uu_id: Mapped[UUID] = mapped_column(String, comment="Project UU ID") project_uu_id: Mapped[str] = mapped_column(String, comment="Project UU ID")
# account_header: Mapped["AccountBooks"] = relationship( # account_header: Mapped["AccountBooks"] = relationship(
# "AccountBooks", # "AccountBooks",
@@ -373,6 +368,11 @@ class AccountDetail(CrudCollection):
class AccountRecords(CrudCollection): class AccountRecords(CrudCollection):
"""
build_decision_book_id = kaydın sorumlu olduğu karar defteri
send_company_id = kaydı gönderen firma, send_person_id = gönderen kişi
customer_id = sorumlu kullanıcı bilgisi, company_id = sorumlu firma
"""
__tablename__ = "account_records" __tablename__ = "account_records"
__exclude__fields__ = [] __exclude__fields__ = []
@@ -380,17 +380,12 @@ class AccountRecords(CrudCollection):
("receive_debit", "DebitTypes", "D"), ("receive_debit", "DebitTypes", "D"),
("budget_type", "BudgetType", "B"), ("budget_type", "BudgetType", "B"),
] ]
"""
build_decision_book_id = kaydın sorumlu olduğu karar defteri
send_company_id = kaydı gönderen firma, send_person_id = gönderen kişi
customer_id = sorumlu kullanıcı bilgisi, company_id = sorumlu firma
"""
iban: Mapped[str] = mapped_column( iban: Mapped[str] = mapped_column(
String(64), nullable=False, comment="IBAN Number of Bank" String(64), nullable=False, comment="IBAN Number of Bank"
) )
bank_date: Mapped[TIMESTAMP] = mapped_column( bank_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP, nullable=False, comment="Bank Transaction Date" TIMESTAMP(timezone=True), nullable=False, comment="Bank Transaction Date"
) )
currency_value: Mapped[float] = mapped_column( currency_value: Mapped[float] = mapped_column(
@@ -417,6 +412,9 @@ class AccountRecords(CrudCollection):
process_comment: Mapped[str] = mapped_column( process_comment: Mapped[str] = mapped_column(
String, nullable=False, comment="Transaction Record Comment" String, nullable=False, comment="Transaction Record Comment"
) )
process_garbage: Mapped[str] = mapped_column(
String, nullable=True, comment="Transaction Record Garbage"
)
bank_reference_code: Mapped[str] = mapped_column( bank_reference_code: Mapped[str] = mapped_column(
String, nullable=False, comment="Bank Reference Code" String, nullable=False, comment="Bank Reference Code"
) )
@@ -435,52 +433,75 @@ class AccountRecords(CrudCollection):
approving_accounting_record: Mapped[bool] = mapped_column( approving_accounting_record: Mapped[bool] = mapped_column(
Boolean, server_default="0" Boolean, server_default="0"
) )
accounting_receipt_date = mapped_column( accounting_receipt_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP, server_default="1900-01-01 00:00:00" TIMESTAMP(timezone=True), server_default="1900-01-01 00:00:00"
) )
accounting_receipt_number = mapped_column(Integer, server_default="0") accounting_receipt_number: Mapped[int] = mapped_column(Integer, server_default="0")
status_id = mapped_column(SmallInteger, server_default="0") status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0")
approved_record: Mapped[bool] = mapped_column(Boolean, server_default="0") approved_record: Mapped[bool] = mapped_column(Boolean, server_default="0")
import_file_name = mapped_column(String, nullable=True, comment="XLS Key") import_file_name: Mapped[str] = mapped_column(
String, nullable=True, comment="XLS Key"
)
receive_debit: Mapped[Identity] = mapped_column(ForeignKey("api_enum_dropdown.id")) receive_debit: Mapped[int] = mapped_column(
receive_debit_uu_id = mapped_column(String, nullable=True, comment="Debit UU ID")
budget_type: Mapped[Identity] = mapped_column(
ForeignKey("api_enum_dropdown.id"), nullable=True ForeignKey("api_enum_dropdown.id"), nullable=True
) )
budget_type_uu_id = mapped_column( receive_debit_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Debit UU ID"
)
budget_type: Mapped[int] = mapped_column(
ForeignKey("api_enum_dropdown.id"), nullable=True
)
budget_type_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Budget Type UU ID" String, nullable=True, comment="Budget Type UU ID"
) )
company_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id")) company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=True)
company_uu_id = mapped_column(String, nullable=True, comment="Company UU ID") company_uu_id: Mapped[str] = mapped_column(
send_company_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id")) String, nullable=True, comment="Company UU ID"
)
send_company_id: Mapped[int] = mapped_column(
ForeignKey("companies.id"), nullable=True
)
send_company_uu_id = mapped_column( send_company_uu_id = mapped_column(
String, nullable=True, comment="Send Company UU ID" String, nullable=True, comment="Send Company UU ID"
) )
customer_id: Mapped[Identity] = mapped_column(ForeignKey("people.id")) send_person_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=True)
customer_uu_id = mapped_column(String, nullable=True, comment="Customer UU ID") send_person_uu_id: Mapped[str] = mapped_column(
send_person_id: Mapped[Identity] = mapped_column(ForeignKey("people.id"))
send_person_uu_id = mapped_column(
String, nullable=True, comment="Send Person UU ID" String, nullable=True, comment="Send Person UU ID"
) )
approving_accounting_person: Mapped[Identity] = mapped_column( approving_accounting_person: Mapped[int] = mapped_column(
ForeignKey("people.id") ForeignKey("people.id"), nullable=True
) )
approving_accounting_person_uu_id = mapped_column( approving_accounting_person_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Approving Accounting Person UU ID" String, nullable=True, comment="Approving Accounting Person UU ID"
) )
# build_id: Mapped[Identity] = mapped_column(ForeignKey("build.id"), nullable=True)
build_parts_id: Mapped[Identity] = mapped_column(ForeignKey("build_parts.id")) living_space_id: Mapped[int] = mapped_column(
build_parts_uu_id = mapped_column( ForeignKey("build_living_space.id"), nullable=True
)
living_space_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Living Space UU ID"
)
customer_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=True)
customer_uu_id = mapped_column(String, nullable=True, comment="Customer UU ID")
build_id: Mapped[int] = mapped_column(ForeignKey("build.id"), nullable=True)
build_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Build UU ID"
)
build_parts_id: Mapped[int] = mapped_column(
ForeignKey("build_parts.id"), nullable=True
)
build_parts_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Build Parts UU ID" String, nullable=True, comment="Build Parts UU ID"
) )
build_decision_book_id: Mapped[Identity] = mapped_column( build_decision_book_id: Mapped[int] = mapped_column(
ForeignKey("build_decision_book.id") ForeignKey("build_decision_book.id"), nullable=True
) )
build_decision_book_uu_id = mapped_column( build_decision_book_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Build Decision Book UU ID" String, nullable=True, comment="Build Decision Book UU ID"
) )
@@ -537,7 +558,7 @@ class AccountRecords(CrudCollection):
"comment": "Bank Records that are related to building and financial transactions" "comment": "Bank Records that are related to building and financial transactions"
}, },
) )
#
# def payment_budget_record_close(self): # def payment_budget_record_close(self):
# from database_sql_models import ( # from database_sql_models import (
# DecisionBookProjectPaymentsMaster, # DecisionBookProjectPaymentsMaster,
@@ -643,3 +664,100 @@ class AccountRecords(CrudCollection):
# ) # )
# ) # )
# print("is all dues_type", payment_dict["dues_type"], paid_value) # print("is all dues_type", payment_dict["dues_type"], paid_value)
# class AccountRecordDecisionPaymentClosed(CrudCollection):
#
# __tablename__ = "account_record_decision_payment_closed"
# __exclude__fields__ = []
#
# arc_currency: Mapped[str] = mapped_column(
# String(5), nullable=False, comment="Unit of Currency"
# )
# arc_processing_time: Mapped[TIMESTAMP] = mapped_column(
# TIMESTAMP(timezone=True), nullable=False, comment="Processing Time"
# )
# arc_currency_value: Mapped[float] = mapped_column(
# Numeric(20, 6), nullable=False, comment="Currency Value"
# )
#
# decision_book_budgets_id: Mapped[int] = mapped_column(
# ForeignKey("decision_book_budgets.id"), nullable=True
# )
# decision_book_budgets_uu_id: Mapped[str] = mapped_column(
# String, nullable=True, comment="Budget UUID"
# )
#
# build_decision_book_payment_id: Mapped[int] = mapped_column(
# ForeignKey("build_decision_book_payments.id")
# )
# build_decision_book_payment_uu_id: Mapped[str] = mapped_column(
# String, nullable=True, comment="Build Decision Book Payment UU ID"
# )
# account_records_id: Mapped[int] = mapped_column(ForeignKey("account_records.id"))
# account_records_uu_id: Mapped[str] = mapped_column(
# String, nullable=True, comment="Account Record UU ID"
# )
#
# __table_args__ = (
# Index(
# "_account_record_decision_payment_closed_ndx_00",
# account_records_id,
# build_decision_book_payment_id,
# arc_processing_time,
# ),
# Index(
# "_account_record_decision_payment_closed_ndx_01",
# build_decision_book_payment_id,
# account_records_id,
# arc_processing_time,
# ),
# {"comment": "Account Record Decision Payment Closed Information"},
# )
#
class AccountRecordExchanges(CrudCollection):
__tablename__ = "account_record_exchanges"
__exclude__fields__ = []
are_currency: Mapped[str] = mapped_column(
String(5), nullable=False, comment="Unit of Currency"
)
are_exchange_rate: Mapped[float] = mapped_column(
Numeric(18, 6), nullable=False, server_default="1"
)
usd_exchange_rate_value: Mapped[float] = mapped_column(
Numeric(18, 6),
nullable=True,
server_default="0",
comment="It will be written by multiplying the usd exchange rate with the current value result.",
)
eur_exchange_rate_value: Mapped[float] = mapped_column(
Numeric(18, 6),
nullable=True,
server_default="0",
comment="It will be written by multiplying the eur exchange rate with the current value result.",
)
gbp_exchange_rate_value: Mapped[float] = mapped_column(
Numeric(18, 6),
nullable=True,
server_default="0",
comment="It will be written by multiplying the gpd exchange rate with the current value result.",
)
cny_exchange_rate_value: Mapped[float] = mapped_column(
Numeric(18, 6),
nullable=True,
server_default="0",
comment="It will be written by multiplying the cny exchange rate with the current value result.",
)
account_records_id: Mapped[int] = mapped_column(ForeignKey("account_records.id"))
account_records_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Account Record UU ID"
)
__table_args__ = (
Index("_account_record_exchanges_ndx_00", account_records_id),
{"comment": "Account Record Exchanges Information"},
)

View File

@@ -16,20 +16,20 @@ class BuildIbans(CrudCollection):
String(40), server_default="", nullable=False, comment="IBAN number" String(40), server_default="", nullable=False, comment="IBAN number"
) )
start_date: Mapped[TIMESTAMP] = mapped_column( start_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP, nullable=False, comment="Bank Transaction Start Date" TIMESTAMP(timezone=True), nullable=False, comment="Bank Transaction Start Date"
) )
stop_date: Mapped[TIMESTAMP] = mapped_column( stop_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP, server_default="2900-01-01 00:00:00" TIMESTAMP(timezone=True), server_default="2900-01-01 00:00:00"
) )
bank_code: Mapped[str] = mapped_column(String(24), server_default="TR0000000000000") bank_code: Mapped[str] = mapped_column(String(24), server_default="TR0000000000000")
xcomment: Mapped[str] = mapped_column(String(64), server_default="????") xcomment: Mapped[str] = mapped_column(String(64), server_default="????")
build_id: Mapped[Identity] = mapped_column( build_id: Mapped[int] = mapped_column(
ForeignKey("build.id"), nullable=False, comment="Building ID" ForeignKey("build.id"), nullable=True, comment="Building ID"
) )
build_uu_id: Mapped[str] = mapped_column( build_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Building UUID", index=True String, nullable=True, comment="Building UUID", index=True
) )
# building: Mapped["Build"] = relationship( # building: Mapped["Build"] = relationship(
# "Build", back_populates="build_ibans", foreign_keys=[build_id] # "Build", back_populates="build_ibans", foreign_keys=[build_id]
@@ -67,23 +67,25 @@ class BuildIbanDescription(CrudCollection):
String, nullable=False, comment="Search Word", index=True String, nullable=False, comment="Search Word", index=True
) )
decision_book_project_id: Mapped[Identity] = mapped_column( # decision_book_project_id: Mapped[int] = mapped_column(
ForeignKey("build_decision_book_projects.id") # ForeignKey("build_decision_book_projects.id")
) # )
decision_book_project_uu_id: Mapped[str] = mapped_column( # decision_book_project_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Decision Book Project UUID" # String, nullable=False, comment="Decision Book Project UUID"
) # )
customer_id: Mapped[Identity] = mapped_column(ForeignKey("people.id")) customer_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=True)
customer_uu_id: Mapped[str] = mapped_column( customer_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Customer UUID" String, nullable=True, comment="Customer UUID"
) )
company_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id")) company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=True)
company_uu_id: Mapped[str] = mapped_column( company_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Company UUID" String, nullable=True, comment="Company UUID"
)
build_parts_id: Mapped[int] = mapped_column(
ForeignKey("build_parts.id"), nullable=True
) )
build_parts_id: Mapped[Identity] = mapped_column(ForeignKey("build_parts.id"))
build_parts_uu_id: Mapped[str] = mapped_column( build_parts_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Build Parts UUID" String, nullable=True, comment="Build Parts UUID"
) )
# decision_book_project: Mapped["BuildDecisionBookProjects"] = relationship( # decision_book_project: Mapped["BuildDecisionBookProjects"] = relationship(

View File

@@ -24,9 +24,9 @@ class CrypterEngine(CrudCollection):
@classmethod @classmethod
def get_valid_keys(cls, row=None): def get_valid_keys(cls, row=None):
cls.encrypt_list, cls.decrypt_list = [], [] cls.encrypt_list, cls.decrypt_list = [], []
if not cls.filter_active( if not cls.filter_all(cls.created_at > datetime.now() - timedelta(days=29)).get(
cls.created_at > datetime.now() - timedelta(days=29) 1
).get(1): ):
cls.create_encrypt_keys(count=100) cls.create_encrypt_keys(count=100)
if decrypt_identifier := getattr(row, "cryp_uu_id", None): if decrypt_identifier := getattr(row, "cryp_uu_id", None):
if decrypt_row := cls.find_one(uu_id=str(decrypt_identifier)): if decrypt_row := cls.find_one(uu_id=str(decrypt_identifier)):
@@ -35,7 +35,7 @@ class CrypterEngine(CrudCollection):
decrypt_row.key_second.decode(), decrypt_row.key_second.decode(),
decrypt_row.uu_id, decrypt_row.uu_id,
) )
if encrypt_rows := cls.filter_active( if encrypt_rows := cls.filter_all(
cls.created_at > datetime.now() - timedelta(days=29) cls.created_at > datetime.now() - timedelta(days=29)
).data: ).data:
encrypt_row = random.choice(encrypt_rows) encrypt_row = random.choice(encrypt_rows)

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