Skip to content

PDJB-1305: Add property record provide-later notification banners - #1601

Draft
JasminConterioSW wants to merge 69 commits into
mainfrom
feat/PDJB-1305-property-record-notification-banners
Draft

PDJB-1305: Add property record provide-later notification banners#1601
JasminConterioSW wants to merge 69 commits into
mainfrom
feat/PDJB-1305-property-record-notification-banners

Conversation

@JasminConterioSW

@JasminConterioSW JasminConterioSW commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Ticket number

PDJB-1305

Goal of change

Add "provide this later" notification banners to the property and tenancy details record, shown when a landlord has skipped licensing and/or tenancy details, combined with compliance-certificate warnings where relevant.

Description of main change(s)

  • Introduces a single, data-driven PropertyDetailsNotificationBannerViewModel for the property record banner. It exposes messages: List<NotificationMessage>, where each message is an optional lead-in text followed by ordered links (each with its own before/after text). This replaces the previous two-mechanism approach (a hardcoded provide-later variant banner plus a separate compliance banner coordinated by a suppress flag).
  • Shows the appropriate banner based on the record's state: licensing-only, tenancy-only, both skipped, a combined provide-later + compliance sentence (single message, two links), or compliance-only. Banners are only shown for occupied properties in the provide-later cases.
  • Uses landlord- vs local-council-specific copy throughout, and splits the "missing compliance certificates" copy by view.
  • Names the specific certificate in the expired-certificate banner (adds linkText for gas, electrical and EPC).
  • Moves compliance banner message construction into NotificationBannerViewModelService and lifts the feature-flag decision up to the controller / compliance factory, so the flag is parsed once per request.
  • Wires the banner into PropertyDetailsController for both the landlord and local-council views.
  • Updates the controller to throw if it can't find a compliance record as we always create one anyway - applies to flag off as well as flag on

Flag-off (legacy) behaviour is preserved: a parallel PropertyDetailsBeforePdjb939NotificationBannerViewModel produces the same banner shape from compliance messages only (using the legacy copy), so the flag-off template renders identically to before. All flag-off banner code is grouped behind the beforePdjb939 naming so it can be deleted in one pass when the provide-later flag is permanently enabled.

This work was split out of PDJB-1048 (property/tenancy record layout) and is stacked on that branch.

Anything you'd like to highlight to the reviewer?

  • This PR is stacked on feat/PDJB-1048-property-record-provide-later — review/merge that first.
  • The banner deliberately keeps two view models (flag-on PropertyDetailsNotificationBannerViewModel and flag-off PropertyDetailsBeforePdjb939NotificationBannerViewModel) that both produce the same messages shape, so both templates share the same rendering markup and the flag-off variant is trivially removable later.
  • The seed data and provide-later columns that support these scenarios live in the PDJB-1048 PR.

Checklist

  • Screenshots of any UI changes have been added
  • Unit tests for new logic (e.g. new service methods) have been added — PropertyDetailsNotificationBannerViewModelTests, PropertyDetailsBeforePdjb939NotificationBannerViewModelTests, and expanded PropertyComplianceViewModelFactoryTests
  • Controller tests for any new endpoints, including testing the relevant permissions — N/A: no new endpoints; the banner is added to the existing property-details views and is exercised by the integration tests below
  • Single page integration tests have been added for any unhappy-flow UI features, e.g. validation errors — PropertyDetailsTests now covers the licensing-only, tenancy-only, both-skipped, combined and compliance banner scenarios for both landlord and local-council views
  • New journey steps have been added to the appropriate journey integration test(s) — N/A: no journey changes
  • A new journey integration test has been added for any new journeys — N/A: no new journeys
  • New email templates have been added to emailTemplates.json — N/A: no email changes
  • Test suite has been run in full locally and is passing — affected unit + integration suites run and passing; please run the full suite before merge
  • Branch has been rebased onto main and run locally — main has been merged into the underlying PDJB-1048 branch rather than rebased
  • TODO comments referencing this JIRA ticket have been searched for and removed — no PDJB-1305 TODOs remain; the intentional beforePdjb939 markers reference the future flag-removal ticket (PDJB-939), not this one
  • Seed data has been updated as needed for your feature to be tested — QA seed data for the compliance/provide-later banners has been added
  • NftDataSeeder has been updated to reflect any changes to the database schema — N/A: no database schema changes in this PR
  • Any special release instructions have been added to the relevant release ticket — N/A: none required
  • QA instructions have been added to the ticket
  • This feature is behind a feature flag. I've checked that there will be no change in function if the feature flag is disabled — the flag-off (beforePdjb939) view models and template reproduce the previous banners exactly
  • This feature is not behind a feature flag — N/A: it is behind PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING

