Source code for ska_oso_pdm.proposal_management.panel

from datetime import datetime, timezone

from pydantic import AwareDatetime, Field, field_validator

from ska_oso_pdm._shared import Metadata, PanelID, PdmObject, ProposalID
from ska_oso_pdm._shared.atoms import TerseStrEnum
from ska_oso_pdm._shared.ids import ReviewerID


[docs] class ReviewerStatus(TerseStrEnum): ACCEPTED = "Accepted" DECLINED = "Declined" PENDING = "Pending"
[docs] class ProposalAssignment(PdmObject): prsl_id: ProposalID assigned_on: AwareDatetime = Field( default_factory=lambda: datetime.now(timezone.utc) )
[docs] class ReviewerAssignment(PdmObject): reviewer_id: ReviewerID assigned_on: AwareDatetime = Field( default_factory=lambda: datetime.now(timezone.utc) ) status: ReviewerStatus = ReviewerStatus.PENDING
[docs] class Panel(PdmObject): metadata: Metadata = Field( default_factory=Metadata, description="The metadata of this Panel." ) panel_id: PanelID name: str cycle: str | None = None expiry_date: AwareDatetime | None = None proposals: list[ProposalAssignment] = Field(default_factory=list) sci_reviewers: list[ReviewerAssignment] = Field(default_factory=list) tech_reviewers: list[ReviewerAssignment] = Field(default_factory=list)
[docs] @field_validator("proposals", mode="after") @classmethod def ensure_unique_proposals( cls, proposals: list[ProposalAssignment] ) -> list[ProposalAssignment]: """ Ensure that `proposals` list contains only unique prsl_ids, and preserves the first occurrence. """ seen: set[str] = set() unique: list[ProposalAssignment] = [] for assignment in proposals: if assignment.prsl_id not in seen: unique.append(assignment) seen.add(assignment.prsl_id) return unique
[docs] def add_proposal(self, prsl_id: ProposalID) -> None: """Appends a proposal only if not already present.""" if all(p.prsl_id != prsl_id for p in self.proposals): self.proposals.append(ProposalAssignment(prsl_id=prsl_id))