Skip to content

PDJB-990: Skip licensing details during property registration - #1607

Open
bnjn-mt wants to merge 19 commits into
mainfrom
feat/PDJB-990-skip-licensing-details
Open

PDJB-990: Skip licensing details during property registration#1607
bnjn-mt wants to merge 19 commits into
mainfrom
feat/PDJB-990-skip-licensing-details

Conversation

@bnjn-mt

@bnjn-mt bnjn-mt commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Ticket number

PDJB-990

Goal of change

Allow landlords to defer providing licensing details during the property registration journey via a "Provide this later" option, mirroring the existing skip behaviour for compliance certificates.

Licensing page with Provide this later button Provide licensing later confirmation Provide licensing later variant CYA showing Provide this later

Description of main change(s)

  • Adds a "Provide this later" secondary button to the licensing type step, behind the PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING feature flag.
  • Adds a new provided confirmation page with two variants — occupied and unoccupied
  • Adds message keys in forms.yml and registerProperty.yml.
  • Adds/updates unit tests for the new step configs, the licensing helper and the registration service.

Checklist

  • Screenshots of any UI changes have been added
  • Unit tests for new logic (e.g. new service methods) have been added
  • Single page integration tests have been added for any unhappy-flow UI features, e.g. validation errors
  • New journey steps have been added to the appropriate journey integration test(s)
  • Test suite has been run in full locally and is passing
  • Branch has been rebased onto main and run locally, with everything working as expected
  • TODO comments referencing this JIRA ticket have been searched for and removed
  • 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

@bnjn-mt
bnjn-mt force-pushed the feat/PDJB-990-skip-licensing-details branch from da6f948 to 41d3700 Compare July 17, 2026 16:49
@bnjn-mt
bnjn-mt marked this pull request as ready for review July 20, 2026 11:05
val address = addressService.findOrCreateAddress(addressModel)

val license =
if (licenseType != LicensingType.NO_LICENSING) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happened to no_licensing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user clicks the provide this later button on the licensing type page, licenseType is null and this variable will also be null. This state means the user still needs to provide this information and will see the "Provide this later" text on other pages (CYA/update etc.)

We can create a license with every value of the LicensingType enum.

My reasoning for this is so we can differentiate between NO_LICENSING and null (provide this later).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense, though I worry that the previous code signature here suggests that a license type of NO_LICENSING used to be stored as null. also, in the LicenseService there is this snippet in the license updating code

if (updateLicenceType == LicensingType.NO_LICENSING) {
    license?.let { licenseRepository.delete(license) }
    null
}

so we may need more work to update the assumption that 'provide later' => null & 'no_licensing' is stored explicitly

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reverted this change and created a LicenseService.licenceShouldBeStored method that allows us to keep the existing code signature.

fun licenceShouldBeStored(
licenceType: LicensingType?,
licenseProvideLater: Boolean = false,
): Boolean = licenceType != null && licenceType != LicensingType.NO_LICENSING && !licenseProvideLater

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to check; when would licenseType be null?

@bnjn-mt bnjn-mt Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the user clicks the 'Provide this later' button during the property registration.

@samyou-softwire samyou-softwire Jul 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if licenceProvideLater is false and licenceType is not NO_LICENSING those two would imply that the license is not null?

thinking about it, it feels like the reason this is getting hard to reason about is that it's surprising that NO_LICENSING is a license type registered in the enum but PROVIDE_LATER isn't. it leads to code with some quite surprising conditions where we 'just can't' check licenseType

if the database has been laid out this way that's fine, but I think our service layer is suffering. there are only 5 possible states for a license to be in

  • selective
  • HMO mandatory
  • HMO additional
  • no license
  • provide later
    so I think it'll make this code a lot more clearer if we can make the enum reflect that. it's fine if we don't actually end up putting them all in the database (NO_LICENSING was already stored as null), but I think this'll help us out now and down the road when it comes to interpreting the database

then the signature of this method could become

fun licenceShouldBeStored(
            licenceType: LicensingType
        )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it would be nicer to just add an extra enum value here

@Travis-Softwire Travis-Softwire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor points, but otherwise LGTM

Comment thread src/main/resources/messages/forms.yml Outdated
licensingType: Licensing type
noLicensing: None
licensingProvideLater: Provide this later
additionalLandlords:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These headings are a bit suspect...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would something like: forms.checkPropertyAnswers.propertyDetails.licensing.licensingProvideLater be better?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it was the new lines below that were suspect - they don't seem related to this ticket!

@bnjn-mt

bnjn-mt commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

This is ready to merge if all looks good to you @samyou-softwire :)

@Travis-Softwire Travis-Softwire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments from me, plus seconding Sammy's earlier suggestion for adding provide later as a licensing type enum value to make some of the checking logic simpler


@Test
fun `licenceShouldBeStored returns false when the licensing details are being provided later`() {
assertFalse(LicenseService.licenceShouldBeStored(null, licenseProvideLater = true))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is passing because you're passing in null rather than testing the actual functionality? Should it be e.g. assertFalse(LicenseService.licenceShouldBeStored(LicensingType.SELECTIVE_LICENCE, licenseProvideLater = true)) instead?

fun licenceShouldBeStored(
licenceType: LicensingType?,
licenseProvideLater: Boolean = false,
): Boolean = licenceType != null && licenceType != LicensingType.NO_LICENSING && !licenseProvideLater

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it would be nicer to just add an extra enum value here

) : Task<LicensingState>() {
override fun makeSubJourney(state: LicensingState) =
subJourney(state) {
// TODO(PDJB-990): route to the 'provide details about licensing later' page when 'Provide this later' is selected behind the FF: pdjb-939-property-registration-restructure-and-skipping/PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we're not using the feature flag manager in this class - should we be? Or should it be removed?

Comment thread src/main/resources/messages/forms.yml Outdated
licensingType: Licensing type
noLicensing: None
licensingProvideLater: Provide this later
additionalLandlords:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My previous comment has been marked as resolved, but these message keys that don't seem related to the ticket are still here?

null
},
licenseType = state.licensingTypeStep.formModel.notNullValue(LicensingTypeFormModel::licensingType),
licenseType = state.licensingTypeStep.formModelOrNull?.licensingType,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggestion RE making provide later a licensing type would also mean that we can keep the notNullValue here which guards against us registering a property with a licensing type of null

@bnjn-mt

bnjn-mt commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

I've made the suggested changes in this commit @Travis-Softwire @samyou-softwire

@Travis-Softwire Travis-Softwire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great now, thanks for persevering! I've left one Q, and it looks like there are some merge conflicts to resolve. Assuming those are relatively simple then this all LGTM (if they turn out to require some more substantive changes then shout and I can quickly re-review)

routeSegment(ProvideLicensingLaterStep.ROUTE_SEGMENT)
parents { journey.licensingTypeStep.hasOutcome(LicensingTypeMode.PROVIDE_LATER) }
nextStep { exitStep }
savable()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for this step being savable but the others aren't?

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.

3 participants