Skip to content

Commit

Permalink
GH-100: Make funding programme mandatory
Browse files Browse the repository at this point in the history
  • Loading branch information
Sparrow0hawk committed Apr 8, 2024
1 parent 0e37651 commit c8eef94
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 89 deletions.
4 changes: 2 additions & 2 deletions schemes/domain/schemes/schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@


class Scheme:
def __init__(self, id_: int, name: str, authority_id: int, type_: SchemeType):
def __init__(self, id_: int, name: str, authority_id: int, type_: SchemeType, funding_programme: FundingProgramme):
self.id = id_
self.name = name
self.authority_id = authority_id
self.type = type_
self.funding_programme: FundingProgramme | None = None
self.funding_programme = funding_programme
self._funding = SchemeFunding()
self._milestones = SchemeMilestones()
self._outputs = SchemeOutputs()
Expand Down
2 changes: 1 addition & 1 deletion schemes/infrastructure/database/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class CapitalSchemeEntity(Base):
nullable=False,
)
scheme_type_id: Mapped[int]
funding_programme_id: Mapped[int | None]
funding_programme_id: Mapped[int]
capital_scheme_bid_statuses: Mapped[list[CapitalSchemeBidStatusEntity]] = relationship()
capital_scheme_financials: Mapped[list[CapitalSchemeFinancialEntity]] = relationship()
capital_scheme_milestones: Mapped[list[CapitalSchemeMilestoneEntity]] = relationship()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Alter capital scheme funding programme nullable
Revision ID: 8e77c6c5b1b8
Revises: 911e18fe1942
Create Date: 2024-04-08 15:08:19.373194
"""

from typing import Sequence, Union

from alembic import op

revision: str = "8e77c6c5b1b8"
down_revision: Union[str, None] = "911e18fe1942"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
with op.batch_alter_table("capital_scheme", schema="capital_scheme") as batch_op:
batch_op.alter_column("funding_programme_id", nullable=False)


def downgrade() -> None:
with op.batch_alter_table("capital_scheme", schema="capital_scheme") as batch_op:
batch_op.alter_column("funding_programme_id", nullable=True)
10 changes: 5 additions & 5 deletions schemes/infrastructure/database/schemes/schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ def _capital_scheme_to_domain(self, capital_scheme: CapitalSchemeEntity) -> Sche
name=capital_scheme.scheme_name,
authority_id=capital_scheme.bid_submitting_authority_id,
type_=self._scheme_type_mapper.to_domain(capital_scheme.scheme_type_id),
funding_programme=self._funding_programme_mapper.to_domain(capital_scheme.funding_programme_id),
)
scheme.funding_programme = self._funding_programme_mapper.to_domain(capital_scheme.funding_programme_id)

for capital_scheme_bid_status in capital_scheme.capital_scheme_bid_statuses:
scheme.funding.update_bid_status(self._capital_scheme_bid_status_to_domain(capital_scheme_bid_status))
Expand Down Expand Up @@ -288,8 +288,8 @@ class FundingProgrammeMapper:
FundingProgrammes.CRSTS: 8,
}

def to_id(self, funding_programme: FundingProgramme | None) -> int | None:
return self._IDS[funding_programme] if funding_programme else None
def to_id(self, funding_programme: FundingProgramme) -> int:
return self._IDS[funding_programme]

def to_domain(self, id_: int | None) -> FundingProgramme | None:
return inverse_dict(self._IDS)[id_] if id_ else None
def to_domain(self, id_: int) -> FundingProgramme:
return inverse_dict(self._IDS)[id_]
21 changes: 12 additions & 9 deletions schemes/views/schemes/schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def from_domain(cls, type_: SchemeType) -> SchemeTypeContext:

@dataclass(frozen=True)
class FundingProgrammeContext:
name: str | None
name: str
_NAMES = {
FundingProgrammes.ATF2: "ATF2",
FundingProgrammes.ATF3: "ATF3",
Expand All @@ -239,8 +239,8 @@ class FundingProgrammeContext:
}

@classmethod
def from_domain(cls, funding_programme: FundingProgramme | None) -> FundingProgrammeContext:
return cls(name=cls._NAMES[funding_programme] if funding_programme else None)
def from_domain(cls, funding_programme: FundingProgramme) -> FundingProgrammeContext:
return cls(name=cls._NAMES[funding_programme])


@bp.get("<int:scheme_id>/spend-to-date")
Expand Down Expand Up @@ -375,7 +375,7 @@ class SchemeRepr:
id: int
name: str
type: SchemeTypeRepr
funding_programme: FundingProgrammeRepr | None = None
funding_programme: FundingProgrammeRepr
bid_status_revisions: list[BidStatusRevisionRepr] = field(default_factory=list)
financial_revisions: list[FinancialRevisionRepr] = field(default_factory=list)
milestone_revisions: list[MilestoneRevisionRepr] = field(default_factory=list)
Expand All @@ -388,9 +388,7 @@ def from_domain(cls, scheme: Scheme) -> SchemeRepr:
id=scheme.id,
name=scheme.name,
type=SchemeTypeRepr.from_domain(scheme.type),
funding_programme=(
FundingProgrammeRepr.from_domain(scheme.funding_programme) if scheme.funding_programme else None
),
funding_programme=FundingProgrammeRepr.from_domain(scheme.funding_programme),
bid_status_revisions=[
BidStatusRevisionRepr.from_domain(bid_status_revision)
for bid_status_revision in scheme.funding.bid_status_revisions
Expand All @@ -413,8 +411,13 @@ def from_domain(cls, scheme: Scheme) -> SchemeRepr:
)

def to_domain(self, authority_id: int) -> Scheme:
scheme = Scheme(id_=self.id, name=self.name, authority_id=authority_id, type_=self.type.to_domain())
scheme.funding_programme = self.funding_programme.to_domain() if self.funding_programme else None
scheme = Scheme(
id_=self.id,
name=self.name,
authority_id=authority_id,
type_=self.type.to_domain(),
funding_programme=self.funding_programme.to_domain(),
)

for bid_status_revision_repr in self.bid_status_revisions:
scheme.funding.update_bid_status(bid_status_revision_repr.to_domain())
Expand Down
2 changes: 1 addition & 1 deletion schemes/views/templates/scheme/_overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"text": "Funding programme"
},
"value": {
"text": overview.funding_programme.name | d("", true)
"text": overview.funding_programme.name
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion schemes/views/templates/schemes.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ <h1 class="govuk-heading-xl">
"html": referenceHtml
},
{
"text": scheme.funding_programme.name | d("", true)
"text": scheme.funding_programme.name
},
{
"html": nameHtml
Expand Down
12 changes: 10 additions & 2 deletions tests/builders.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
from datetime import datetime

from schemes.domain.dates import DateRange
from schemes.domain.schemes import BidStatus, BidStatusRevision, Scheme, SchemeType
from schemes.domain.schemes import (
BidStatus,
BidStatusRevision,
FundingProgramme,
FundingProgrammes,
Scheme,
SchemeType,
)


def build_scheme(
id_: int,
name: str,
authority_id: int,
type_: SchemeType = SchemeType.CONSTRUCTION,
funding_programme: FundingProgramme = FundingProgrammes.ATF2,
bid_status: BidStatus = BidStatus.FUNDED,
bid_status_revisions: list[BidStatusRevision] | None = None,
) -> Scheme:
Expand All @@ -18,6 +26,6 @@ def build_scheme(
else [BidStatusRevision(id_=None, effective=DateRange(datetime.min, None), status=bid_status)]
)

scheme = Scheme(id_, name, authority_id, type_)
scheme = Scheme(id_, name, authority_id, type_, funding_programme)
scheme.funding.update_bid_statuses(*bid_status_revisions)
return scheme
67 changes: 51 additions & 16 deletions tests/domain/schemes/test_schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@

class TestScheme:
def test_create(self) -> None:
scheme = Scheme(id_=1, name="Wirral Package", authority_id=2, type_=SchemeType.CONSTRUCTION)
scheme = Scheme(
id_=1,
name="Wirral Package",
authority_id=2,
type_=SchemeType.CONSTRUCTION,
funding_programme=FundingProgrammes.ATF4,
)

assert (
scheme.id == 1
and scheme.name == "Wirral Package"
and scheme.authority_id == 2
and scheme.type == SchemeType.CONSTRUCTION
and scheme.funding_programme is None
and scheme.funding_programme == FundingProgrammes.ATF4
)

def test_get_reference(self) -> None:
Expand Down Expand Up @@ -69,8 +75,13 @@ def test_get_reviews(self) -> None:
],
)
def test_is_updateable_when_funded(self, bid_status: BidStatus, expected_updateable: bool) -> None:
scheme = build_scheme(id_=1, name="Wirral Package", authority_id=2, bid_status=bid_status)
scheme.funding_programme = FundingProgrammes.ATF4
scheme = build_scheme(
id_=1,
name="Wirral Package",
authority_id=2,
funding_programme=FundingProgrammes.ATF4,
bid_status=bid_status,
)
scheme.milestones.update_milestone(
MilestoneRevision(
id_=3,
Expand All @@ -93,8 +104,13 @@ def test_is_updateable_when_funded(self, bid_status: BidStatus, expected_updatea
],
)
def test_is_updateable_when_active_and_incomplete(self, milestone: Milestone, expected_updateable: bool) -> None:
scheme = build_scheme(id_=1, name="Wirral Package", authority_id=2, bid_status=BidStatus.FUNDED)
scheme.funding_programme = FundingProgrammes.ATF4
scheme = build_scheme(
id_=1,
name="Wirral Package",
authority_id=2,
funding_programme=FundingProgrammes.ATF4,
bid_status=BidStatus.FUNDED,
)
scheme.milestones.update_milestone(
MilestoneRevision(
id_=3,
Expand All @@ -111,16 +127,20 @@ def test_is_updateable_when_active_and_incomplete(self, milestone: Milestone, ex
@pytest.mark.parametrize(
"funding_programme, expected_updateable",
[
(None, True),
(FundingProgrammes.ATF4, True),
(FundingProgramme("ATF100", True), False),
],
)
def test_is_updateable_when_not_under_embargo(
self, funding_programme: FundingProgramme | None, expected_updateable: bool
self, funding_programme: FundingProgramme, expected_updateable: bool
) -> None:
scheme = build_scheme(id_=1, name="Wirral Package", authority_id=2, bid_status=BidStatus.FUNDED)
scheme.funding_programme = funding_programme
scheme = build_scheme(
id_=1,
name="Wirral Package",
authority_id=2,
funding_programme=funding_programme,
bid_status=BidStatus.FUNDED,
)
scheme.milestones.update_milestone(
MilestoneRevision(
id_=3,
Expand All @@ -135,8 +155,13 @@ def test_is_updateable_when_not_under_embargo(
assert scheme.is_updateable == expected_updateable

def test_is_updateable_when_no_bid_status_revision(self) -> None:
scheme = build_scheme(id_=1, name="Wirral Package", authority_id=2, bid_status_revisions=[])
scheme.funding_programme = FundingProgrammes.ATF4
scheme = build_scheme(
id_=1,
name="Wirral Package",
authority_id=2,
funding_programme=FundingProgrammes.ATF4,
bid_status_revisions=[],
)
scheme.milestones.update_milestone(
MilestoneRevision(
id_=3,
Expand All @@ -151,14 +176,24 @@ def test_is_updateable_when_no_bid_status_revision(self) -> None:
assert scheme.is_updateable is False

def test_is_updateable_when_no_milestone_revision(self) -> None:
scheme = build_scheme(id_=1, name="Wirral Package", authority_id=2, bid_status=BidStatus.FUNDED)
scheme.funding_programme = FundingProgrammes.ATF4
scheme = build_scheme(
id_=1,
name="Wirral Package",
authority_id=2,
funding_programme=FundingProgrammes.ATF4,
bid_status=BidStatus.FUNDED,
)

assert scheme.is_updateable is True

def test_is_updateable_uses_latest_milestone_revision(self) -> None:
scheme = build_scheme(id_=1, name="Wirral Package", authority_id=2, bid_status=BidStatus.FUNDED)
scheme.funding_programme = FundingProgrammes.ATF4
scheme = build_scheme(
id_=1,
name="Wirral Package",
authority_id=2,
funding_programme=FundingProgrammes.ATF4,
bid_status=BidStatus.FUNDED,
)
scheme.milestones.update_milestones(
MilestoneRevision(
id_=3,
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def build_scheme(
id_: int,
name: str,
type_: str = "construction",
funding_programme: str | None = None,
funding_programme: str = "ATF2",
bid_status: str = "funded",
financial_revisions: list[FinancialRevisionRepr] | None = None,
milestone_revisions: list[MilestoneRevisionRepr] | None = None,
Expand Down
Loading

0 comments on commit c8eef94

Please sign in to comment.