… support

Introduces the new read-only 'Property and tenancy details' property record layout behind the ALLOW_SKIPPING_PROPERTY_REGISTRATION_FIELDS feature flag, grouping the record into property details, ownership, occupation, licensing and tenancy sections. Licensing and tenancy support a provide-later state showing a deadline (last occupied date + 28 days) for occupied properties, matching the compliance tab behaviour. Adds UPRN and multiline address to the property details section, seed data for the four occupancy/licensing scenarios, and unit and integration test coverage.
Adds notification banners on the property record (behind
PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) for occupied properties
where licensing and/or tenancy details are provided later, and a combined
banner when there is also an outstanding compliance issue. The combined
banner suppresses the separate provide-later and compliance-cert banners.
# Conflicts:
#	src/main/resources/data-local.sql
…e and flag-off path is isolated under beforePdjb939
…d seed inserts)

- Move flag-off heading to propertyDetails.beforePdjb939.propertyRecord.heading and inline the h2 into each layout block
- Rename newAddressRow/legacyAddressRow to addressRow/beforePdjb939AddressRow; drop hideNullUprn in favour of !isLandlordView
- Combine property_ownership seed inserts into a single CTE-based insert in data-test.sql and data-integration.sql
- Rename view-model tests to standard/beforePdjb939 wording; merge the two provideLaterEnabled controller tests into one parameterised test
…n tests; isolate flag-off coverage under BeforePdjb939Layout
# Conflicts:
#	.secrets.baseline
#	src/main/kotlin/uk/gov/communities/prsdb/webapp/database/entity/PropertyOwnership.kt
#	src/test/kotlin/uk/gov/communities/prsdb/webapp/controllers/PropertyDetailsControllerTests.kt
#	src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsTests.kt
#	src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt
# Conflicts:
#	.secrets.baseline
#	src/main/resources/data-local.sql
…DJB-1305-property-record-notification-banners

# Conflicts:
#	src/main/kotlin/uk/gov/communities/prsdb/webapp/models/viewModels/summaryModels/propertyComplianceViewModels/PropertyComplianceViewModelFactory.kt
#	src/main/resources/data-local.sql
#	src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsTests.kt
#	src/test/kotlin/uk/gov/communities/prsdb/webapp/models/viewModels/summaryModels/propertyComplianceViewModels/PropertyComplianceViewModelFactoryTests.kt
…. Previously there were two separate banner mechanisms — a provide-later banner (Variant enum LICENSING/TENANCY/BOTH/COMBINED with copy hardcoded in the template) and a data-driven compliance banner — coordinated by a suppressComplianceBanner flag. Now there's a single  PropertyDetailsNotificationBannerViewModel.messages: List<NotificationMessage>, where each  NotificationMessage  is an optional  mainText  + orderedNotificationBannerLink s (each with optional before/after text). The combined case stays a single merged sentence with two links
Split the property-details page into two parallel view model + template
stacks selected once in the controller, so the flag is parsed a single
time and the pre-PDJB-939 path can be deleted cleanly.

- Add PropertyDetailsViewModelBase with the shared row/section logic
- Make PropertyDetailsViewModel the flag-on subclass and add
  PropertyDetailsBeforePdjb939ViewModel as the flag-off subclass
- Select the view model and template in PropertyDetailsController via a
  single feature-flag check
- Split the templates into propertyDetailsView.html (flag-on) and
  propertyDetailsViewBeforePdjb939.html (flag-off) with shared
  landlordDetails.html and compliance.html tab fragments
- Split the view model tests to match the new class structure
Split the property-details page into two parallel view model + template
stacks selected once in the controller, so the flag is parsed a single
time and the pre-PDJB-939 path can be deleted cleanly.

- Add PropertyDetailsViewModelBase with the shared row/section logic
- Make PropertyDetailsViewModel the flag-on subclass and add
  PropertyDetailsBeforePdjb939ViewModel as the flag-off subclass
- Select the view model and template in PropertyDetailsController via a
  single feature-flag check
- Split the templates into propertyDetailsView.html (flag-on) and
  propertyDetailsViewBeforePdjb939.html (flag-off) with shared
  landlordDetails.html and compliance.html tab fragments
