diff --git a/api_events/events/decision_book/project_decision_book.py b/api_events/events/decision_book/project_decision_book.py index f374dd6..e60abb4 100644 --- a/api_events/events/decision_book/project_decision_book.py +++ b/api_events/events/decision_book/project_decision_book.py @@ -1,6 +1,65 @@ +from typing import Union + +from api_library.date_time_actions.date_functions import system_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 + + +class ProjectDecisionBookPersonListEvents(MethodToEvent): + + event_type = "LIST" + + __event_keys__ = { + "96459b36-37f2-4d5b-8370-c459058d5bce": "project_decision_book_person_list", + } + + @classmethod + def project_decision_book_person_list( + cls, + data: 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 book created successfully", + result=decision_book_projects, + ) class ProjectDecisionBookCreateEvents(MethodToEvent): @@ -12,8 +71,51 @@ class ProjectDecisionBookCreateEvents(MethodToEvent): } @classmethod - def project_decision_book_create(cls, request, *args, **kwargs): - pass + 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.living_space_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.get("build_decision_book_uu_id"), + 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 ProjectDecisionBookUpdateEvents(MethodToEvent): @@ -25,8 +127,187 @@ class ProjectDecisionBookUpdateEvents(MethodToEvent): } @classmethod - def project_decision_book_update(cls, request, *args, **kwargs): - pass + 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.living_space_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( + BuildDecisionBookProjects.build_decision_book_project_uu_id == data.get("build_decision_book_project_uu_id"), + BuildDecisionBookProjects.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 ProjectDecisionBookApprovalEvents(MethodToEvent): + + event_type = "UPDATE" + + __event_keys__ = { + "a83a83fe-8446-4c60-9ae5-d1c06adbf626": "project_decision_book_approval", + } + + @classmethod + def project_decision_book_approval( + cls, + data: ApprovalsBuildDecisionBookProjects, + 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.living_space_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( + BuildDecisionBookProjects.build_decision_book_project_uu_id == data.get( + "build_decision_book_project_uu_id"), + BuildDecisionBookProjects.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, + ).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 + data_dict["status_id"] = 1 # is completed status + + 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( + payment_plan_time_periods=str(), + 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: + 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), + period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}", + **book_payment_dict, + ) + created_book_payment.save_and_confirm() + return + + 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 ProjectDecisionBookPatchEvents(MethodToEvent): @@ -38,5 +319,9 @@ class ProjectDecisionBookPatchEvents(MethodToEvent): } @classmethod - def project_decision_book_patch(cls, request, *args, **kwargs): - pass + def project_decision_book_patch( + cls, + data, + token_dict: Union[EmployeeTokenObject, OccupantTokenObject], + ): + return diff --git a/api_events/events/decision_book/project_decision_book_items.py b/api_events/events/decision_book/project_decision_book_items.py new file mode 100644 index 0000000..0a764b6 --- /dev/null +++ b/api_events/events/decision_book/project_decision_book_items.py @@ -0,0 +1,19 @@ +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 + + + diff --git a/api_events/events/decision_book/project_decision_book_person.py b/api_events/events/decision_book/project_decision_book_person.py index 24442bb..0bde9b7 100644 --- a/api_events/events/decision_book/project_decision_book_person.py +++ b/api_events/events/decision_book/project_decision_book_person.py @@ -1,8 +1,57 @@ +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 ProjectDecisionBookPersonListEvents(MethodToEvent): + + event_type = "LIST" + + __event_keys__ = { + "7101b5ca-8bef-40f9-8b4d-646d9994e18f": "project_decision_book_person_list", + } + + @classmethod + def project_decision_book_person_list( + cls, + data: 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 book created successfully", + result=decision_book_projects, + ) + + class ProjectDecisionBookPersonCreateEvents(MethodToEvent): event_type = "CREATE" @@ -12,8 +61,28 @@ class ProjectDecisionBookPersonCreateEvents(MethodToEvent): } @classmethod - def project_decision_book_create(cls, request, *args, **kwargs): - return + 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 ProjectDecisionBookPersonUpdateEvents(MethodToEvent): @@ -25,8 +94,29 @@ class ProjectDecisionBookPersonUpdateEvents(MethodToEvent): } @classmethod - def project_decision_book_update(cls, request, *args, **kwargs): - return + 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 ProjectDecisionBookPersonPatchEvents(MethodToEvent): @@ -38,5 +128,26 @@ class ProjectDecisionBookPersonPatchEvents(MethodToEvent): } @classmethod - def project_decision_book_patch(cls, request, *args, **kwargs): - return + 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, + ) + diff --git a/api_events/tasks2events/occupant_tasks/project_leader.py b/api_events/tasks2events/occupant_tasks/project_leader.py index 1494ddd..c6e5ba0 100644 --- a/api_events/tasks2events/occupant_tasks/project_leader.py +++ b/api_events/tasks2events/occupant_tasks/project_leader.py @@ -7,7 +7,12 @@ class ProjectLeader(AddEventFunctionality): related_code = "PRJ-LDR" events = [ - {"function_code": ""}, + {"function_code": "b8e44bb2-f157-4dd5-8a24-0e02db4877c9"}, + {"function_code": "bfe3ef13-030f-495f-b692-94bcb746d700"}, + {"function_code": "444d67a0-b3a8-4ca2-9d8d-f1acc75011e0"}, + {"function_code": "9c88e314-84e8-435e-8c1e-6a5aae80b2e6"}, + {"function_code": "7fbd18a0-c099-4494-ada1-bb23e39bb141"}, + {"function_code": "a122e84a-5556-4bf7-b680-1f47c438d4f7"}, ] def __new__(cls, *args, **kwargs): diff --git a/api_validations/validations_request/__init__.py b/api_validations/validations_request/__init__.py index 0529d86..5ac6a8c 100644 --- a/api_validations/validations_request/__init__.py +++ b/api_validations/validations_request/__init__.py @@ -103,12 +103,15 @@ from .people import ( ResponsePersonSalesMange, ) from .project_decision_book import ( - InsertBuildDecisionBookProjectItems, - UpdateBuildDecisionBookProjectItems, InsertBuildDecisionBookProjectItemDebits, UpdateBuildDecisionBookProjectItemDebits, InsertBuildDecisionBookProjects, UpdateBuildDecisionBookProjects, + InsertBuildDecisionBookProjectPerson, + UpdateBuildDecisionBookProjectPerson, + InsertBuildDecisionBookProjectItems, + UpdateBuildDecisionBookProjectItems, + ApprovalsBuildDecisionBookProjects, ) from .rules import ( UpdateEndpointAccess, @@ -213,10 +216,13 @@ __all__ = [ "ResponsePersonSalesMange", "InsertBuildDecisionBookProjectItems", "UpdateBuildDecisionBookProjectItems", + "ApprovalsBuildDecisionBookProjects", "InsertBuildDecisionBookProjectItemDebits", "UpdateBuildDecisionBookProjectItemDebits", "InsertBuildDecisionBookProjects", "UpdateBuildDecisionBookProjects", + "InsertBuildDecisionBookProjectPerson", + "UpdateBuildDecisionBookProjectPerson", "UpdateEndpointAccess", "UpdateEndpointAccessList", "InsertEndpointAccess", diff --git a/api_validations/validations_request/core_request_validations.py b/api_validations/validations_request/core_request_validations.py index a983c57..eb28949 100644 --- a/api_validations/validations_request/core_request_validations.py +++ b/api_validations/validations_request/core_request_validations.py @@ -19,6 +19,7 @@ class PydanticBaseModel(BaseModelRegular): deleted: Optional[bool] = None expiry_starts: Optional[str] = None expiry_ends: Optional[str] = None + is_confirmed: Optional[bool] = None class EndpointPydantic(BaseModelRegular): diff --git a/api_validations/validations_request/project_decision_book.py b/api_validations/validations_request/project_decision_book.py index ce852c8..7d480e5 100644 --- a/api_validations/validations_request/project_decision_book.py +++ b/api_validations/validations_request/project_decision_book.py @@ -1,12 +1,48 @@ from typing import Optional +from pydantic import BaseModel from api_validations.core_validations import BaseModelRegular from api_validations.validations_request import ( PydanticBaseModel, - ListOptions, ) -class InsertBuildDecisionBookProjects(PydanticBaseModel): +class InsertBuildDecisionBookProjectItems(BaseModelRegular): + item_header: str + item_comment: str + build_decision_book_project_uu_id: str + attachment_pdf_path: Optional[str] = None + item_objection: Optional[str] = None + + +class UpdateBuildDecisionBookProjectItems(PydanticBaseModel): + item_header: Optional[str] = None + item_comment: Optional[str] = None + attachment_pdf_path: Optional[str] = None + item_estimated_cost: Optional[float] = None + build_decision_book_project_uu_id: Optional[str] = None + + +class InsertBuildDecisionBookProjectPerson(BaseModelRegular): + dues_percent_discount: Optional[int] = None + job_fix_wage: Optional[float] = None + bid_price: Optional[float] = None + decision_price: Optional[float] = None + build_decision_book_project_uu_id: str + living_space_uu_id: str + project_team_type_uu_id: str + + +class UpdateBuildDecisionBookProjectPerson(PydanticBaseModel): + dues_percent_discount: Optional[int] = None + job_fix_wage: Optional[float] = None + bid_price: Optional[float] = None + decision_price: Optional[float] = None + build_decision_book_project_uu_id: Optional[str] = None + living_space_uu_id: Optional[str] = None + project_team_type_uu_id: Optional[str] = None + + +class InsertBuildDecisionBookProjects(BaseModelRegular): build_decision_book_item_uu_id: str project_response_person_uu_id: str project_name: str @@ -21,40 +57,29 @@ class InsertBuildDecisionBookProjects(PydanticBaseModel): contact_agreement_path: Optional[str] = None contact_agreement_date: Optional[str] = None meeting_date: Optional[str] = None + currency: Optional[str] = None bid_price: Optional[float] = None - approved_price: Optional[float] = None - final_price: Optional[float] = None resp_company_uu_id: Optional[str] = None class UpdateBuildDecisionBookProjects(PydanticBaseModel): - resp_company_uu_id: Optional[str] = None - - project_response: Optional[str] = None - project_name: Optional[str] = None - project_type: Optional[str] = None + build_decision_book_project_uu_id: str + is_out_sourced: Optional[bool] = False project_note: Optional[str] = None decision_book_pdf_path: Optional[str] = None + status_id: Optional[int] = None resp_company_fix_wage: Optional[float] = None - is_out_sourced: Optional[bool] = None contact_agreement_path: Optional[str] = None contact_agreement_date: Optional[str] = None - meeting_date: Optional[str] = None - bid_price: Optional[float] = None + contact_uu_id: Optional[str] = None + resp_company_uu_id: Optional[str] = None approved_price: Optional[float] = None - final_price: Optional[float] = None -class InsertBuildDecisionBookProjectItems(PydanticBaseModel): - item_order: int - item_comment: str +class ApprovalsBuildDecisionBookProjects(PydanticBaseModel): build_decision_book_project_uu_id: str - item_objection: Optional[str] = None - - -class UpdateBuildDecisionBookProjectItems(PydanticBaseModel): - item_comment: Optional[str] = None - item_objection: Optional[str] = None + final_price_list: list[dict] # {"date": "2021-01-01", "price": 1000} + project_stop_date: str class InsertBuildDecisionBookProjectItemDebits(PydanticBaseModel): diff --git a/databases/__init__.py b/databases/__init__.py index 2461f4d..75e66e9 100644 --- a/databases/__init__.py +++ b/databases/__init__.py @@ -34,6 +34,7 @@ from databases.sql_models.building.decision_book import ( BuildDecisionBookProjects, BuildDecisionBookProjectPerson, BuildDecisionBookPersonOccupants, + BuildDecisionBookProjectItems, ) from databases.sql_models.company.company import ( Companies, @@ -120,6 +121,7 @@ __all__ = [ "BuildDecisionBookProjects", "BuildDecisionBookProjectPerson", "BuildDecisionBookPersonOccupants", + "BuildDecisionBookProjectItems", "Companies", "RelationshipDutyCompany", "Employees", diff --git a/databases/sql_models/building/decision_book.py b/databases/sql_models/building/decision_book.py index 36a0451..5e9e8fa 100644 --- a/databases/sql_models/building/decision_book.py +++ b/databases/sql_models/building/decision_book.py @@ -1033,17 +1033,15 @@ class BuildDecisionBookProjects(CrudCollection): decision_book_pdf_path: Mapped[str] = mapped_column( String, server_default="", nullable=True ) - + is_completed: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Project is Completed" + ) + status_id: Mapped[int] = mapped_column(SmallInteger, nullable=True) resp_company_fix_wage: Mapped[float] = mapped_column( Numeric(10, 2), server_default="0" ) is_out_sourced: Mapped[bool] = mapped_column(Boolean, server_default="0") - contact_id: Mapped[int] = mapped_column( - ForeignKey("contracts.id"), nullable=True, comment="Contract id" - ) - contact_uu_id: Mapped[str] = mapped_column( - String, nullable=True, comment="Contract UUID" - ) + meeting_date: Mapped[TIMESTAMP] = mapped_column( TIMESTAMP, server_default="1900-01-01 00:00:00", index=True ) @@ -1052,6 +1050,12 @@ class BuildDecisionBookProjects(CrudCollection): approved_price: Mapped[float] = mapped_column(Numeric(16, 4), server_default="0") final_price: Mapped[float] = mapped_column(Numeric(16, 4), server_default="0") + contact_id: Mapped[int] = mapped_column( + ForeignKey("contracts.id"), nullable=True, comment="Contract id" + ) + contact_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Contract UUID" + ) build_decision_book_id: Mapped[int] = mapped_column( ForeignKey("build_decision_book.id"), nullable=False ) @@ -1209,6 +1213,38 @@ class BuildDecisionBookProjectPerson(CrudCollection): ) +class BuildDecisionBookProjectItems(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_decision_book_project_items" + __exclude__fields__ = [] + + item_header: Mapped[str] = mapped_column( + String, nullable=False, comment="Item Header" + ) + item_comment: Mapped[str] = mapped_column( + Text, nullable=False, comment="Item Comment" + ) + attachment_pdf_path: Mapped[str] = mapped_column( + String, server_default="", nullable=True, comment="Attachment PDF Path" + ) + item_estimated_cost: Mapped[float] = mapped_column( + Numeric(16, 2), server_default="0", comment="Estimated Cost" + ) + + build_decision_book_project_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_projects.id"), nullable=False + ) + build_decision_book_project_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Project UUID" + ) + + __table_args__ = ( + {"comment": "Project Items related to decision taken at building meetings"}, + ) + # # class BuildDecisionBookPaymentsMaster(CrudCollection): # """