database and services updated and tested
This commit is contained in:
0
api_events/events/decision_book/__init__.py
Normal file
0
api_events/events/decision_book/__init__.py
Normal file
229
api_events/events/decision_book/decision_book_decision_book.py
Normal file
229
api_events/events/decision_book/decision_book_decision_book.py
Normal file
@@ -0,0 +1,229 @@
|
||||
import typing
|
||||
|
||||
from fastapi import status, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from databases import (
|
||||
Build,
|
||||
BuildDecisionBook,
|
||||
Companies,
|
||||
OccupantTypes,
|
||||
)
|
||||
|
||||
from api_validations.validations_request import (
|
||||
InsertDecisionBook,
|
||||
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 api_library.date_time_actions.date_functions import system_arrow
|
||||
|
||||
|
||||
class DecisionBookListEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "SELECT"
|
||||
__event_keys__ = {
|
||||
"5c10d6ae-2aee-4243-a7c3-94826d028d13": "building_decision_book_list",
|
||||
}
|
||||
__event_validation__ = {"5c10d6ae-2aee-4243-a7c3-94826d028d13": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_list(
|
||||
cls,
|
||||
list_options: ListOptions,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
records = []
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
build_id_list_query = Build.select_action(
|
||||
employee_id=token_dict.selected_company.employee_id
|
||||
)
|
||||
build_id_list = build_id_list_query.all()
|
||||
if not build_id_list:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||
)
|
||||
BuildDecisionBook.filter_attr = list_options
|
||||
records = BuildDecisionBook.filter_all(
|
||||
BuildDecisionBook.build_id.in_([build.id for build in build_id_list]),
|
||||
)
|
||||
elif isinstance(token_dict, OccupantTokenObject):
|
||||
BuildDecisionBook.filter_attr = list_options
|
||||
records = BuildDecisionBook.filter_all(
|
||||
BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
|
||||
)
|
||||
return AlchemyJsonResponse(
|
||||
completed=True,
|
||||
message="DecisionBook are listed successfully",
|
||||
result=records,
|
||||
)
|
||||
|
||||
|
||||
class DecisionBookCreateEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "CREATE"
|
||||
__event_keys__ = {
|
||||
"0a68cb44-271a-4829-81f6-cd99a5f326b4": "building_decision_book_create",
|
||||
}
|
||||
__event_validation__ = {"0a68cb44-271a-4829-81f6-cd99a5f326b4": InsertDecisionBook}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_create(
|
||||
cls,
|
||||
data: InsertDecisionBook,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
data_dict = data.excluded_dump()
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
Build.pre_query = Build.select_action(
|
||||
employee_id=token_dict.selected_company.employee_id
|
||||
)
|
||||
build = Build.filter_one(
|
||||
Build.uu_id == data.build_uu_id,
|
||||
).data
|
||||
if not build:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Emloyee UUID {token_dict.selected_company.employee_uu_id} has no build with given UUID {data_dict.get('build_uu_id')}",
|
||||
)
|
||||
data_dict["build_id"] = build.id
|
||||
if data.resp_company_uu_id:
|
||||
Companies.pre_query = Companies.select_action(
|
||||
duty_id_list=[
|
||||
token_dict.selected_company.duty_id,
|
||||
token_dict.selected_company.bulk_duties_id,
|
||||
]
|
||||
)
|
||||
company = Companies.filter_one(
|
||||
Companies.uu_id == data.resp_company_uu_id,
|
||||
).data
|
||||
if not company:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Duty UUID {token_dict.selected_company.duty_uu_id} has no company with given UUID {data_dict.get('resp_company_uu_id')}",
|
||||
)
|
||||
data_dict["resp_company_id"] = company.id
|
||||
data_dict["resp_company_uu_id"] = str(company.uu_id)
|
||||
|
||||
decision_period_date = system_arrow.get(build.decision_period_date)
|
||||
data_dict["expiry_starts"] = system_arrow.get(
|
||||
system_arrow.now().date().year,
|
||||
int(decision_period_date.date().month),
|
||||
int(decision_period_date.date().day),
|
||||
)
|
||||
data_dict["expiry_ends"] = str(
|
||||
data_dict["expiry_starts"].shift(years=1, days=-1)
|
||||
)
|
||||
data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
|
||||
build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
|
||||
build_decision_book.save_and_confirm()
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content=dict(
|
||||
message="Decision Book has created",
|
||||
completed=True,
|
||||
data=build_decision_book.get_dict(),
|
||||
),
|
||||
)
|
||||
elif isinstance(token_dict, OccupantTokenObject):
|
||||
occupant_manager = OccupantTypes.filter_by_one(
|
||||
occupant_category_type="BU", occupant_code="BU-MNG"
|
||||
).data
|
||||
if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Only Build Manager can create decision book",
|
||||
)
|
||||
|
||||
occupant_build = Build.filter_one(
|
||||
Build.id == token_dict.selected_occupant.build_id,
|
||||
).data
|
||||
occupant_company = Companies.filter_one(
|
||||
Companies.id == token_dict.selected_occupant.responsible_company_id,
|
||||
).data
|
||||
data_dict["build_id"] = occupant_build.id
|
||||
data_dict["build_uu_id"] = str(occupant_build.uu_id)
|
||||
data_dict["resp_company_id"] = occupant_company.id
|
||||
data_dict["resp_company_uu_id"] = str(occupant_company.uu_id)
|
||||
|
||||
decision_period_date = system_arrow.get(occupant_build.decision_period_date)
|
||||
data_dict["expiry_starts"] = system_arrow.get(
|
||||
system_arrow.now().date().year,
|
||||
int(decision_period_date.date().month),
|
||||
int(decision_period_date.date().day),
|
||||
)
|
||||
data_dict["expiry_ends"] = str(
|
||||
data_dict["expiry_starts"].shift(years=1, days=-1)
|
||||
)
|
||||
data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
|
||||
build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
|
||||
build_decision_book.save()
|
||||
build_decision_book.update(is_confirmed=True)
|
||||
build_decision_book.save()
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content=dict(
|
||||
message="Decision Book has created",
|
||||
completed=True,
|
||||
data=build_decision_book.get_dict(),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class DecisionBookUpdateEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "UPDATE"
|
||||
__event_keys__ = {
|
||||
"6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29": "building_decision_book_update",
|
||||
}
|
||||
__event_validation__ = {"6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_update(cls, data: InsertDecisionBook, token_dict: dict):
|
||||
return
|
||||
|
||||
|
||||
class DecisionBookPatchEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "PATCH"
|
||||
__event_keys__ = {
|
||||
"7b58ed84-9a65-4588-994d-30df8366b050": "building_decision_book_patch",
|
||||
}
|
||||
__event_validation__ = {"7b58ed84-9a65-4588-994d-30df8366b050": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_patch(cls, data: InsertDecisionBook, token_dict: dict):
|
||||
return
|
||||
|
||||
|
||||
class DecisionBookApprovalEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "UPDATE"
|
||||
__event_keys__ = {
|
||||
"fc745142-3437-4ca2-89fa-c5a3e2b5c6c2": "building_decision_book_approval",
|
||||
}
|
||||
__event_validation__ = {"fc745142-3437-4ca2-89fa-c5a3e2b5c6c2": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_approval(cls, data, token_dict):
|
||||
return
|
||||
|
||||
|
||||
DecisionBookListEventMethod = DecisionBookListEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/list")
|
||||
)
|
||||
DecisionBookCreateEventMethod = DecisionBookCreateEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/create")
|
||||
)
|
||||
DecisionBookUpdateEventMethod = DecisionBookUpdateEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/update")
|
||||
)
|
||||
DecisionBookPatchEventMethod = DecisionBookPatchEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/patch")
|
||||
)
|
||||
DecisionBookApprovalEventMethod = DecisionBookApprovalEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/approval")
|
||||
)
|
||||
@@ -0,0 +1,570 @@
|
||||
import typing
|
||||
|
||||
from fastapi import status, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from api_events.events.events.events_bind_services import (
|
||||
ServiceBindOccupantEventMethods,
|
||||
)
|
||||
from databases import (
|
||||
Build,
|
||||
BuildParts,
|
||||
BuildDecisionBook,
|
||||
BuildDecisionBookItems,
|
||||
BuildDecisionBookPerson,
|
||||
BuildDecisionBookPayments,
|
||||
BuildDecisionBookProjects,
|
||||
BuildDecisionBookProjectPerson,
|
||||
ApiEnumDropdown,
|
||||
OccupantTypes,
|
||||
Companies,
|
||||
BuildLivingSpace,
|
||||
)
|
||||
|
||||
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||
from api_validations.core_response import AlchemyJsonResponse
|
||||
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
|
||||
|
||||
from api_validations.validations_request import (
|
||||
InsertBuildDecisionBookItems,
|
||||
ListOptions,
|
||||
ListDecisionBook,
|
||||
)
|
||||
from databases.sql_models.event.event import Services
|
||||
|
||||
|
||||
class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "SELECT"
|
||||
__event_keys__ = {
|
||||
"eb36de59-8268-4d96-80b6-5d01c12bf0b1": "building_decision_book_items_list",
|
||||
}
|
||||
__event_validation__ = {"eb36de59-8268-4d96-80b6-5d01c12bf0b1": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_items_list(
|
||||
cls,
|
||||
data: ListOptions,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
decision_book = BuildDecisionBook.filter_one(
|
||||
BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
|
||||
).data
|
||||
if not decision_book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"No Decision Book is match with given UUID {data.build_decision_book_uu_id}",
|
||||
)
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
Build.pre_query = Build.select_action(
|
||||
employee_id=token_dict.selected_company.employee_id,
|
||||
filter_expr=[
|
||||
Build.uu_id == str(decision_book.uu_id),
|
||||
],
|
||||
)
|
||||
reachable_building = Build.filter_all()
|
||||
if not reachable_building.data:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||
)
|
||||
|
||||
Companies.pre_query = Companies.select_action(
|
||||
duty_id_list=[
|
||||
token_dict.selected_company.duty_id,
|
||||
token_dict.selected_company.bulk_duties_id,
|
||||
],
|
||||
filter_expr=[Companies.id == decision_book.resp_company_id],
|
||||
)
|
||||
reachable_companies = Companies.filter_all()
|
||||
if not reachable_companies.data:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||
)
|
||||
BuildDecisionBookItems.filter_attr = BuildDecisionBookItems.FilterModel(
|
||||
**data.dump()
|
||||
)
|
||||
records = BuildDecisionBookItems.filter_all(
|
||||
BuildDecisionBookItems.build_decision_book_id == decision_book.id
|
||||
)
|
||||
return AlchemyJsonResponse(
|
||||
completed=True,
|
||||
message="DecisionBook are listed successfully",
|
||||
result=records,
|
||||
)
|
||||
# return JSONResponse(
|
||||
# status_code=status.HTTP_200_OK,
|
||||
# content=dict(
|
||||
# total_count=records.count,
|
||||
# count=len(records.data),
|
||||
# message=f"Decision Book Items has found from given Decision Book UUID {data.build_decision_book_uu_id}",
|
||||
# completed=True,
|
||||
# data=[record.get_dict() for record in records.data],
|
||||
# ),
|
||||
# )
|
||||
else:
|
||||
# BuildDecisionBookItems.pre_query = BuildDecisionBookItems.select_action(
|
||||
# occupant_id=token_dict.occupant_list["occupant_id"]
|
||||
# )
|
||||
# BuildDecisionBookItems.filter_attr = list_options
|
||||
# records = BuildDecisionBookItems.filter_all(
|
||||
# )
|
||||
# return return_json_response_from_alchemy(response=records, pagination=list_options)
|
||||
return
|
||||
|
||||
|
||||
class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "CREATE"
|
||||
__event_keys__ = {
|
||||
"dce10509-0da5-46fb-af3c-a81d54d5481c": "building_decision_book_items_create",
|
||||
}
|
||||
__event_validation__ = {
|
||||
"dce10509-0da5-46fb-af3c-a81d54d5481c": InsertBuildDecisionBookItems
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def iterate_over_build_parts(
|
||||
cls,
|
||||
build_parts_list,
|
||||
payment_types,
|
||||
local_date,
|
||||
end_date,
|
||||
unit_price,
|
||||
unit_type,
|
||||
book_payment_dict,
|
||||
unit_price_is_fixed,
|
||||
):
|
||||
start_date, payment_return_dict = local_date, {}
|
||||
for build_part_single in build_parts_list:
|
||||
local_date = start_date
|
||||
while local_date.is_between(start_date, end_date, "[]"):
|
||||
local_date = system_arrow.find_last_day_of_month(local_date)
|
||||
payment_amount = unit_price
|
||||
if not unit_price_is_fixed:
|
||||
unit_amount = int(build_part_single.part_net_size)
|
||||
payment_amount = abs(unit_price * float(unit_amount)) * -1
|
||||
payment_amount = -1 * (
|
||||
abs(payment_amount) + (50 - float(abs(payment_amount)) % 50)
|
||||
)
|
||||
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_types.id,
|
||||
payment_types_uu_id=str(payment_types.uu_id),
|
||||
process_date=str(local_date),
|
||||
process_date_m=int(local_date.month),
|
||||
process_date_y=int(local_date.year),
|
||||
period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}",
|
||||
**book_payment_dict,
|
||||
)
|
||||
created_book_payment.save_and_confirm()
|
||||
local_date = local_date.shift(days=2)
|
||||
part_key = str(build_part_single.due_part_key).upper()
|
||||
if part_key not in payment_return_dict:
|
||||
payment_return_dict[part_key] = payment_amount
|
||||
return payment_return_dict
|
||||
|
||||
@classmethod
|
||||
def create_payment_records_for_each_build_part(
|
||||
cls,
|
||||
data_info_type,
|
||||
build_id,
|
||||
unit_price,
|
||||
unit_type,
|
||||
decision_book,
|
||||
decision_book_item,
|
||||
unit_price_is_fixed,
|
||||
currency,
|
||||
debit_start_date: str = None,
|
||||
debit_end_date: str = None,
|
||||
):
|
||||
build_parts_list = BuildParts.filter_all(
|
||||
BuildParts.human_livable == True,
|
||||
BuildParts.build_id == build_id,
|
||||
)
|
||||
print("data_info_type.key", data_info_type.key)
|
||||
book_payment_dict = dict(
|
||||
payment_plan_time_periods=str(data_info_type.key),
|
||||
build_decision_book_item_id=decision_book_item.id,
|
||||
build_decision_book_item_uu_id=str(decision_book_item.uu_id),
|
||||
currency=currency,
|
||||
)
|
||||
payment_types = ApiEnumDropdown.get_debit_search(search_debit="DT-D")
|
||||
if data_info_type.key == "BDT-D":
|
||||
local_date = system_arrow.get(
|
||||
system_arrow.get(decision_book.expiry_starts).date()
|
||||
)
|
||||
end_date = system_arrow.get(
|
||||
system_arrow.get(decision_book.expiry_ends).date()
|
||||
)
|
||||
payment_return_dict = cls.iterate_over_build_parts(
|
||||
build_parts_list=build_parts_list.data,
|
||||
payment_types=payment_types,
|
||||
local_date=local_date,
|
||||
end_date=end_date,
|
||||
unit_price=unit_price,
|
||||
unit_type=unit_type,
|
||||
unit_price_is_fixed=unit_price_is_fixed,
|
||||
book_payment_dict=book_payment_dict,
|
||||
)
|
||||
return payment_return_dict
|
||||
elif data_info_type.key == "BDT-A":
|
||||
local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
|
||||
end_date = system_arrow.get(system_arrow.get(debit_end_date).date())
|
||||
payment_return_dict = cls.iterate_over_build_parts(
|
||||
build_parts_list=build_parts_list.data,
|
||||
payment_types=payment_types,
|
||||
local_date=local_date,
|
||||
end_date=end_date,
|
||||
unit_price=unit_price,
|
||||
unit_type=unit_type,
|
||||
unit_price_is_fixed=unit_price_is_fixed,
|
||||
book_payment_dict=book_payment_dict,
|
||||
)
|
||||
return payment_return_dict
|
||||
elif data_info_type.key == "BDT-R" or data_info_type.key == "BDT-L":
|
||||
local_date = system_arrow.get(system_arrow.get(debit_start_date).date())
|
||||
end_date = system_arrow.get(system_arrow.get(debit_end_date).date())
|
||||
decision_date = system_arrow.get(decision_book.expiry_starts).date()
|
||||
meeting_date = system_arrow.get(decision_book.meeting_date).date()
|
||||
|
||||
already_book_projects = BuildDecisionBookProjects.filter_all(
|
||||
BuildDecisionBookProjects.build_decision_book_id == decision_book.id,
|
||||
BuildDecisionBookProjects.project_type
|
||||
== f"{decision_book.decision_type}_{data_info_type.key}",
|
||||
system=True,
|
||||
)
|
||||
management_room = BuildParts.filter_one(
|
||||
BuildParts.build_id == build_id, BuildParts.part_no == 0, system=True
|
||||
).data
|
||||
occupant_man = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="MT-VPR", occupant_category_type="MT"
|
||||
).data
|
||||
manager_living_space = BuildLivingSpace.filter_one(
|
||||
BuildLivingSpace.build_parts_id == management_room.id,
|
||||
BuildLivingSpace.occupant_type == occupant_man.id,
|
||||
).data
|
||||
if not manager_living_space:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"{occupant_man.occupant_description} Living Space is not found. Check manager living space and try again",
|
||||
)
|
||||
already_book_project_count = already_book_projects.count + 1
|
||||
book_project_dict = dict(
|
||||
project_no=f"{data_info_type.key}_{decision_date.year}_{already_book_project_count}",
|
||||
project_name=f"{str(meeting_date)}_{decision_book.decision_type} Project {already_book_projects.count + 1}",
|
||||
project_start_date=str(local_date),
|
||||
project_stop_date=str(end_date),
|
||||
project_type=f"{decision_book.decision_type}_{data_info_type.key}",
|
||||
project_note=str(decision_book_item.item_comment),
|
||||
build_decision_book_id=decision_book.id,
|
||||
build_decision_book_uu_id=str(decision_book.uu_id),
|
||||
build_decision_book_item_id=decision_book_item.id,
|
||||
build_decision_book_item_uu_id=str(decision_book_item.uu_id),
|
||||
project_response_living_space_id=manager_living_space.id,
|
||||
project_response_living_space_uu_id=str(manager_living_space.uu_id),
|
||||
)
|
||||
book_project_created = BuildDecisionBookProjects.find_or_create(
|
||||
**book_project_dict
|
||||
)
|
||||
book_project_created.save_and_confirm()
|
||||
print("book_project_created", book_project_created)
|
||||
item_comment_at_database = decision_book_item.item_comment
|
||||
decision_book_item.update(
|
||||
item_comment=f"{book_project_created.project_no}_{book_project_created.project_name} "
|
||||
f"is assigned to {occupant_man.occupant_description} | {item_comment_at_database}"
|
||||
)
|
||||
decision_book_item.save_and_confirm()
|
||||
project_lead = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="PRJ-LDR", occupant_category_type="PRJ"
|
||||
).data
|
||||
build_new_president = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="MT-VPR", occupant_category_type="MT"
|
||||
).data
|
||||
|
||||
new_president = BuildLivingSpace.filter_one(
|
||||
BuildLivingSpace.occupant_type == build_new_president.id,
|
||||
BuildLivingSpace.build_parts_id == management_room.id,
|
||||
).data
|
||||
|
||||
project_leader = BuildLivingSpace.filter_one(
|
||||
BuildLivingSpace.occupant_type == project_lead.id,
|
||||
BuildLivingSpace.build_parts_id == management_room.id,
|
||||
BuildLivingSpace.person_id == new_president.person_id,
|
||||
).data
|
||||
if not project_leader:
|
||||
project_leader = BuildLivingSpace.find_or_create(
|
||||
person_id=new_president.person_id,
|
||||
person_uu_id=str(new_president.person_uu_id),
|
||||
build_parts_id=management_room.id,
|
||||
build_parts_uu_id=str(management_room.uu_id),
|
||||
occupant_type=project_lead.id,
|
||||
occupant_type_uu_id=str(project_lead.uu_id),
|
||||
)
|
||||
project_leader.save_and_confirm()
|
||||
related_service = Services.filter_by_one(
|
||||
system=True,
|
||||
related_responsibility=project_lead.occupant_code,
|
||||
).data
|
||||
ServiceBindOccupantEventMethods.bind_services_occupant_system(
|
||||
service_id=related_service.id,
|
||||
build_living_space_id=project_leader.id,
|
||||
)
|
||||
project_person = BuildDecisionBookProjectPerson.find_or_create(
|
||||
build_decision_book_project_id=book_project_created.id,
|
||||
build_decision_book_project_uu_id=str(book_project_created.uu_id),
|
||||
living_space_id=project_leader.id,
|
||||
living_space_uu_id=str(project_leader.uu_id),
|
||||
)
|
||||
project_person.save_and_confirm()
|
||||
book_project_created.update(
|
||||
project_response_living_space_id=project_leader.id,
|
||||
project_response_living_space_uu_id=str(project_leader.uu_id),
|
||||
)
|
||||
book_project_created.save()
|
||||
return book_project_created
|
||||
elif data_info_type.key == "BDT-S":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="BDT-S is not implemented yet. Check info type and try again",
|
||||
)
|
||||
elif data_info_type.key == "BDT-I":
|
||||
return
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Payment Info Type is not valid. Check payment type and try again",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_items_create(
|
||||
cls,
|
||||
data: InsertBuildDecisionBookItems,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
|
||||
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",
|
||||
)
|
||||
elif isinstance(token_dict, OccupantTokenObject):
|
||||
data_dict = data.dump()
|
||||
occupant_wrt = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="MT-WRT", occupant_category_type="MT"
|
||||
).data
|
||||
|
||||
if token_dict.selected_occupant.occupant_type_id != occupant_wrt.id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Only WRITER can create decision book item. Check your occupant type and try again",
|
||||
)
|
||||
|
||||
decision_book_person = BuildDecisionBookPerson.filter_one(
|
||||
BuildDecisionBookPerson.token == data.token,
|
||||
).data
|
||||
decision_book = BuildDecisionBook.filter_one(
|
||||
BuildDecisionBook.id == decision_book_person.build_decision_book_id,
|
||||
).data
|
||||
|
||||
book_items = BuildDecisionBookItems.filter_all(
|
||||
BuildDecisionBookItems.build_decision_book_id == decision_book.id,
|
||||
system=True,
|
||||
)
|
||||
if int(book_items.count) < 3:
|
||||
BuildDecisionBookItems.check_meeting_is_valid_to_start_add_attendance(
|
||||
decision_book=decision_book,
|
||||
token_dict=token_dict,
|
||||
)
|
||||
|
||||
book_items = BuildDecisionBookItems.filter_all(
|
||||
BuildDecisionBookItems.build_decision_book_id == decision_book.id,
|
||||
system=True,
|
||||
)
|
||||
|
||||
data_dict["item_order"] = int(book_items.count) + 1
|
||||
data_dict["build_decision_book_id"] = decision_book.id
|
||||
data_dict["build_decision_book_uu_id"] = str(decision_book.uu_id)
|
||||
|
||||
data_info_type = ApiEnumDropdown.filter_by_one(
|
||||
system=True,
|
||||
enum_class="BuildDuesTypes",
|
||||
key="BDT-I",
|
||||
).data
|
||||
data_info_types = ApiEnumDropdown.due_type_search()
|
||||
for info_type in data_info_types:
|
||||
if str(info_type.uu_id) == data_dict["info_type_uu_id"]:
|
||||
data_info_type = info_type
|
||||
break
|
||||
|
||||
row_is_debit = str(data_info_type.key).upper() in ["BDT-A", "BDT-D"]
|
||||
row_is_project = str(data_info_type.key).upper() in [
|
||||
"BDT-R",
|
||||
"BDT-L",
|
||||
"BDT-S",
|
||||
]
|
||||
debit_dates_required = (
|
||||
not data_dict["debit_start_date"] or not data_dict["debit_end_date"]
|
||||
)
|
||||
if row_is_project and debit_dates_required:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Debit Start Date and Debit End Date is required for this payment type. "
|
||||
"Check debit start date and debit end date and try again",
|
||||
)
|
||||
|
||||
data_dict["info_type_id"] = data_info_type.id
|
||||
data_dict["info_type_uu_id"] = str(data_info_type.uu_id)
|
||||
unit_price, unit_type = float(data_dict["unit_price"]), str(
|
||||
data_dict["unit_type"]
|
||||
)
|
||||
|
||||
debit_start_date, debit_end_date = (
|
||||
data_dict["debit_start_date"],
|
||||
data_dict["debit_end_date"],
|
||||
)
|
||||
currency = data_dict["currency"]
|
||||
del (
|
||||
data_dict["token"],
|
||||
data_dict["unit_price"],
|
||||
data_dict["unit_type"],
|
||||
data_dict["unit_price_is_fixed"],
|
||||
data_dict["debit_start_date"],
|
||||
data_dict["debit_end_date"],
|
||||
data_dict["currency"],
|
||||
)
|
||||
|
||||
new_decision_book_item = BuildDecisionBookItems.find_or_create(**data_dict)
|
||||
new_decision_book_item.save_and_confirm()
|
||||
print("new_decision_book_item", new_decision_book_item)
|
||||
if created_payment_records_dict := cls.create_payment_records_for_each_build_part(
|
||||
data_info_type=data_info_type,
|
||||
build_id=decision_book.build_id,
|
||||
unit_price=unit_price,
|
||||
unit_type=unit_type.upper(),
|
||||
decision_book=decision_book,
|
||||
decision_book_item=new_decision_book_item,
|
||||
unit_price_is_fixed=data.unit_price_is_fixed,
|
||||
debit_start_date=debit_start_date,
|
||||
debit_end_date=debit_end_date,
|
||||
currency=currency,
|
||||
):
|
||||
if row_is_debit:
|
||||
if data_info_type.key == "BDT-D":
|
||||
item_comment = "Regular Payment Plan : "
|
||||
else:
|
||||
item_comment = "Additional Payment Plan : "
|
||||
for key, value in dict(
|
||||
sorted(
|
||||
created_payment_records_dict.items(),
|
||||
key=lambda x: x[1],
|
||||
reverse=True,
|
||||
)
|
||||
).items():
|
||||
item_comment += f" {key} | {abs(float(value))} {currency}, "
|
||||
item_comment = item_comment[:-2]
|
||||
new_decision_book_item.update(item_comment=item_comment)
|
||||
new_decision_book_item.update(is_payment_created=True)
|
||||
elif row_is_project:
|
||||
project_no = str(created_payment_records_dict.project_no)
|
||||
item_comment = (
|
||||
f"{data.item_comment} | @ Project is created no : {project_no}."
|
||||
)
|
||||
new_decision_book_item.update(item_comment=item_comment)
|
||||
new_decision_book_item.update(is_payment_created=True)
|
||||
new_decision_book_item.save_and_confirm()
|
||||
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content=dict(
|
||||
message=f"Decision Book Item has created for given Decision Book UUID {decision_book.uu_id}",
|
||||
completed=True,
|
||||
data=new_decision_book_item.get_dict(),
|
||||
),
|
||||
)
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_400_BAD_REQUEST,
|
||||
# detail="Decision Book Item is not created. Check info type and info no and try again. Unique constraint index is implemented for info type and info no",
|
||||
# )
|
||||
|
||||
|
||||
class DecisionBookDecisionBookItemsUpdateEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "UPDATE"
|
||||
__event_keys__ = {
|
||||
"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": "building_decision_book_items_update",
|
||||
}
|
||||
__event_validation__ = {"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_items_update(
|
||||
cls,
|
||||
data: InsertBuildDecisionBookItems,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
return
|
||||
|
||||
|
||||
class DecisionBookDecisionBookItemsPatchEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "PATCH"
|
||||
__event_keys__ = {
|
||||
"42328809-b516-477b-82cc-2d6fadf28843": "building_decision_book_items_patch",
|
||||
}
|
||||
__event_validation__ = {"42328809-b516-477b-82cc-2d6fadf28843": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_items_patch(
|
||||
cls,
|
||||
data: InsertBuildDecisionBookItems,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
return
|
||||
|
||||
|
||||
DecisionBookDecisionBookItemsListEventMethod = (
|
||||
DecisionBookDecisionBookItemsListEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/items/list")
|
||||
)
|
||||
)
|
||||
DecisionBookDecisionBookItemsCreateEventMethod = (
|
||||
DecisionBookDecisionBookItemsCreateEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/items/create")
|
||||
)
|
||||
)
|
||||
DecisionBookDecisionBookItemsUpdateEventMethod = (
|
||||
DecisionBookDecisionBookItemsUpdateEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/items/update")
|
||||
)
|
||||
)
|
||||
DecisionBookDecisionBookItemsPatchEventMethod = (
|
||||
DecisionBookDecisionBookItemsPatchEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/items/patch")
|
||||
)
|
||||
)
|
||||
|
||||
# if data.info_no is None:
|
||||
# data_dict["info_no"] = data_dict["item_order"]
|
||||
# elif data.occupant_types_uu_id:
|
||||
# data_dict["info_type"] = None
|
||||
# if occupant_type := OccupantTypes.find_one(
|
||||
# uu_id=data.occupant_types_uu_id
|
||||
# ):
|
||||
# if (
|
||||
# str(data.occupant_types_uu_id)
|
||||
# in OccupantTypes.get_manager_occupant_type()
|
||||
# ):
|
||||
# if BuildDecisionBookItems.find_one(
|
||||
# build_decision_book_id=decision_book.id,
|
||||
# occupant_type=occupant_type.id,
|
||||
# ):
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_400_BAD_REQUEST,
|
||||
# detail="This Occupant Type is already exist for given Decision Book UUID. Check occupant type and try again",
|
||||
# )
|
||||
# data_dict["occupant_type"] = occupant_type.id
|
||||
# data_dict["occupant_type_uu_id"] = str(occupant_type.uu_id)
|
||||
@@ -0,0 +1,105 @@
|
||||
import typing
|
||||
|
||||
from databases import (
|
||||
Build,
|
||||
BuildParts,
|
||||
BuildDecisionBook,
|
||||
BuildDecisionBookItems,
|
||||
BuildDecisionBookPerson,
|
||||
BuildDecisionBookPayments,
|
||||
BuildDecisionBookProjects,
|
||||
BuildDecisionBookProjectPerson,
|
||||
ApiEnumDropdown,
|
||||
OccupantTypes,
|
||||
Companies,
|
||||
BuildLivingSpace,
|
||||
)
|
||||
|
||||
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||
from api_validations.core_response import AlchemyJsonResponse
|
||||
from api_library.date_time_actions.date_functions import system_arrow, client_arrow
|
||||
|
||||
|
||||
class 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,
|
||||
)
|
||||
@@ -0,0 +1,456 @@
|
||||
import typing
|
||||
|
||||
from fastapi import status, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from databases import (
|
||||
BuildDecisionBook,
|
||||
BuildDecisionBookPerson,
|
||||
BuildDecisionBookInvitations,
|
||||
Users,
|
||||
BuildLivingSpace,
|
||||
BuildParts,
|
||||
BuildDecisionBookPersonOccupants,
|
||||
People,
|
||||
OccupantTypes,
|
||||
)
|
||||
|
||||
from api_validations.validations_request import (
|
||||
ListOptions,
|
||||
RemoveDecisionBookPerson,
|
||||
DecisionBookDecisionBookInvitationsAttend,
|
||||
DecisionBookDecisionBookInvitationsUpdate,
|
||||
DecisionBookDecisionBookInvitationsAssign,
|
||||
)
|
||||
|
||||
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 DecisionBookPersonListEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "SELECT"
|
||||
__event_keys__ = {
|
||||
"ea324dc0-3b08-4896-9040-7fa0401a176f": "building_decision_book_person_list",
|
||||
}
|
||||
__event_validation__ = {"ea324dc0-3b08-4896-9040-7fa0401a176f": None}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_person_list(
|
||||
cls,
|
||||
data: ListOptions,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
return
|
||||
|
||||
|
||||
class DecisionBookPersonAddEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "CREATE"
|
||||
__event_keys__ = {
|
||||
"e346f720-880b-4b07-93d6-9ac76fbbaa33": "building_decision_book_person_add",
|
||||
}
|
||||
__event_validation__ = {
|
||||
"e346f720-880b-4b07-93d6-9ac76fbbaa33": DecisionBookDecisionBookInvitationsUpdate
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_person_add(
|
||||
cls,
|
||||
data: DecisionBookDecisionBookInvitationsUpdate,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Employee cannot create decision book invitations",
|
||||
)
|
||||
elif isinstance(token_dict, OccupantTokenObject):
|
||||
decision_book = BuildDecisionBook.filter_one(
|
||||
BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
|
||||
).data
|
||||
if not decision_book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"No Decision Book is match with given UUID {data.build_decision_book_uu_id}",
|
||||
)
|
||||
manager_occupant_type = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="BU-MNG", occupant_category_type="BU"
|
||||
).data
|
||||
if (
|
||||
not manager_occupant_type.uu_id
|
||||
== token_dict.selected_occupant.occupant_type_uu_id
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Only Build Manager can update the invitation",
|
||||
)
|
||||
|
||||
assign_occupant_type = OccupantTypes.filter_by_one(
|
||||
system=True,
|
||||
uu_id=data.occupant_type_uu_id,
|
||||
occupant_category_type="MT",
|
||||
).data
|
||||
if not assign_occupant_type:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
|
||||
)
|
||||
|
||||
manger_book_person = BuildDecisionBookPerson.filter_one(
|
||||
BuildDecisionBookPerson.token == data.token,
|
||||
BuildDecisionBookPerson.build_decision_book_uu_id
|
||||
== data.build_decision_book_uu_id,
|
||||
).data
|
||||
if not manger_book_person:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Manager person not found. Please check token",
|
||||
)
|
||||
book_invite = BuildDecisionBookInvitations.filter_one(
|
||||
BuildDecisionBookInvitations.id == manger_book_person.invite_id,
|
||||
BuildDecisionBookInvitations.build_id
|
||||
== token_dict.selected_occupant.build_id,
|
||||
).data
|
||||
if not book_invite:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Invitation not found. Please check token",
|
||||
)
|
||||
selected_book_person = BuildDecisionBookPerson.filter_one(
|
||||
BuildDecisionBookPerson.invite_id == book_invite.id,
|
||||
BuildDecisionBookPerson.person_uu_id == data.person_uu_id,
|
||||
).data
|
||||
if not selected_book_person:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Selected person is not in the invitation list. Please check {data.person_uu_id}",
|
||||
)
|
||||
selected_book_person.update(
|
||||
occupant_type=assign_occupant_type.id,
|
||||
occupant_type_uu_id=str(assign_occupant_type.uu_id),
|
||||
)
|
||||
BuildDecisionBookPerson.save()
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content={
|
||||
"completed": True,
|
||||
"message": "Invitation is updated",
|
||||
"data": selected_book_person.get_dict(),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class DecisionBookPersonRemoveEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "DELETE"
|
||||
__event_keys__ = {
|
||||
"30588869-04cd-48ea-ad00-0e4f8dd7f735": "building_decision_book_people_remove",
|
||||
}
|
||||
__event_validation__ = {
|
||||
"30588869-04cd-48ea-ad00-0e4f8dd7f735": RemoveDecisionBookPerson
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def building_decision_book_people_remove(
|
||||
cls, data: RemoveDecisionBookPerson, token_dict: EmployeeTokenObject
|
||||
):
|
||||
return
|
||||
|
||||
|
||||
class DecisionBookPersonAttendEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "UPDATE"
|
||||
__event_keys__ = {
|
||||
"bdcba521-0116-441c-ace1-84c5b68c86c7": "decision_book_invitations_attend",
|
||||
}
|
||||
__event_validation__ = {
|
||||
"bdcba521-0116-441c-ace1-84c5b68c86c7": DecisionBookDecisionBookInvitationsAttend
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def decision_book_invitations_attend(
|
||||
cls,
|
||||
data: DecisionBookDecisionBookInvitationsAttend,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Employee cannot create decision book invitations",
|
||||
)
|
||||
|
||||
token_user = Users.filter_one(Users.id == token_dict.user_id).data
|
||||
invitation_person = BuildDecisionBookPerson.filter_one(
|
||||
BuildDecisionBookPerson.token == data.token,
|
||||
).data
|
||||
if not invitation_person:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Invitation for the this specific user is not found. Please check token",
|
||||
)
|
||||
|
||||
# is_token_valid = token_dict.person_id == invitation_person.person_id
|
||||
# if not invitation_person.vicarious_person_id:
|
||||
# if not invitation_person or not is_token_valid:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_404_NOT_FOUND,
|
||||
# detail=f"Invitation for the user {token_user.email} is not valid. Please check token",
|
||||
# )
|
||||
# todo check if vicarious person is valid
|
||||
invitation = BuildDecisionBookInvitations.filter_one(
|
||||
BuildDecisionBookInvitations.id == invitation_person.invite_id,
|
||||
BuildDecisionBookInvitations.build_id
|
||||
== token_dict.selected_occupant.build_id,
|
||||
).data
|
||||
if not invitation:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Invitation not found. Please check invitation uuid : {invitation.uu_id}",
|
||||
)
|
||||
invitation_person.update(
|
||||
is_attending=bool(data.is_attend), vicarious_person_id=None
|
||||
)
|
||||
BuildDecisionBookInvitations.save()
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content={
|
||||
"completed": True,
|
||||
"message": "Attendance is updated. Thank you for your response",
|
||||
"data": {
|
||||
"is_attending": bool(data.is_attend),
|
||||
"user_uuid": str(token_user.uu_id),
|
||||
"invitation_uuid": str(invitation.uu_id),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class DecisionBookPersonAssignOccupantEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "UPDATE"
|
||||
__event_keys__ = {
|
||||
"c0b65098-9c79-4212-b1d0-c7e7836cf141": "decision_book_invitations_assign_occupant",
|
||||
}
|
||||
__event_validation__ = {
|
||||
"c0b65098-9c79-4212-b1d0-c7e7836cf141": DecisionBookDecisionBookInvitationsAssign
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def decision_book_invitations_assign_occupant(
|
||||
cls,
|
||||
data: DecisionBookDecisionBookInvitationsAssign,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Employee cannot create decision book invitations",
|
||||
)
|
||||
|
||||
book_person_manager = BuildDecisionBookPerson.filter_one(
|
||||
BuildDecisionBookPerson.token == data.token,
|
||||
BuildDecisionBookPerson.build_living_space_id
|
||||
== token_dict.selected_occupant.living_space_id,
|
||||
).data
|
||||
manager_occupant_type = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="BU-MNG", occupant_category_type="BU"
|
||||
).data
|
||||
book_person_manager.check_occupant_type(manager_occupant_type)
|
||||
|
||||
# supervisor_occupant_type = OccupantTypes.find_or_abort(occupant_code="BU-SPV", occupant_category_type="BU")
|
||||
# book_person_supervisor.check_occupant_type(supervisor_occupant_type)
|
||||
|
||||
invitation = BuildDecisionBookInvitations.filter_one(
|
||||
BuildDecisionBookInvitations.id == book_person_manager.invite_id,
|
||||
BuildDecisionBookInvitations.build_id
|
||||
== token_dict.selected_occupant.build_id,
|
||||
).data
|
||||
if not invitation:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Invitation not found. Please check token",
|
||||
)
|
||||
|
||||
assign_occupant_type = OccupantTypes.filter_by_one(
|
||||
system=True,
|
||||
uu_id=data.occupant_type_uu_id,
|
||||
).data
|
||||
if not assign_occupant_type:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
|
||||
)
|
||||
|
||||
build_parts_of_token = BuildParts.filter_all(
|
||||
BuildParts.build_id == token_dict.selected_occupant.build_id,
|
||||
).data
|
||||
selected_living_space = BuildLivingSpace.filter_one(
|
||||
BuildLivingSpace.uu_id == data.build_living_space_uu_id,
|
||||
BuildLivingSpace.build_parts_id.in_(
|
||||
[build.id for build in build_parts_of_token]
|
||||
),
|
||||
).data
|
||||
if not selected_living_space:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Person not found. Please check person uuid",
|
||||
)
|
||||
|
||||
book_person_to_assign: BuildDecisionBookPerson = (
|
||||
BuildDecisionBookPerson.filter_one(
|
||||
BuildDecisionBookPerson.build_living_space_id
|
||||
== selected_living_space.id,
|
||||
BuildDecisionBookPerson.invite_id == invitation.id,
|
||||
).data
|
||||
)
|
||||
if not book_person_to_assign:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Person not found in the invitation list. Please check person uuid: {data.build_living_space_uu_id}",
|
||||
)
|
||||
if not book_person_to_assign.is_attending:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Person is declined the invitation. This person is not attending the meeting. "
|
||||
f"Please check person uuid: {data.build_living_space_uu_id}. Invite UUID: {invitation.uu_id}",
|
||||
)
|
||||
|
||||
if assign_occupant_type.occupant_code in ("MT-PRS", "MT-WRT"):
|
||||
occupant_type_unique = OccupantTypes.filter_by_one(
|
||||
system=True,
|
||||
occupant_code=assign_occupant_type.occupant_code,
|
||||
occupant_category_type="MT",
|
||||
).data
|
||||
if assigned_book_person_occupant := BuildDecisionBookPersonOccupants.filter_one(
|
||||
BuildDecisionBookPersonOccupants.invite_id == invitation.id,
|
||||
BuildDecisionBookPersonOccupants.occupant_type_id
|
||||
== occupant_type_unique.id,
|
||||
).data:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Only one person can be assigned to {assign_occupant_type.occupant_code} type"
|
||||
f" {assigned_book_person_occupant.uu_id} is already assigned",
|
||||
)
|
||||
|
||||
if assign_occupant_type.occupant_code == "BU-MNG":
|
||||
person_occupant_manager = BuildDecisionBookPersonOccupants.filter_one(
|
||||
BuildDecisionBookPersonOccupants.invite_id == invitation.id,
|
||||
BuildDecisionBookPersonOccupants.occupant_type_id
|
||||
== manager_occupant_type.id,
|
||||
)
|
||||
person_occupant_manager.query.delete()
|
||||
|
||||
book_person_to_assign.add_occupant_type(
|
||||
occupant_type=assign_occupant_type,
|
||||
build_living_space_id=selected_living_space.id,
|
||||
)
|
||||
BuildDecisionBookPersonOccupants.save()
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content={
|
||||
"completed": True,
|
||||
"message": "Invitation is updated",
|
||||
"data": book_person_to_assign.get_dict(),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
DecisionBookPersonListEventMethod = DecisionBookPersonListEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/people/list")
|
||||
)
|
||||
DecisionBookPersonAddEventMethod = DecisionBookPersonAddEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/people/add")
|
||||
)
|
||||
DecisionBookPersonRemoveEventMethod = DecisionBookPersonRemoveEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/people/remove")
|
||||
)
|
||||
DecisionBookPersonAttendEventMethod = DecisionBookPersonAttendEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/invitations/attend")
|
||||
)
|
||||
DecisionBookPersonAssignOccupantEventMethod = (
|
||||
DecisionBookPersonAssignOccupantEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/invitations/assign")
|
||||
)
|
||||
)
|
||||
|
||||
# Build.pre_query = Build.select_action(
|
||||
# employee_id=token_dict.selected_company.employee_id,
|
||||
# filter_expr=[
|
||||
# Build.id == decision_book.build_id,
|
||||
# ],
|
||||
# )
|
||||
# reachable_building = Build.filter_all()
|
||||
# if not reachable_building.data:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_404_NOT_FOUND,
|
||||
# detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||
# )
|
||||
#
|
||||
# Companies.pre_query = Companies.select_action(
|
||||
# duty_id_list=[
|
||||
# token_dict.selected_company.duty_id,
|
||||
# token_dict.selected_company.bulk_duties_id,
|
||||
# ],
|
||||
# filter_expr=[Companies.id == decision_book.resp_company_id],
|
||||
# )
|
||||
# reachable_companies = Companies.filter_all()
|
||||
# if not reachable_companies.data:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_404_NOT_FOUND,
|
||||
# detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||
# )
|
||||
# person_to_add = People.find_one(uu_id=data.person_uu_id)
|
||||
# if not person_to_add:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_404_NOT_FOUND,
|
||||
# detail=f"No person is match with given UUID {data.person_uu_id}",
|
||||
# )
|
||||
# management_typecode = ApiEnumDropdown.filter_all(
|
||||
# ApiEnumDropdown.uu_id == data.management_typecode_uu_id,
|
||||
# ApiEnumDropdown.enum_class.in_("BuildManagementType", "BuildDuesTypes"),
|
||||
# )
|
||||
# if not management_typecode.data:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_404_NOT_FOUND,
|
||||
# detail=f"No management type is match with given UUID {data.management_typecode_uu_id}",
|
||||
# )
|
||||
# condition_to_met = (
|
||||
# data.management_typecode_uu_id
|
||||
# in ApiEnumDropdown.get_management_type_codes_list()
|
||||
# )
|
||||
# any_type_already = BuildDecisionBookPerson.find_one(
|
||||
# build_decision_book_id=decision_book.id,
|
||||
# management_typecode=data.management_typecode_uu_id,
|
||||
# )
|
||||
# if condition_to_met and any_type_already:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_400_BAD_REQUEST,
|
||||
# detail=f"Management type is already exist in given Decision Book UUID {data.build_decision_book_uu_id}.",
|
||||
# )
|
||||
#
|
||||
# data_dict.pop("build_decision_book_uu_id", None)
|
||||
# data_dict.pop("person_uu_id", None)
|
||||
# data_dict["management_typecode"] = data_dict.pop(
|
||||
# "management_typecode_uu_id", None
|
||||
# )
|
||||
# data_dict["build_decision_book_id"] = decision_book.id
|
||||
# data_dict["person_id"] = person_to_add.id
|
||||
#
|
||||
# created = BuildDecisionBookPerson.find_or_create(**data_dict)
|
||||
# if created.is_found:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_400_BAD_REQUEST,
|
||||
# detail=f"Decision Book Person is already exist in given Decision Book UUID {data.build_decision_book_uu_id}.",
|
||||
# )
|
||||
# return JSONResponse(
|
||||
# status_code=status.HTTP_200_OK,
|
||||
# content=dict(
|
||||
# message=f"Decision Book Person has added for given Decision Book UUID {data.build_decision_book_uu_id}",
|
||||
# completed=True,
|
||||
# data=created.get_dict(),
|
||||
# ),
|
||||
# )
|
||||
282
api_events/events/decision_book/decision_book_invitations.py
Normal file
282
api_events/events/decision_book/decision_book_invitations.py
Normal file
@@ -0,0 +1,282 @@
|
||||
import typing
|
||||
|
||||
from fastapi import status, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from databases import (
|
||||
Build,
|
||||
BuildLivingSpace,
|
||||
BuildParts,
|
||||
BuildDecisionBookInvitations,
|
||||
BuildDecisionBookPerson,
|
||||
BuildDecisionBook,
|
||||
BuildDecisionBookPersonOccupants,
|
||||
OccupantTypes,
|
||||
Users,
|
||||
ApiEnumDropdown,
|
||||
)
|
||||
|
||||
from api_validations.validations_request import (
|
||||
DecisionBookDecisionBookInvitationsUpdate,
|
||||
DecisionBookDecisionBookInvitations,
|
||||
)
|
||||
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||
from api_validations.core_response import AlchemyJsonResponse
|
||||
from api_library.date_time_actions.date_functions import system_arrow
|
||||
|
||||
|
||||
class BuildDecisionBookInvitationsListEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "SELECT"
|
||||
__event_keys__ = {
|
||||
"e2277528-8c9c-4c0c-ae64-3ce80cae664b": "decision_book_invitations_list",
|
||||
}
|
||||
__event_validation__ = {"e2277528-8c9c-4c0c-ae64-3ce80cae664b": None}
|
||||
|
||||
@classmethod
|
||||
def decision_book_invitations_list(
|
||||
cls,
|
||||
data,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
return
|
||||
|
||||
|
||||
class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "CREATE"
|
||||
__event_keys__ = {
|
||||
"d0bfa20c-841d-421c-98e6-d308f938d16a": "decision_book_invitations_create",
|
||||
}
|
||||
__event_validation__ = {
|
||||
"d0bfa20c-841d-421c-98e6-d308f938d16a": DecisionBookDecisionBookInvitations
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def decision_book_invitations_create(
|
||||
cls,
|
||||
data: DecisionBookDecisionBookInvitations,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Employee cannot create decision book invitations",
|
||||
)
|
||||
# Check token posses the occupant type of Build Manager
|
||||
occupant_manager = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_category_type="BU", occupant_code="BU-MNG"
|
||||
).data
|
||||
if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Only Build Manager can create decision book",
|
||||
)
|
||||
|
||||
# Check decision book is valid for this token and building
|
||||
decision_book = BuildDecisionBook.filter_one(
|
||||
BuildDecisionBook.uu_id == data.build_decision_book_uu_id,
|
||||
BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
|
||||
).data
|
||||
if not decision_book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Decision book not found. Please create decision book first",
|
||||
)
|
||||
occupant_building = Build.filter_one(
|
||||
Build.id == token_dict.selected_occupant.build_id
|
||||
).data
|
||||
|
||||
# Check planned decision book date is valid
|
||||
if (
|
||||
not system_arrow.get(data.planned_date).date()
|
||||
>= system_arrow.now().shift(days=1).date()
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Planned date must be greater than today",
|
||||
)
|
||||
|
||||
# Create an invitation for specific invitation type to start invite sending process
|
||||
planned_date_expires = str(
|
||||
system_arrow.get(data.planned_date).shift(days=15).date()
|
||||
)
|
||||
book_invitation = BuildDecisionBookInvitations.find_or_create(
|
||||
build_id=token_dict.selected_occupant.build_id,
|
||||
build_uu_id=token_dict.selected_occupant.build_uuid,
|
||||
decision_book_id=decision_book.id,
|
||||
decision_book_uu_id=str(decision_book.uu_id),
|
||||
invitation_type=str(decision_book.decision_type),
|
||||
living_part_count=occupant_building.livable_part_count,
|
||||
living_part_percentage=0.51,
|
||||
message=data.message,
|
||||
planned_date=str(system_arrow.get(data.planned_date)),
|
||||
planned_date_expires=planned_date_expires,
|
||||
expiry_ends=str(system_arrow.get(data.planned_date).shift(days=15).date()),
|
||||
)
|
||||
book_invitation.save_and_confirm()
|
||||
|
||||
# Get all the parts of the building that is occupant in token
|
||||
build_parts = BuildParts.filter_all(
|
||||
BuildParts.build_id == occupant_building.id,
|
||||
)
|
||||
|
||||
# Get all build living spaces that is found in building with distinct person id
|
||||
occupants = OccupantTypes.filter_all(system=True)
|
||||
BuildLivingSpace.filter_attr = None
|
||||
build_living_spaces_people = (
|
||||
BuildLivingSpace.filter_all(
|
||||
BuildLivingSpace.build_parts_id.in_(
|
||||
[build_part.id for build_part in build_parts.data]
|
||||
),
|
||||
BuildLivingSpace.occupant_type.in_(
|
||||
[occupant.id for occupant in occupants.data]
|
||||
),
|
||||
)
|
||||
.query.distinct(BuildLivingSpace.person_id)
|
||||
.all()
|
||||
)
|
||||
if not build_living_spaces_people:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="No living spaces found for the building",
|
||||
)
|
||||
print(
|
||||
f"Tnvite UUID : {book_invitation.uu_id} Message : {data.message} Planned date : {data.planned_date}"
|
||||
)
|
||||
|
||||
# Send invitation to all the users as attend and update the manager as build manager
|
||||
attendance_occupant_type = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="MT-ATT", occupant_category_type="MT"
|
||||
).data
|
||||
manager_occupant_type = OccupantTypes.filter_by_one(
|
||||
system=True, occupant_code="BU-MNG", occupant_category_type="BU"
|
||||
).data
|
||||
|
||||
build_decision_book_person_dict = dict(
|
||||
build_decision_book_id=decision_book.id,
|
||||
build_decision_book_uu_id=str(decision_book.uu_id),
|
||||
invite_id=book_invitation.id,
|
||||
invite_uu_id=str(book_invitation.uu_id),
|
||||
send_date=str(system_arrow.now().date()),
|
||||
expiry_starts=decision_book.expiry_starts,
|
||||
expiry_ends=decision_book.expiry_ends,
|
||||
)
|
||||
# Check if the invitation is already created at database
|
||||
for build_living_spaces_user in build_living_spaces_people:
|
||||
if invite := BuildDecisionBookPerson.filter_one(
|
||||
BuildDecisionBookPerson.invite_id == book_invitation.id,
|
||||
BuildDecisionBookPerson.build_living_space_id
|
||||
== build_living_spaces_user.id,
|
||||
).data:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Invitation already send to {build_living_spaces_user.email} "
|
||||
f"for invite {invite.uu_id} date : {str(book_invitation.planned_date)}",
|
||||
)
|
||||
|
||||
invitations_person = BuildDecisionBookPerson.find_or_create(
|
||||
**build_decision_book_person_dict,
|
||||
build_living_space_id=build_living_spaces_user.id,
|
||||
build_living_space_uu_id=str(build_living_spaces_user.uu_id),
|
||||
person_id=build_living_spaces_user.person_id,
|
||||
token=Users.generate_token(40),
|
||||
)
|
||||
invitations_person.save_and_confirm()
|
||||
|
||||
invitations_person.add_occupant_type(occupant_type=attendance_occupant_type)
|
||||
if invitations_person:
|
||||
print(f'"{invitations_person.token}",')
|
||||
spaces_user = Users.filter_one(
|
||||
Users.person_id == build_living_spaces_user.person_id,
|
||||
).data
|
||||
# print(
|
||||
# f"Invitation is send : {spaces_user.email} "
|
||||
# f"Token : {invitations_person.token} "
|
||||
# f"Send Date : {str(invitations_person.send_date.date())}"
|
||||
# )
|
||||
|
||||
manager_living_spaces = BuildLivingSpace.filter_all(
|
||||
BuildLivingSpace.person_id == token_dict.person_id,
|
||||
)
|
||||
manager_people = BuildDecisionBookPerson.filter_all(
|
||||
BuildDecisionBookPerson.invite_id == book_invitation.id,
|
||||
BuildDecisionBookPerson.build_living_space_id.in_(
|
||||
[
|
||||
manager_living_space.id
|
||||
for manager_living_space in manager_living_spaces.data
|
||||
]
|
||||
),
|
||||
system=True,
|
||||
)
|
||||
manager_people_occupants = BuildDecisionBookPersonOccupants.filter_all(
|
||||
BuildDecisionBookPersonOccupants.build_decision_book_person_id
|
||||
== manager_people.get(1).id,
|
||||
system=True,
|
||||
)
|
||||
if manager_people_occupants.count:
|
||||
manager_people_occupants.query.delete()
|
||||
BuildDecisionBookPersonOccupants.save()
|
||||
if manager_people.count:
|
||||
manager_people.query.delete()
|
||||
BuildDecisionBookPerson.save()
|
||||
|
||||
if book_person_manager := BuildDecisionBookPerson.find_or_create(
|
||||
**build_decision_book_person_dict,
|
||||
build_living_space_id=token_dict.selected_occupant.living_space_id,
|
||||
build_living_space_uu_id=str(
|
||||
token_dict.selected_occupant.living_space_uu_id
|
||||
),
|
||||
person_id=token_dict.person_id,
|
||||
token=Users.generate_token(40),
|
||||
):
|
||||
book_person_manager.save_and_confirm()
|
||||
book_person_manager.add_occupant_type(occupant_type=manager_occupant_type)
|
||||
print(f"Manager Token : {book_person_manager.token}")
|
||||
BuildDecisionBookPerson.save()
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content={
|
||||
"completed": True,
|
||||
"message": "Invitation are send to people related with building",
|
||||
"data": book_invitation.get_dict(),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class BuildDecisionBookInvitationsUpdateEventMethods(MethodToEvent):
|
||||
|
||||
event_type = "UPDATE"
|
||||
__event_keys__ = {
|
||||
"92413636-53a8-4a05-842c-1485a64e00d1": "decision_book_invitations_attend",
|
||||
}
|
||||
__event_validation__ = {
|
||||
"92413636-53a8-4a05-842c-1485a64e00d1": DecisionBookDecisionBookInvitationsUpdate
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def decision_book_invitations_attend(
|
||||
cls,
|
||||
data: DecisionBookDecisionBookInvitationsUpdate,
|
||||
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||
):
|
||||
return
|
||||
|
||||
|
||||
BuildDecisionBookInvitationsListEventMethod = (
|
||||
BuildDecisionBookInvitationsListEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/invite/list")
|
||||
)
|
||||
)
|
||||
BuildDecisionBookInvitationsCreateEventMethod = (
|
||||
BuildDecisionBookInvitationsCreateEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/invite/create")
|
||||
)
|
||||
)
|
||||
BuildDecisionBookInvitationsUpdateEventMethod = (
|
||||
BuildDecisionBookInvitationsUpdateEventMethods(
|
||||
action=ActionsSchema(endpoint="/build/decision_book/invite/update")
|
||||
)
|
||||
)
|
||||
169
api_events/events/decision_book/decision_book_payment.py
Normal file
169
api_events/events/decision_book/decision_book_payment.py
Normal 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,
|
||||
)
|
||||
372
api_events/events/decision_book/project_decision_book.py
Normal file
372
api_events/events/decision_book/project_decision_book.py
Normal 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")
|
||||
)
|
||||
156
api_events/events/decision_book/project_decision_book_items.py
Normal file
156
api_events/events/decision_book/project_decision_book_items.py
Normal 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")
|
||||
)
|
||||
)
|
||||
189
api_events/events/decision_book/project_decision_book_person.py
Normal file
189
api_events/events/decision_book/project_decision_book_person.py
Normal 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")
|
||||
)
|
||||
Reference in New Issue
Block a user