- Split the view model tests to match the new class structure
@JasminConterioSW
JasminConterioSW force-pushed the feat/PDJB-1048-property-record-provide-later branch from 5d89f1e to 12bcf56 Compare July 27, 2026 09:55
…r flag parsing

Merge the PDJB-1048 controller-level provide-later flag split into the
notification-banner branch and lift all provide-later flag parsing up to the
controller so the flag is read exactly once per request.

- PropertyDetailsController parses PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING
  once per handler and threads it into view-model/template selection, the
  compliance view-model factory, and the flag-on unified banner.
- PropertyComplianceViewModelFactory no longer reads the flag itself; it takes a
  provideLaterEnabled parameter.
- Flag-off reproduces the main-branch compliance banner exactly as a self-contained,
  deletable path (legacy notification message types, service method, message key and
  template markup), rendered via propertyDetailsViewBeforePdjb939.html.
- Flag-on keeps the unified provide-later + compliance banner.
…DJB-1305-property-record-notification-banners

# Conflicts:
#	src/main/kotlin/uk/gov/communities/prsdb/webapp/controllers/PropertyDetailsController.kt
#	src/main/kotlin/uk/gov/communities/prsdb/webapp/models/viewModels/summaryModels/PropertyDetailsBeforePdjb939ViewModel.kt
#	src/main/kotlin/uk/gov/communities/prsdb/webapp/models/viewModels/summaryModels/PropertyDetailsViewModelBase.kt
#	src/main/resources/templates/propertyDetailsViewBeforePdjb939.html
#	src/test/kotlin/uk/gov/communities/prsdb/webapp/models/viewModels/summaryModels/PropertyDetailsBeforePdjb939ViewModelTests.kt
Resolves conflicts from main's parallel restructure work (PDJB-1353 bedrooms, PDJB-1054 joint-landlord invitations for local councils) against the 1048 controller-level flag split. Ports PDJB-1054 into the landlordDetails fragment and keeps main's new invitation/integration tests alongside the split-VM tests.
Add PropertyDetailsBeforePdjb939NotificationBannerViewModel so the flag-off
path sets the same notificationBanner attribute as the flag-on path, letting
both templates render the banner identically. Combine the two notification
message-key builders into one (beforePdjb939 flag + missingMainTextKey
selector), rename the compliance view model message fields to make clear they
are compliance-only, and drop the legacy PropertyComplianceNotificationMessage
structures and the flag-off template's bespoke banner blocks.
…omState

The flag-off case now has its own PropertyDetailsBeforePdjb939NotificationBannerViewModel,
so PropertyDetailsNotificationBannerViewModel.fromState is only ever called on the flag-on
path (provideLaterEnabled was always true). Remove the redundant parameter, simplify the
provide-later check, and delete the now-unreachable flag-disabled test.
Base automatically changed from feat/PDJB-1048-property-record-provide-later to main July 29, 2026 08:36
…ty-record-notification-banners

# Conflicts:
#	src/main/kotlin/uk/gov/communities/prsdb/webapp/controllers/PropertyDetailsController.kt
#	src/main/kotlin/uk/gov/communities/prsdb/webapp/models/viewModels/summaryModels/PropertyDetailsViewModel.kt
#	src/main/resources/data-integration.sql
#	src/main/resources/data-local.sql
#	src/main/resources/data-test.sql
#	src/main/resources/messages/propertyDetails.yml
#	src/main/resources/templates/propertyDetailsView.html
#	src/main/resources/templates/propertyDetailsViewBeforePdjb939.html
#	src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsTests.kt
…iewModelService

Build the full property-record banner in NotificationBannerViewModelService instead of
couriering compliance banner inputs on PropertyComplianceViewModel. The controller now
calls a single buildNotificationBanner method, and the compliance view model only keeps
compliance-tab concerns (isAllValid). Also removes orphaned root template copies of the
compliance and landlordDetails fragments left by an earlier merge.
Rename combined -> propertyAndCompliance and both -> licensingAndTenancy
across message keys, YAML, and tests to match the view model method names.
@JasminConterioSW
JasminConterioSW force-pushed the feat/PDJB-1305-property-record-notification-banners branch from 48a8fea to 9168a25 Compare July 30, 2026 10:45
Enforce the invariant that every registered property has a PropertyCompliance record. PropertyDetailsController now throws PrsdbWebException when compliance is null (regardless of feature flag), and the notification banner service takes a non-null PropertyCompliance. Adds a seed compliance record for property_ownership 40 in data-local.sql and updates tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant