wag-services-and-backend-la.../ApiLayers/Schemas/building/build.py

807 lines
28 KiB
Python

from datetime import timedelta
from typing import List, Union
from fastapi import HTTPException, status
from sqlalchemy.orm import mapped_column, relationship, Mapped
from sqlalchemy import (
String,
Integer,
Boolean,
ForeignKey,
Index,
TIMESTAMP,
Text,
Numeric,
or_,
)
from ApiLayers.ApiLibrary import system_arrow, SelectActionWithEmployee
from Services.PostgresService.controllers.mixin_controllers import CrudCollection
from ApiLayers.ApiValidations.Request import (
InsertBuild,
InsertBuildParts,
InsertBuildLivingSpace,
UpdateBuild,
)
from ApiLayers.ApiValidations.Custom.token_objects import (
EmployeeTokenObject,
OccupantTokenObject,
)
from ApiLayers.LanguageModels.Database.building.build import (
BuildTypesLanguageModel,
Part2EmployeeLanguageModel,
BuildPartsLanguageModel,
BuildSitesLanguageModel,
RelationshipEmployee2BuildLanguageModel,
BuildLanguageModel,
BuildPartsLanguageModel,
BuildLivingSpaceLanguageModel,
BuildManagementLanguageModel,
BuildAreaLanguageModel,
BuildCompaniesProvidingLanguageModel,
BuildPersonProvidingLanguageModel,
)
class BuildTypes(CrudCollection):
"""
BuildTypes class based on declarative_base and BaseMixin via session
"""
__tablename__ = "build_types"
__exclude__fields__ = []
__language_model__ = BuildTypesLanguageModel
__include__fields__ = []
function_code: Mapped[str] = mapped_column(
String(12), server_default="", nullable=False, comment="Function Code"
)
type_code: Mapped[str] = mapped_column(
String(12), server_default="", nullable=False, comment="Structure Type Code"
)
lang: Mapped[str] = mapped_column(
String(4), server_default="TR", nullable=False, comment="Language"
)
type_name: Mapped[str] = mapped_column(
String(48), server_default="", nullable=False, comment="Type Name"
)
__table_args__ = (
Index("_build_types_ndx_00", type_code, function_code, lang, unique=True),
{"comment": "Function group of building types with their language information"},
)
class Part2Employee(CrudCollection):
"""
Employee2Parts class based on declarative_base and BaseMixin via session
In between start and end date, a part can be assigned to only one employee
"""
__tablename__ = "part2employee"
__exclude__fields__ = []
__language_model__ = Part2EmployeeLanguageModel
__include__fields__ = []
build_id: Mapped[int] = mapped_column(Integer, comment="Building ID")
part_id: Mapped[int] = mapped_column(
ForeignKey("build_parts.id"), nullable=False, comment="Part ID"
)
employee_id: Mapped[int] = mapped_column(
ForeignKey("employees.id"), nullable=False, comment="Employee ID"
)
__table_args__ = (
Index("_part2employee_ndx_00", employee_id, part_id, unique=True),
{"comment": "Employee2Parts Information"},
)
class RelationshipEmployee2Build(CrudCollection):
"""
CompanyRelationship class based on declarative_base and CrudCollection via session
Company -> Sub Company -> Sub-Sub Company
"""
__tablename__ = "relationship_employee2build"
__exclude__fields__ = []
__language_model__ = RelationshipEmployee2BuildLanguageModel
company_id: Mapped[int] = mapped_column(
ForeignKey("companies.id"), nullable=False
) # 1, 2, 3
employee_id: Mapped[int] = mapped_column(
ForeignKey("employees.id"), nullable=False
) # employee -> (n)person Evyos LTD
member_id: Mapped[int] = mapped_column(
ForeignKey("build.id"), nullable=False
) # 2, 3, 4
relationship_type: Mapped[str] = mapped_column(
String, nullable=True, server_default="Employee"
) # Commercial
show_only: Mapped[bool] = mapped_column(Boolean, server_default="False")
__table_args__ = (
Index(
"relationship_build_employee_ndx_00",
company_id,
employee_id,
member_id,
relationship_type,
unique=True,
),
{"comment": "Build & Employee Relationship Information"},
)
class Build(CrudCollection, SelectActionWithEmployee):
"""
Builds class based on declarative_base and BaseMixin via session
"""
__tablename__ = "build"
__exclude__fields__ = []
__language_model__ = BuildLanguageModel
__include__fields__ = []
__access_by__ = []
__many__table__ = RelationshipEmployee2Build
# __explain__ = AbstractBuild()
gov_address_code: Mapped[str] = mapped_column(
String, server_default="", unique=True
)
build_name: Mapped[str] = mapped_column(
String, nullable=False, comment="Building Name"
)
build_no: Mapped[str] = mapped_column(
String(8), nullable=False, comment="Building Number"
)
max_floor: Mapped[int] = mapped_column(
Integer, server_default="1", nullable=False, comment="Max Floor"
)
underground_floor: Mapped[int] = mapped_column(
Integer, server_default="0", nullable=False, comment="Underground Floor"
)
build_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP(timezone=True), server_default="1900-01-01"
)
decision_period_date: Mapped[TIMESTAMP] = mapped_column(
TIMESTAMP(timezone=True),
server_default="1900-01-01",
comment="Building annual ordinary meeting period",
)
tax_no: Mapped[str] = mapped_column(String(24), server_default="")
lift_count: Mapped[int] = mapped_column(Integer, server_default="0")
heating_system: Mapped[bool] = mapped_column(Boolean, server_default="True")
cooling_system: Mapped[bool] = mapped_column(Boolean, server_default="False")
hot_water_system: Mapped[bool] = mapped_column(Boolean, server_default="False")
block_service_man_count: Mapped[int] = mapped_column(Integer, server_default="0")
security_service_man_count: Mapped[int] = mapped_column(Integer, server_default="0")
garage_count: Mapped[int] = mapped_column(
Integer, server_default="0", comment="Garage Count"
)
management_room_id: Mapped[int] = mapped_column(
Integer, nullable=True, comment="Management Room ID"
)
site_id: Mapped[int] = mapped_column(ForeignKey("build_sites.id"), nullable=True)
site_uu_id: Mapped[str] = mapped_column(String, comment="Site UUID", nullable=True)
address_id: Mapped[int] = mapped_column(ForeignKey("addresses.id"), nullable=False)
address_uu_id: Mapped[str] = mapped_column(
String, comment="Address UUID", nullable=False
)
build_types_id: Mapped[int] = mapped_column(
ForeignKey("build_types.id"), nullable=False, comment="Building Type"
)
build_types_uu_id: Mapped[str] = mapped_column(String, comment="Building Type UUID")
parts: Mapped[List["BuildParts"]] = relationship(
"BuildParts", back_populates="buildings", foreign_keys="BuildParts.build_id"
)
decision_books: Mapped[List["BuildDecisionBook"]] = relationship(
"BuildDecisionBook",
back_populates="buildings",
foreign_keys="BuildDecisionBook.build_id",
)
# build_ibans: Mapped["BuildIbans"] = relationship(
# "BuildIbans", back_populates="building", foreign_keys="BuildIbans.build_id"
# )
# areas: Mapped["BuildArea"] = relationship(
# "BuildArea", back_populates="buildings", foreign_keys="BuildArea.build_id"
# )
# response_companies: Mapped["Companies"] = relationship(
# "Companies",
# back_populates="response_buildings",
# foreign_keys=[response_company_id],
# )
# addresses: Mapped[List["Address"]] = relationship(
# "Address", back_populates="buildings", foreign_keys=[address_id]
# )
# peoples: Mapped["People"] = relationship(
# "People", back_populates="buildings", foreign_keys=[people_id]
# )
# sites: Mapped["BuildSites"] = relationship(
# "BuildSites", back_populates="buildings", foreign_keys=[site_id]
# )
__table_args__ = (
Index("_builds_ndx_00", gov_address_code),
Index("_builds_ndx_01", build_name, build_no),
{
"comment": "Build objects are building that are created for living and store purposes"
},
)
@property
def management_room(self):
if management_room := BuildParts.filter_by_one(
system=True, id=self.management_room_id, build_id=self.id
).data:
return management_room
return None
@classmethod
def create_action(cls, data: InsertBuild, token):
from Schemas import Addresses
data_dict = data.excluded_dump()
data_dict["address_id"] = None
if data.address_uu_id:
official_address = Addresses.filter_one(
Addresses.uu_id == data.address_uu_id,
).data
data_dict["address_id"] = official_address.id
data_dict["build_no"] = str(official_address.build_number)
if not data_dict["address_id"]:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Address is not found in database. Re-enter address record then try again.",
)
build_type = BuildTypes.filter_by_one(
system=True, uu_id=str(data.build_types_uu_id)
).data
data_dict["build_types_id"] = build_type.id
build_created = cls.find_or_create(**data_dict)
created_build_relation = cls.__many__table__.find_or_create(
company_id=token.selected_company.company_id,
employee_id=token.selected_company.employee_id,
member_id=build_created.id,
)
build_created.save()
build_created.update(is_confirmed=True)
build_created.save()
created_build_relation.update(is_confirmed=True)
created_build_relation.save()
return build_created
@classmethod
def update_action(cls, data: UpdateBuild, build_uu_id: str, token):
from Schemas import Addresses
data_dict = data.excluded_dump()
db = Addresses.new_session()
if data.address_uu_id:
official_address = Addresses.filter_one(
Addresses.uu_id == data.address_uu_id, db=db
).first
data_dict["address_id"] = official_address.id if official_address else None
if build_to_update := cls.filter_one(cls.uu_id == build_uu_id, db=db).first:
updated_build = build_to_update.update(**data_dict)
updated_build.save()
return updated_build
@property
def top_flat(self):
max_flat_no = 0
for part in self.parts:
if part.part_no > self.max_floor:
max_flat_no = part.part_no
return max_flat_no
@property
def bottom_flat(self):
min_flat_no = 0
for part in self.parts:
if part.part_no < self.max_floor:
min_flat_no = part.part_no
return min_flat_no
@property
def human_livable_parts(self) -> tuple:
parts = list(part for part in self.parts if part.human_livable)
return parts, len(parts)
@property
def livable_part_count(self):
livable_parts = BuildParts.filter_all(
BuildParts.build_id == self.id,
BuildParts.human_livable == True,
)
if not livable_parts.data:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="There is no livable part in this building.",
)
return livable_parts.count
@property
def part_type_count(self):
building_types = None
for part in self.parts:
building_types = {}
build_type = BuildTypes.filter_by_one(
system=True, id=part.build_part_type_id
).data
if build_type.type_code in building_types:
building_types[build_type.type_code]["list"].append(part.part_no)
else:
building_types[build_type.type_code] = {"list": [part.part_no]}
# for key, val in building_types.items():
# list_parts = val["list"]
# building_types[key] = {
# "list": list_parts,
# "min": min(list_parts),
# "max": max(list_parts),
# "count": len(list_parts),
# }
return building_types
class BuildParts(CrudCollection):
"""
BuildParts class based on declarative_base and BaseMixin via session
Attentions: Part_no is unique for each building and Every building must have a management section.!!! default no 0
"""
__tablename__ = "build_parts"
__exclude__fields__ = []
__language_model__ = BuildPartsLanguageModel
__include__fields__ = []
__enum_list__ = [("part_direction", "Directions", "NN")]
# https://adres.nvi.gov.tr/VatandasIslemleri/AdresSorgu
address_gov_code: Mapped[str] = mapped_column(
String, nullable=False, comment="Goverment Door Code"
)
# part_name: Mapped[str] = mapped_column(String(24), server_default="", nullable=False, comment="Part Name")
part_no: Mapped[int] = mapped_column(
Integer, server_default="0", nullable=False, comment="Part Number"
)
part_level: Mapped[int] = mapped_column(
Integer, server_default="0", comment="Building Part Level"
)
part_code: Mapped[str] = mapped_column(
String, server_default="", nullable=False, comment="Part Code"
)
part_gross_size: Mapped[int] = mapped_column(
Integer, server_default="0", comment="Part Gross Size"
)
part_net_size: Mapped[int] = mapped_column(
Integer, server_default="0", comment="Part Net Size"
)
default_accessory: Mapped[str] = mapped_column(
Text, server_default="0", comment="Default Accessory"
)
human_livable: Mapped[bool] = mapped_column(
Boolean, server_default="1", comment="Human Livable"
)
due_part_key: Mapped[str] = mapped_column(
String, server_default="", nullable=False, comment="Constant Payment Group"
)
build_id: Mapped[int] = mapped_column(
ForeignKey("build.id"), nullable=False, comment="Building ID"
)
build_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Building UUID"
)
part_direction_id: Mapped[int] = mapped_column(
ForeignKey("api_enum_dropdown.id"), nullable=True
)
part_direction_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Part Direction UUID"
)
part_type_id: Mapped[int] = mapped_column(
ForeignKey("build_types.id"), nullable=False, comment="Building Part Type"
)
part_type_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Building Part Type UUID"
)
buildings: Mapped["Build"] = relationship(
"Build", back_populates="parts", foreign_keys=[build_id]
)
__table_args__ = (
Index("build_parts_ndx_01", build_id, part_no, unique=True),
{"comment": "Part objects that are belong to building objects"},
)
@classmethod
def create_action(cls, data: InsertBuildParts, token):
from Schemas import ApiEnumDropdown
data_dict = data.dump()
build_from_duty = Build.select_action(
employee_id=token.selected_company.employee_id,
filter_expr=[Build.uu_id == data.build_uu_id],
)
building = build_from_duty.first()
if not building:
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE,
detail="This Employee can not reach this building or building uu-id not found in database. "
"Check with your supervisor.",
)
if build_types := BuildTypes.filter_one(
BuildTypes.uu_id == data.build_part_type_uu_id,
).data:
part_direction = ApiEnumDropdown.get_by_uuid(
uuid=str(data.part_direction_uu_id)
)
data_dict["part_gross_size"] = data.part_gross_size
data_dict["part_net_size"] = data.part_net_size
data_dict["part_type_id"] = build_types.id
data_dict["part_level"] = data.part_level
data_dict["build_id"] = building.id
data_dict["part_no"] = data.part_no
data_dict["part_code"] = (
f"{build_types.type_code}:{str(data_dict['part_no']).zfill(2)}"
)
data_dict["address_gov_code"] = data.address_gov_code
data_dict["default_accessory"] = data.default_accessory
data_dict["human_livable"] = bool(data.human_livable)
data_dict["build_uu_id"] = str(data.build_uu_id)
data_dict["part_type_id"] = build_types.id
data_dict["part_type_uu_id"] = str(build_types.uu_id)
data_dict["part_direction_id"] = part_direction.id
data_dict["part_direction_uu_id"] = str(part_direction.uu_id)
# data_dict["part_direction"] = str(data.part_direction_uu_id)
if not data_dict["part_gross_size"]:
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE,
detail="Part Gross Size can not be empty.",
)
if not data_dict["part_net_size"]:
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE,
detail="Part Net Size can not be empty.",
)
pt = int(data_dict["part_net_size"])
data_dict["due_part_key"] = str(pt + (5 - (pt % 5))) + "M2"
del data_dict["build_part_type_uu_id"]
return cls.find_or_create(**data_dict)
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail="Build Part can not be created.",
)
@property
def part_name(self):
if build_type := BuildTypes.filter_by_one(
system=True, id=self.part_type_id
).data:
return f"{str(build_type.type_name).upper()} : {str(self.part_no).upper()}"
return f"Undefined:{str(build_type.type_name).upper()}"
class BuildLivingSpace(CrudCollection):
"""
LivingSpace class based on declarative_base and BaseMixin via session
Owner or live person = Occupant of the build part
+ Query OR(owner_person_id == person_id, life_person_id == person_id) AND (now(date))
"""
__tablename__ = "build_living_space"
__exclude__fields__ = []
__language_model__ = BuildLivingSpaceLanguageModel
__include__fields__ = []
fix_value: Mapped[float] = mapped_column(
Numeric(20, 6),
server_default="0",
comment="Fixed value is deducted from debit.",
)
fix_percent: Mapped[float] = mapped_column(
Numeric(6, 2),
server_default="0",
comment="Fixed percent is deducted from debit.",
)
agreement_no: Mapped[str] = mapped_column(
String, server_default="", comment="Agreement No"
)
marketing_process: Mapped[bool] = mapped_column(Boolean, server_default="False")
marketing_layer: Mapped[int] = mapped_column(Integer, server_default="0")
build_parts_id: Mapped[int] = mapped_column(
ForeignKey("build_parts.id"),
nullable=False,
index=True,
comment="Build Part ID",
)
build_parts_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Build Part UUID"
)
person_id: Mapped[int] = mapped_column(
ForeignKey("people.id"),
nullable=False,
index=True,
comment="Responsible People ID",
)
person_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Responsible People UUID"
)
occupant_type: Mapped[int] = mapped_column(
ForeignKey("occupant_types.id"),
nullable=False,
comment="Occupant Type",
)
occupant_type_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Occupant Type UUID"
)
__table_args__ = (
{"comment": "Living Space inside building parts that are related to people"},
)
@classmethod
def create_action(
cls,
data: dict,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
from Schemas import Services, OccupantTypes
from api_events.events.events.events_bind_modules import (
ModulesBindOccupantEventMethods,
)
if data.get("expiry_starts"):
data["expiry_starts"] = str(system_arrow.get(data["expiry_starts"]))
if data.get("expiry_ends"):
data["expiry_ends"] = str(system_arrow.get(data["expiry_ends"]))
created_living_space = BuildLivingSpace.find_or_create(**data)
occupant_type = OccupantTypes.filter_by_one(
system=True, uu_id=created_living_space.occupant_type_uu_id
).data
related_service = Services.filter_by_one(
related_responsibility=occupant_type.occupant_code,
).data
if not related_service:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail="Service is not found in database. Re-enter service record then try again.",
)
ModulesBindOccupantEventMethods.bind_default_module_for_first_init_occupant(
build_living_space_id=created_living_space.id,
)
created_living_space.save_and_confirm()
return created_living_space
@classmethod
def find_living_from_customer_id(
cls, customer_id, process_date, add_days: int = 32
):
from ApiLibrary.date_time_actions.date_functions import system_arrow
formatted_date = system_arrow.get(str(process_date))
living_spaces = cls.filter_all(
or_(
cls.owner_person_id == customer_id,
cls.life_person_id == customer_id,
),
cls.start_date < formatted_date - timedelta(days=add_days),
cls.stop_date > formatted_date + timedelta(days=add_days),
)
return living_spaces.data, living_spaces.count
class BuildManagement(CrudCollection):
__tablename__ = "build_management"
__exclude__fields__ = []
__language_model__ = BuildManagementLanguageModel
discounted_percentage: Mapped[float] = mapped_column(
Numeric(6, 2), server_default="0.00"
) # %22
discounted_price: Mapped[float] = mapped_column(
Numeric(20, 2), server_default="0.00"
) # Normal: 78.00 TL
calculated_price: Mapped[float] = mapped_column(
Numeric(20, 2), server_default="0.00"
) # sana düz 75.00 TL yapar
occupant_type: Mapped[int] = mapped_column(
ForeignKey("occupant_types.id"),
nullable=False,
comment="Occupant Type",
)
occupant_type_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Occupant Type UUID"
)
build_id: Mapped[int] = mapped_column(
ForeignKey("build.id"), nullable=False, comment="Building ID"
)
build_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Building UUID"
)
build_parts_id: Mapped[int] = mapped_column(
ForeignKey("build_parts.id"),
nullable=False,
index=True,
comment="Build Part ID",
)
build_parts_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Build Part UUID"
)
__table_args__ = (
Index(
"build_management_ndx_00",
build_parts_id,
occupant_type,
"expiry_starts",
unique=True,
),
{"comment": "Management of the building parts that are related to people"},
)
class BuildArea(CrudCollection):
"""
Builds class based on declarative_base and BaseMixin via session
"""
__tablename__ = "build_area"
__exclude__fields__ = []
__language_model__ = BuildAreaLanguageModel
area_name: Mapped[str] = mapped_column(String, server_default="")
area_code: Mapped[str] = mapped_column(String, server_default="")
area_type: Mapped[str] = mapped_column(String, server_default="GREEN")
area_direction: Mapped[str] = mapped_column(String(2), server_default="NN")
area_gross_size: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0")
area_net_size: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0")
width = mapped_column(Integer, server_default="0")
size = mapped_column(Integer, server_default="0")
build_id: Mapped[int] = mapped_column(ForeignKey("build.id"))
build_uu_id: Mapped[str] = mapped_column(String, comment="Building UUID")
part_type_id: Mapped[int] = mapped_column(
ForeignKey("build_types.id"), nullable=True, comment="Building Part Type"
)
part_type_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Building Part Type UUID"
)
# buildings: Mapped["Build"] = relationship(
# "Build", back_populates="areas", foreign_keys=[build_id]
# )
_table_args_ = (
Index("_edm_build_parts_area_ndx_00", build_id, area_code, unique=True),
)
class BuildSites(CrudCollection):
"""
Builds class based on declarative_base and BaseMixin via session
"""
__tablename__ = "build_sites"
__exclude__fields__ = []
__language_model__ = BuildSitesLanguageModel
__include__fields__ = []
site_name: Mapped[str] = mapped_column(String(24), nullable=False)
site_no: Mapped[str] = mapped_column(String(8), nullable=False)
address_id: Mapped[int] = mapped_column(ForeignKey("addresses.id"))
address_uu_id: Mapped[str] = mapped_column(String, comment="Address UUID")
# addresses: Mapped["Address"] = relationship(
# "Address", back_populates="site", foreign_keys=[address_id]
# )
# buildings: Mapped["Build"] = relationship(
# "Build", back_populates="sites", foreign_keys="Build.site_id"
# )
__table_args__ = (
Index("_sites_ndx_01", site_no, site_name),
{"comment": "Sites that groups building objets"},
)
class BuildCompaniesProviding(CrudCollection):
""" """
__tablename__ = "build_companies_providing"
__exclude__fields__ = []
__language_model__ = BuildCompaniesProvidingLanguageModel
__include__fields__ = []
build_id = mapped_column(
ForeignKey("build.id"), nullable=False, comment="Building ID"
)
build_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Providing UUID"
)
company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"))
company_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Providing UUID"
)
provide_id: Mapped[int] = mapped_column(
ForeignKey("api_enum_dropdown.id"), nullable=True
)
provide_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Providing UUID"
)
contract_id: Mapped[int] = mapped_column(
Integer, ForeignKey("companies.id"), nullable=True
)
__table_args__ = (
Index(
"_build_companies_providing_ndx_00",
build_id,
company_id,
provide_id,
unique=True,
),
{"comment": "Companies providing services for building"},
)
class BuildPersonProviding(CrudCollection):
""" """
__tablename__ = "build_person_providing"
__exclude__fields__ = []
__language_model__ = BuildPersonProvidingLanguageModel
__include__fields__ = []
build_id = mapped_column(
ForeignKey("build.id"), nullable=False, comment="Building ID"
)
build_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Providing UUID"
)
people_id: Mapped[int] = mapped_column(ForeignKey("people.id"))
people_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="People UUID"
)
provide_id: Mapped[int] = mapped_column(
ForeignKey("api_enum_dropdown.id"), nullable=True
)
provide_uu_id: Mapped[str] = mapped_column(
String, nullable=True, comment="Providing UUID"
)
contract_id: Mapped[int] = mapped_column(
Integer, ForeignKey("companies.id"), nullable=True
)
__table_args__ = (
Index(
"_build_person_providing_ndx_00",
build_id,
people_id,
provide_id,
unique=True,
),
{"comment": "People providing services for building"},
)