853 lines
30 KiB
Python
853 lines
30 KiB
Python
import typing
|
||
from operator import or_
|
||
from datetime import datetime, timedelta
|
||
from typing import List
|
||
|
||
from fastapi import HTTPException, status
|
||
|
||
from sqlalchemy.orm import mapped_column, relationship, Mapped
|
||
from sqlalchemy import (
|
||
String,
|
||
Integer,
|
||
ForeignKey,
|
||
Index,
|
||
SmallInteger,
|
||
Boolean,
|
||
TIMESTAMP,
|
||
Text,
|
||
Numeric,
|
||
Identity,
|
||
)
|
||
|
||
from databases.sql_models.core_mixin import CrudCollection
|
||
from databases import ApiEnumDropdown
|
||
|
||
from databases.extensions.selector_classes import SelectActionWithEmployee, Explanation
|
||
from api_validations.validations_request import (
|
||
InsertBuildParts,
|
||
InsertBuild,
|
||
UpdateBuild,
|
||
)
|
||
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||
|
||
|
||
class AbstractBuild:
|
||
"""
|
||
Abstract and explanation of Build class for end-user guide
|
||
"""
|
||
|
||
gov_address_code = Explanation(
|
||
explanation="Devletin resmi adres kodudur.",
|
||
usage="Devletin resmi adres kodu istendiğinde kullanılır.",
|
||
alias="Devlet Adres Kodu",
|
||
example=["1234567890"],
|
||
)
|
||
build_name = Explanation(
|
||
explanation="Bina adıdır.",
|
||
usage="Bina adı istendiğinde kullanılır.",
|
||
alias="Bina Adı",
|
||
example=["X Binası", "Y Binası"],
|
||
)
|
||
build_no = Explanation(
|
||
explanation="Bina numarasıdır.",
|
||
usage="Bina numarası istendiğinde kullanılır.",
|
||
alias="Bina No",
|
||
example=["1234567890"],
|
||
)
|
||
build_types = Explanation(
|
||
explanation="Bina türüdür.",
|
||
usage="Bina türü istendiğinde kullanılır.",
|
||
alias="Bina Türü",
|
||
example=["Ofis", "Konut", "Depo"],
|
||
)
|
||
max_floor = Explanation(
|
||
explanation="Bina kat sayısıdır.",
|
||
usage="Bina kat sayısı istendiğinde kullanılır.",
|
||
alias="Kat Sayısı",
|
||
example=["1", "2", "3"],
|
||
)
|
||
underground_floor = Explanation(
|
||
explanation="Bina bodrum kat sayısıdır.",
|
||
usage="Bina bodrum kat sayısı istendiğinde kullanılır.",
|
||
alias="Bodrum Kat Sayısı",
|
||
example=["1", "2", "3"],
|
||
)
|
||
build_date = Explanation(
|
||
explanation="Bina yapım tarihidir.",
|
||
usage="Bina yapım tarihi istendiğinde kullanılır.",
|
||
alias="Yapım Tarihi",
|
||
example=["2021-01-01"],
|
||
)
|
||
tax_no = Explanation(
|
||
explanation="Bina vergi numarasıdır.",
|
||
usage="Bina vergi numarası istendiğinde kullanılır.",
|
||
alias="Vergi No",
|
||
example=["1234567890"],
|
||
)
|
||
lift_count = Explanation(
|
||
explanation="Bina asansör sayısıdır.",
|
||
usage="Bina asansör sayısı istendiğinde kullanılır.",
|
||
alias="Asansör Sayısı",
|
||
example=["1", "2", "3"],
|
||
)
|
||
heating_system = Explanation(
|
||
explanation="Bina ısıtma sistemi var mı?",
|
||
usage="Bina ısıtma sistemi var mı istendiğinde kullanılır.",
|
||
alias="Isıtma Sistemi",
|
||
example=[True, False],
|
||
)
|
||
cooling_system = Explanation(
|
||
explanation="Bina soğutma sistemi var mı?",
|
||
usage="Bina soğutma sistemi var mı istendiğinde kullanılır.",
|
||
alias="Soğutma Sistemi",
|
||
example=[True, False],
|
||
)
|
||
hot_water_system = Explanation(
|
||
explanation="Bina sıcak su sistemi var mı?",
|
||
usage="Bina sıcak su sistemi var mı istendiğinde kullanılır.",
|
||
alias="Sıcak Su Sistemi",
|
||
example=[True, False],
|
||
)
|
||
|
||
|
||
class BuildTypes(CrudCollection):
|
||
"""
|
||
BuildTypes class based on declarative_base and BaseMixin via session
|
||
|
||
"""
|
||
|
||
__tablename__ = "build_types"
|
||
__exclude__fields__ = []
|
||
__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__ = []
|
||
__include__fields__ = []
|
||
|
||
build_id: Mapped[int] = mapped_column(Integer, comment="Building ID")
|
||
part_id: Mapped[Identity] = mapped_column(
|
||
ForeignKey("build_parts.id"), nullable=False, comment="Part ID"
|
||
)
|
||
employee_id: Mapped[Identity] = 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__ = []
|
||
|
||
company_id: Mapped[Identity] = mapped_column(
|
||
ForeignKey("companies.id"), nullable=False
|
||
) # 1, 2, 3
|
||
employee_id: Mapped[Identity] = mapped_column(
|
||
ForeignKey("employees.id"), nullable=False
|
||
) # employee -> (n)person Evyos LTD
|
||
member_id: Mapped[Identity] = 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__ = []
|
||
__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(
|
||
SmallInteger, server_default="1", nullable=False, comment="Max Floor"
|
||
)
|
||
underground_floor: Mapped[int] = mapped_column(
|
||
SmallInteger, server_default="0", nullable=False, comment="Underground Floor"
|
||
)
|
||
build_date: Mapped[TIMESTAMP] = mapped_column(
|
||
TIMESTAMP, server_default="1900-01-01"
|
||
)
|
||
decision_period_date: Mapped[TIMESTAMP] = mapped_column(
|
||
TIMESTAMP,
|
||
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(SmallInteger, 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(
|
||
SmallInteger, server_default="0"
|
||
)
|
||
security_service_man_count: Mapped[int] = mapped_column(
|
||
SmallInteger, server_default="0"
|
||
)
|
||
garage_count: Mapped[int] = mapped_column(
|
||
SmallInteger, server_default="0", comment="Garage Count"
|
||
)
|
||
management_room_id: Mapped[int] = mapped_column(
|
||
Integer, nullable=True, comment="Management Room ID"
|
||
)
|
||
|
||
site_id: Mapped[Identity] = mapped_column(ForeignKey("build_sites.id"))
|
||
site_uu_id: Mapped[str] = mapped_column(String, comment="Site UUID")
|
||
address_id: Mapped[Identity] = mapped_column(ForeignKey("addresses.id"))
|
||
address_uu_id: Mapped[str] = mapped_column(String, comment="Address UUID")
|
||
build_types_id = 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.find_one(
|
||
id=self.management_room_id, build_id=self.id, active=True, is_confirmed=True
|
||
):
|
||
return management_room
|
||
return None
|
||
|
||
@classmethod
|
||
def create_action(cls, data: InsertBuild, token):
|
||
from databases import Addresses
|
||
|
||
data_dict = data.excluded_dump()
|
||
data_dict["address_id"] = None
|
||
if data.address_uu_id:
|
||
official_address = Addresses.find_one(uu_id=data.address_uu_id)
|
||
data_dict["address_id"] = official_address.id
|
||
data_dict["build_no"] = str(official_address.build_number)
|
||
del data_dict["address_uu_id"]
|
||
if not data_dict["address_id"]:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||
detail="Address is not found in database. Re-enter address record then try again.",
|
||
)
|
||
build_type = BuildTypes.find_one(uu_id=str(data.build_types_uu_id))
|
||
data_dict["build_types_id"] = build_type.id
|
||
del data_dict["build_types_uu_id"]
|
||
build_created = cls.find_or_create(**data_dict)
|
||
if not build_created.is_found:
|
||
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,
|
||
is_confirmed=True,
|
||
)
|
||
return build_created
|
||
|
||
@classmethod
|
||
def update_action(cls, data: UpdateBuild, build_uu_id: str, token):
|
||
from databases import Addresses
|
||
|
||
data_dict = data.excluded_dump()
|
||
if data.official_address_uu_id:
|
||
official_address = Addresses.find_one(uu_id=data.address_uu_id)
|
||
data_dict["address_id"] = official_address.id
|
||
del data_dict["address_uu_id"]
|
||
if build_to_update := cls.find_one(uu_id=build_uu_id, person_id=token.id):
|
||
return build_to_update.update(**data_dict)
|
||
|
||
@property
|
||
def top_flat(self):
|
||
max_flat_no = 0
|
||
for part in self.parts:
|
||
if part.part_no > self.max_flat_no:
|
||
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_flat_no:
|
||
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_active(
|
||
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.find_one(id=part.build_part_type_id)
|
||
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__ = []
|
||
__include__fields__ = []
|
||
__enum_list__ = [("part_direction", "Directions", "NN")]
|
||
|
||
# https://adres.nvi.gov.tr/VatandasIslemleri/AdresSorgu
|
||
address_gov_code = 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_column(
|
||
SmallInteger, server_default="0", nullable=False, comment="Part Number"
|
||
)
|
||
part_level = mapped_column(
|
||
SmallInteger, server_default="0", comment="Building Part Level"
|
||
)
|
||
part_code = mapped_column(
|
||
String, server_default="", nullable=False, comment="Part Code"
|
||
)
|
||
part_gross_size = mapped_column(
|
||
Integer, server_default="0", comment="Part Gross Size"
|
||
)
|
||
part_net_size = mapped_column(Integer, server_default="0", comment="Part Net Size")
|
||
default_accessory = 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_column(
|
||
String, server_default="", nullable=False, comment="Constant Payment Group"
|
||
)
|
||
|
||
build_id = 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[Identity] = mapped_column(
|
||
ForeignKey("api_enum_dropdown.id"), nullable=True
|
||
)
|
||
part_direction_uu_id = mapped_column(
|
||
String, nullable=True, comment="Part Direction UUID"
|
||
)
|
||
part_type_id = mapped_column(
|
||
ForeignKey("build_types.id"), nullable=False, comment="Building Part Type"
|
||
)
|
||
part_type_uu_id = 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):
|
||
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_418_IM_A_TEAPOT,
|
||
detail="This Employee can not reach this building or building uu-id not found in database. "
|
||
"Check with your supervisor.",
|
||
)
|
||
|
||
if build_types := BuildTypes.find_one(uu_id=data.build_part_type_uu_id):
|
||
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_418_IM_A_TEAPOT,
|
||
detail="Part Gross Size can not be empty.",
|
||
)
|
||
|
||
if not data_dict["part_net_size"]:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||
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.find_one(id=self.build_part_type_id):
|
||
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__ = []
|
||
__include__fields__ = []
|
||
|
||
fix_value = mapped_column(
|
||
Numeric(20, 6),
|
||
server_default="0",
|
||
comment="Fixed value is deducted from debit.",
|
||
)
|
||
fix_percent = 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_column(SmallInteger, server_default="0")
|
||
|
||
discounted_percentage: Mapped[float] = mapped_column(
|
||
Numeric(6, 2), server_default="0.00"
|
||
) # %22
|
||
discounted_price = mapped_column(
|
||
Numeric(20, 2), server_default="0.00"
|
||
) # Normal: 78.00 TL
|
||
calculated_price = mapped_column(
|
||
Numeric(20, 2), server_default="0.00"
|
||
) # sana düz 75.00 TL yapar
|
||
|
||
build_parts_id = 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_column(
|
||
ForeignKey("people.id"),
|
||
nullable=False,
|
||
index=True,
|
||
comment="Responsible People ID",
|
||
)
|
||
person_uu_id = mapped_column(
|
||
String, nullable=False, comment="Responsible People UUID"
|
||
)
|
||
occupant_type = mapped_column(
|
||
ForeignKey("occupant_types.id"),
|
||
nullable=False,
|
||
comment="Occupant Type",
|
||
)
|
||
occupant_type_uu_id = 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: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||
):
|
||
from databases import Services, OccupantTypes
|
||
from api_events.events.events.events_bind_services import (
|
||
ServiceBindOccupantEventMethods,
|
||
)
|
||
|
||
created_living_space = BuildLivingSpace.find_or_create(**data)
|
||
occupant_type = OccupantTypes.find_one(
|
||
uu_id=created_living_space.occupant_type_uu_id
|
||
)
|
||
related_service = Services.find_one(
|
||
active=True,
|
||
related_responsibility=occupant_type.occupant_code,
|
||
)
|
||
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.",
|
||
)
|
||
ServiceBindOccupantEventMethods.bind_services_occupant_system(
|
||
service_id=related_service.id,
|
||
build_living_space_id=created_living_space.id,
|
||
)
|
||
return created_living_space
|
||
|
||
@classmethod
|
||
def find_living_from_customer_id(
|
||
cls, customer_id, process_date, add_days: int = 32
|
||
):
|
||
formatted_date = datetime.strptime(str(process_date), "%Y-%m-%d %H:%M:%S")
|
||
living_spaces = cls.filter_active(
|
||
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 BuildArea(CrudCollection):
|
||
"""
|
||
Builds class based on declarative_base and BaseMixin via session
|
||
"""
|
||
|
||
__tablename__ = "build_area"
|
||
|
||
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[Identity] = mapped_column(ForeignKey("build.id"))
|
||
build_uu_id = mapped_column(String, comment="Building UUID")
|
||
part_type_id = mapped_column(
|
||
ForeignKey("build_types.id"), nullable=True, comment="Building Part Type"
|
||
)
|
||
part_type_uu_id = 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__ = []
|
||
__include__fields__ = []
|
||
|
||
site_name = mapped_column(String(24), nullable=False)
|
||
site_no = mapped_column(String(8), nullable=False)
|
||
|
||
address_id: Mapped[Identity] = mapped_column(ForeignKey("addresses.id"))
|
||
address_uu_id = 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__ = []
|
||
__include__fields__ = []
|
||
|
||
build_id = mapped_column(
|
||
ForeignKey("build.id"), nullable=False, comment="Building ID"
|
||
)
|
||
build_uu_id = mapped_column(String, nullable=True, comment="Providing UUID")
|
||
company_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id"))
|
||
company_uu_id = mapped_column(String, nullable=True, comment="Providing UUID")
|
||
provide_id: Mapped[Identity] = mapped_column(
|
||
ForeignKey("api_enum_dropdown.id"), nullable=True
|
||
)
|
||
provide_uu_id = mapped_column(String, nullable=True, comment="Providing UUID")
|
||
contract_id = 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__ = []
|
||
__include__fields__ = []
|
||
|
||
build_id = mapped_column(
|
||
ForeignKey("build.id"), nullable=False, comment="Building ID"
|
||
)
|
||
build_uu_id = mapped_column(String, nullable=True, comment="Providing UUID")
|
||
people_id: Mapped[Identity] = mapped_column(ForeignKey("people.id"))
|
||
people_uu_id = mapped_column(String, nullable=True, comment="People UUID")
|
||
provide_id: Mapped[Identity] = mapped_column(
|
||
ForeignKey("api_enum_dropdown.id"), nullable=True
|
||
)
|
||
provide_uu_id = mapped_column(String, nullable=True, comment="Providing UUID")
|
||
contract_id = 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"},
|
||
)
|
||
|
||
|
||
# owner_people: Mapped["People"] = relationship(
|
||
# "People",
|
||
# back_populates="owner_buildings",
|
||
# foreign_keys=[current_owner_person_id],
|
||
# )
|
||
# tenant_people: Mapped["People"] = relationship(
|
||
# "People",
|
||
# back_populates="tenant_buildings",
|
||
# foreign_keys=[current_tenant_person_id],
|
||
# )
|
||
# decision_book_management: Mapped[List["BuildDecisionBookManagement"]] = (
|
||
# relationship(
|
||
# "BuildDecisionBookManagement",
|
||
# back_populates="buildings",
|
||
# foreign_keys="BuildDecisionBookManagement.build_parts_id",
|
||
# )
|
||
# )
|
||
# budget_records: Mapped[List["CompanyBudgetRecords"]] = relationship(
|
||
# "CompanyBudgetRecords",
|
||
# back_populates="parts",
|
||
# foreign_keys="CompanyBudgetRecords.build_parts_id",
|
||
# )
|
||
# living_spaces: Mapped[List["BuildLivingSpace"]] = relationship(
|
||
# "BuildLivingSpace",
|
||
# back_populates="parts",
|
||
# foreign_keys="BuildLivingSpace.build_parts_id",
|
||
# )
|
||
# decision_book_payment_master: Mapped[List["BuildDecisionBookPaymentsMaster"]] = (
|
||
# relationship(
|
||
# "BuildDecisionBookPaymentsMaster",
|
||
# back_populates="parts",
|
||
# foreign_keys="BuildDecisionBookPaymentsMaster.build_parts_id",
|
||
# )
|
||
# )
|
||
# decision_book_project_payments_master: Mapped[
|
||
# "BuildDecisionBookProjectPaymentsMaster"
|
||
# ] = relationship(
|
||
# "BuildDecisionBookProjectPaymentsMaster",
|
||
# back_populates="parts",
|
||
# foreign_keys="BuildDecisionBookProjectPaymentsMaster.build_parts_id",
|
||
# )
|
||
# search_iban_description: Mapped["BuildIbanDescription"] = relationship(
|
||
# "BuildIbanDescription",
|
||
# back_populates="parts",
|
||
# foreign_keys="BuildIbanDescription.build_parts_id",
|
||
# )
|
||
|
||
# parts: Mapped[List["BuildParts"]] = relationship(
|
||
# "BuildParts", back_populates="living_spaces", foreign_keys=[build_parts_id]
|
||
# )
|
||
# owner_people: Mapped["People"] = relationship(
|
||
# "People", back_populates="owner_living_spaces", foreign_keys=[owner_person_id]
|
||
# )
|
||
# life_people: Mapped["People"] = relationship(
|
||
# "People", back_populates="life_living_spaces", foreign_keys=[life_person_id]
|
||
# )
|
||
# company_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id"))
|
||
# response_company_id: Mapped[Identity] = mapped_column(ForeignKey("companies.id"))
|
||
# person_id: Mapped[Identity] = mapped_column(ForeignKey("people.id"))
|
||
|
||
# companies: Mapped["Companies"] = relationship(
|
||
# "Companies", back_populates="buildings", foreign_keys=[company_id]
|
||
# )
|
||
# @classmethod
|
||
# def select_action(cls, duty_id, token=None):
|
||
# from database_sql_models import Companies
|
||
#
|
||
# related_companies = Companies.select_action(duty_id=duty_id)
|
||
# companies_ids = [company.id for company in related_companies.all()]
|
||
# return cls.filter_all(cls.company_id.in_(companies_ids)).query
|