Coverage for middle_layer/solicit/domain_layer/entities/external_joint_parameter.py: 88.89%
27 statements
« prev ^ index » next coverage.py v7.10.5, created at 2026-04-13 06:13 +0000
« prev ^ index » next coverage.py v7.10.5, created at 2026-04-13 06:13 +0000
1# Copyright 2024 Associated Universities, Inc.
2#
3# This file is part of Telescope Time Allocation Tools (TTAT).
4#
5# TTAT is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# any later version.
9#
10# TTAT is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with TTAT. If not, see <https://www.gnu.org/licenses/>.
17# pyright: reportImportCycles=false
19import typing
21from sqlalchemy import Column, ForeignKey, Integer, Table
22from sqlalchemy.orm import Mapped, mapped_column, relationship
24from common.domain_layer import JSON_OBJECT
25from common.domain_layer.entities.base import Base
27if typing.TYPE_CHECKING:
28 from propose.domain_layer.entities.proposal import CapabilityRequest
29 from propose.domain_layer.entities.resource_specification import ResourceSpecification
30 from solicit.domain_layer.entities.capability import Facility
33external_joint_required_facilities = Table(
34 "external_joint_required_facilities",
35 Base.metadata,
36 Column(
37 "external_joint_parameter_id",
38 Integer,
39 ForeignKey("external_joint_parameters.external_joint_parameter_id", ondelete="cascade"),
40 nullable=False,
41 ),
42 Column("facility_id", Integer, ForeignKey("facilities.facility_id", ondelete="cascade"), nullable=False),
43 extend_existing=True,
44)
47class ExternalJointParameter(Base):
48 __tablename__: str = "external_joint_parameters"
50 external_joint_parameter_id: Mapped[int] = mapped_column(primary_key=True)
51 capability_request_id: Mapped[int] = mapped_column(
52 ForeignKey("capability_requests.capability_request_id", ondelete="cascade"), nullable=False
53 )
54 capability_request: Mapped["CapabilityRequest"] = relationship(
55 "CapabilityRequest", back_populates="external_joint_parameter"
56 )
57 requested_amount: Mapped[float] = mapped_column(nullable=False)
58 simultaneous: Mapped[bool] = mapped_column(nullable=False)
59 coordinated: Mapped[bool] = mapped_column(nullable=False)
60 required_facilities: Mapped[list["Facility"]] = relationship(
61 "Facility",
62 back_populates="external_joint_parameters",
63 secondary=external_joint_required_facilities,
64 )
65 resource_specification_id: Mapped[int] = mapped_column(
66 ForeignKey("resource_specifications.resource_specification_id", ondelete="CASCADE"), nullable=False
67 )
68 resource_specification: Mapped["ResourceSpecification"] = relationship(
69 "ResourceSpecification", back_populates="external_joint_parameters"
70 )
72 @typing.override
73 def __json__(self) -> JSON_OBJECT:
74 overrides: JSON_OBJECT = {"requiredFacilities": [facility.facility_id for facility in self.required_facilities]}
75 return super().__json__() | overrides
77 def clone(self, parent: "CapabilityRequest|None" = None) -> "ExternalJointParameter":
78 return ExternalJointParameter(
79 requested_amount=self.requested_amount,
80 simultaneous=self.simultaneous,
81 coordinated=self.coordinated,
82 required_facilities=list(self.required_facilities),
83 capability_request=parent or self.capability_request,
84 resource_specification=self.resource_specification,
85 )