Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PRSD-642: Landlord Registration Confirmation #103

Merged
merged 27 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ebc9992
PRSD-642: Renames confirmationPageBanner.html title to heading
isobel-softwire Dec 10, 2024
bf6dfea
PRSD-642: Conforms addLAUser.heading message to parameter naming conv…
isobel-softwire Dec 10, 2024
4ea63ef
PRSD-642: Creates registerAsALandlordConfirmation.html
isobel-softwire Dec 10, 2024
be0b86f
PRSD-642: Refactors create landlord function to check if landlord alr…
isobel-softwire Dec 10, 2024
08809d5
PRSD-642: Changes singleLineAddress format
isobel-softwire Dec 11, 2024
9386568
PRSD-642: Adds TODO for updating link to landlord dashboard
isobel-softwire Dec 11, 2024
b1ed099
PRSD-642: Updates LandlordServiceTests for retrieveLandlordByRegNum
isobel-softwire Dec 11, 2024
2b541f1
PRSD-642: Adds Confirmation step to LandlordRegistrationJourney
isobel-softwire Dec 10, 2024
e91fa73
PRSD-642: Updates ConfirmationPageLandlordRegistration
isobel-softwire Dec 11, 2024
e9383b1
PRSD-642: Refactors ErrorPage
isobel-softwire Dec 12, 2024
1e6ea6b
PRSD-642: Updates ConfirmationPageLandlordRegistration
isobel-softwire Dec 12, 2024
fdba708
PRSD-642: Updates Navigator and moves identity verification into it
isobel-softwire Dec 12, 2024
e835a38
PRSD-642: Consolidates LandlordRegistrationJourneyTests and creates t…
isobel-softwire Dec 12, 2024
09aba40
PRSD-642: Refactors Landlord entity
isobel-softwire Dec 12, 2024
d336f96
PRSD-642: Fix linting error
isobel-softwire Dec 12, 2024
1f96943
PRSD-642: Updates RegisterLandlordControllerTests
isobel-softwire Dec 12, 2024
541dffd
PRSD-642: Resyncs id generating sequences after test data input
isobel-softwire Dec 12, 2024
5ffd9e1
PRSD-642: Creates method that turns a RegistrationNumber into a data …
isobel-softwire Dec 12, 2024
852644b
PRSD-642: Refactors LandlordRegistrationJourney.Companion.declaration…
isobel-softwire Dec 12, 2024
a64691d
PRSD-642: Stores Landlord.dateOfBirth as a java LocalDate
isobel-softwire Dec 12, 2024
05a4933
PRSD-642: Annotates TODOs with TICKET numbers
isobel-softwire Dec 13, 2024
44a5cd1
PRSD-642: Fixes error in LandlordRegistrationJourneyTests
isobel-softwire Dec 17, 2024
dccc010
PRSD-642: Makes isContactAddress parameter optional
isobel-softwire Dec 17, 2024
57d0bb9
PRSD-642: Refactors LandlordRegistrationJourney to use LandlordJourne…
isobel-softwire Dec 17, 2024
1a9ba6a
PRSD-642: Fix rebasing error
isobel-softwire Dec 17, 2024
a081691
PRSD-642: Actually fix rebasing error
isobel-softwire Dec 17, 2024
5e67f2c
PRSD-642: Actually fix rebasing error (v2)
isobel-softwire Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import uk.gov.communities.prsdb.webapp.constants.REGISTER_LANDLORD_JOURNEY_URL
import uk.gov.communities.prsdb.webapp.exceptions.PrsdbWebException
import uk.gov.communities.prsdb.webapp.forms.journeys.LandlordRegistrationJourney
import uk.gov.communities.prsdb.webapp.forms.journeys.PageData
import uk.gov.communities.prsdb.webapp.models.dataModels.RegistrationNumberDataModel
import uk.gov.communities.prsdb.webapp.services.LandlordService
import uk.gov.communities.prsdb.webapp.services.OneLoginIdentityService
import java.security.Principal

Expand All @@ -20,6 +23,7 @@ import java.security.Principal
class RegisterLandlordController(
var landlordRegistrationJourney: LandlordRegistrationJourney,
val identityService: OneLoginIdentityService,
val landlordService: LandlordService,
) {
@GetMapping
fun index(model: Model): CharSequence {
Expand Down Expand Up @@ -78,8 +82,26 @@ class RegisterLandlordController(
principal,
)

@GetMapping("/$CONFIRMATION_PAGE_PATH_SEGMENT")
fun getConfirmation(
model: Model,
principal: Principal,
): String {
val landlord =
landlordService.retrieveLandlordByBaseUserId(principal.name)
?: throw PrsdbWebException("User ${principal.name} is not registered as a landlord")

model.addAttribute(
"registrationNumber",
RegistrationNumberDataModel.fromRegistrationNumber(landlord.registrationNumber).toString(),
)

return "registerAsALandlordConfirmation"
}

companion object {
const val START_PAGE_PATH_SEGMENT = "start"
const val IDENTITY_VERIFICATION_PATH_SEGMENT = "verify-identity"
const val CONFIRMATION_PAGE_PATH_SEGMENT = "confirmation"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import jakarta.persistence.Id
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import jakarta.persistence.OneToOne
import java.util.Date
import java.time.LocalDate

@Entity
class Landlord() : ModifiableAuditableEntity() {
Expand Down Expand Up @@ -43,10 +43,10 @@ class Landlord() : ModifiableAuditableEntity() {
lateinit var address: Address
private set

lateinit var internationalAddress: String
var internationalAddress: String? = null
private set

lateinit var dateOfBirth: Date
var dateOfBirth: LocalDate? = null
private set

@OneToOne(optional = false)
Expand All @@ -70,16 +70,16 @@ class Landlord() : ModifiableAuditableEntity() {
address: Address,
registrationNumber: RegistrationNumber,
internationalAddress: String?,
dateOfBirth: Date?,
dateOfBirth: LocalDate?,
) : this() {
this.baseUser = baseUser
this.name = name
this.email = email
this.phoneNumber = phoneNumber
this.address = address
this.registrationNumber = registrationNumber
this.internationalAddress = internationalAddress
this.dateOfBirth = dateOfBirth
this.isActive = true
if (internationalAddress != null) this.internationalAddress = internationalAddress
if (dateOfBirth != null) this.dateOfBirth = dateOfBirth
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import uk.gov.communities.prsdb.webapp.database.entity.Landlord

// The underscore tells JPA to access fields relating to the referenced table
@Suppress("ktlint:standard:function-naming")
interface LandlordRepository : JpaRepository<Landlord?, Long?> {
// The underscore tells JPA to access fields relating to the referenced table
@Suppress("ktlint:standard:function-naming")
fun findByRegistrationNumber_Number(registrationNumber: Long): Landlord?

fun findByBaseUser_Id(subjectId: String): Landlord?

@Query(
"SELECT l.* " +
"FROM landlord l " +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package uk.gov.communities.prsdb.webapp.forms.journeys

import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.stereotype.Component
import org.springframework.validation.Validator
import uk.gov.communities.prsdb.webapp.constants.INTERNATIONAL_ADDRESS_MAX_LENGTH
import uk.gov.communities.prsdb.webapp.constants.MANUAL_ADDRESS_CHOSEN
import uk.gov.communities.prsdb.webapp.constants.PLACE_NAMES
import uk.gov.communities.prsdb.webapp.constants.REGISTER_LANDLORD_JOURNEY_URL
import uk.gov.communities.prsdb.webapp.constants.enums.JourneyType
import uk.gov.communities.prsdb.webapp.controllers.RegisterLandlordController.Companion.CONFIRMATION_PAGE_PATH_SEGMENT
import uk.gov.communities.prsdb.webapp.forms.pages.ConfirmIdentityPage
import uk.gov.communities.prsdb.webapp.forms.pages.LandlordRegistrationSummaryPage
import uk.gov.communities.prsdb.webapp.forms.pages.Page
import uk.gov.communities.prsdb.webapp.forms.pages.SelectAddressPage
import uk.gov.communities.prsdb.webapp.forms.pages.VerifyIdentityPage
import uk.gov.communities.prsdb.webapp.forms.steps.LandlordRegistrationStepId
import uk.gov.communities.prsdb.webapp.forms.steps.Step
import uk.gov.communities.prsdb.webapp.helpers.LandlordJourneyDataHelper
import uk.gov.communities.prsdb.webapp.models.formModels.CheckAnswersFormModel
import uk.gov.communities.prsdb.webapp.models.formModels.CountryOfResidenceFormModel
import uk.gov.communities.prsdb.webapp.models.formModels.DateOfBirthFormModel
Expand All @@ -25,35 +27,35 @@ import uk.gov.communities.prsdb.webapp.models.formModels.ManualAddressFormModel
import uk.gov.communities.prsdb.webapp.models.formModels.NameFormModel
import uk.gov.communities.prsdb.webapp.models.formModels.PhoneNumberFormModel
import uk.gov.communities.prsdb.webapp.models.formModels.SelectAddressFormModel
import uk.gov.communities.prsdb.webapp.models.formModels.VerifiedIdentityModel
import uk.gov.communities.prsdb.webapp.models.viewModels.CheckboxViewModel
import uk.gov.communities.prsdb.webapp.models.viewModels.RadiosButtonViewModel
import uk.gov.communities.prsdb.webapp.models.viewModels.SelectViewModel
import uk.gov.communities.prsdb.webapp.services.AddressDataService
import uk.gov.communities.prsdb.webapp.services.AddressLookupService
import uk.gov.communities.prsdb.webapp.services.JourneyDataService
import java.time.LocalDate
import uk.gov.communities.prsdb.webapp.services.LandlordService

@Component
class LandlordRegistrationJourney(
validator: Validator,
journeyDataService: JourneyDataService,
addressLookupService: AddressLookupService,
addressDataService: AddressDataService,
landlordService: LandlordService,
) : Journey<LandlordRegistrationStepId>(
journeyType = JourneyType.LANDLORD_REGISTRATION,
initialStepId = LandlordRegistrationStepId.VerifyIdentity,
validator = validator,
journeyDataService = journeyDataService,
steps =
setOf(
verifyIdentityStep(),
verifyIdentityStep(journeyDataService),
nameStep(),
dateOfBirthStep(),
confirmIdentityStep(journeyDataService),
emailStep(),
phoneNumberStep(),
countryOfResidenceStep(),
countryOfResidenceStep(journeyDataService),
lookupAddressStep(),
selectAddressStep(journeyDataService, addressLookupService, addressDataService),
manualAddressStep(),
Expand All @@ -62,16 +64,16 @@ class LandlordRegistrationJourney(
selectContactAddressStep(journeyDataService, addressLookupService, addressDataService),
manualContactAddressStep(),
checkAnswersStep(),
declarationStep(),
declarationStep(journeyDataService, landlordService, addressDataService),
),
) {
companion object {
private fun verifyIdentityStep() =
private fun verifyIdentityStep(journeyDataService: JourneyDataService) =
Step(
id = LandlordRegistrationStepId.VerifyIdentity,
page = VerifyIdentityPage(),
nextAction = { journeyData, _ ->
if (doesJourneyDataContainVerifiedIdentity(journeyData)) {
if (LandlordJourneyDataHelper.isIdentityVerified(journeyDataService, journeyData)) {
Pair(LandlordRegistrationStepId.ConfirmIdentity, null)
} else {
Pair(LandlordRegistrationStepId.Name, null)
Expand Down Expand Up @@ -184,7 +186,7 @@ class LandlordRegistrationJourney(
saveAfterSubmit = false,
)

private fun countryOfResidenceStep() =
private fun countryOfResidenceStep(journeyDataService: JourneyDataService) =
Step(
id = LandlordRegistrationStepId.CountryOfResidence,
page =
Expand Down Expand Up @@ -212,7 +214,7 @@ class LandlordRegistrationJourney(
),
),
),
nextAction = { journeyData, _ -> countryOfResidenceNextAction(journeyData) },
nextAction = { journeyData, _ -> countryOfResidenceNextAction(journeyData, journeyDataService) },
saveAfterSubmit = false,
)

Expand Down Expand Up @@ -292,7 +294,6 @@ class LandlordRegistrationJourney(
"submitButtonText" to "forms.buttons.continue",
),
),
// TODO: Set nextAction to next journey step
nextAction = { _, _ -> Pair(LandlordRegistrationStepId.CheckAnswers, null) },
saveAfterSubmit = false,
)
Expand All @@ -314,7 +315,6 @@ class LandlordRegistrationJourney(
"submitButtonText" to "forms.buttons.continue",
),
),
// TODO: Set nextAction to next journey step
nextAction = { _, _ -> Pair(LandlordRegistrationStepId.LookupContactAddress, null) },
saveAfterSubmit = false,
)
Expand Down Expand Up @@ -393,7 +393,6 @@ class LandlordRegistrationJourney(
"submitButtonText" to "forms.buttons.continue",
),
),
// TODO: Set nextAction to next journey step
nextAction = { _, _ -> Pair(LandlordRegistrationStepId.CheckAnswers, null) },
saveAfterSubmit = false,
)
Expand All @@ -417,82 +416,103 @@ class LandlordRegistrationJourney(
saveAfterSubmit = false,
)

private fun declarationStep() =
Step(
id = LandlordRegistrationStepId.Declaration,
page =
Page(
formModel = DeclarationFormModel::class,
templateName = "forms/declarationForm",
content =
mapOf(
"title" to "registerAsALandlord.title",
"options" to
listOf(
CheckboxViewModel(
value = "true",
labelMsgKey = "forms.declaration.checkbox.label",
),
private fun declarationStep(
journeyDataService: JourneyDataService,
landlordService: LandlordService,
addressDataService: AddressDataService,
) = Step(
id = LandlordRegistrationStepId.Declaration,
page =
Page(
formModel = DeclarationFormModel::class,
templateName = "forms/declarationForm",
content =
mapOf(
"title" to "registerAsALandlord.title",
"options" to
listOf(
CheckboxViewModel(
value = "true",
labelMsgKey = "forms.declaration.checkbox.label",
),
"submitButtonText" to "forms.buttons.confirmAndCompleteRegistration",
),
),
nextAction = { _, _ -> Pair(LandlordRegistrationStepId.Confirmation, null) },
saveAfterSubmit = false,
)

private fun countryOfResidenceNextAction(journeyData: JourneyData): Pair<LandlordRegistrationStepId, Int?> =
when (
val livesInUK =
objectToStringKeyedMap(journeyData[LandlordRegistrationStepId.CountryOfResidence.urlPathSegment])
?.get("livesInUK")
.toString()
) {
"true" -> Pair(LandlordRegistrationStepId.LookupAddress, null)
"false" -> Pair(LandlordRegistrationStepId.InternationalAddress, null)
else -> throw IllegalArgumentException(
"Invalid value for journeyData[\"${LandlordRegistrationStepId.CountryOfResidence.urlPathSegment}\"][\"livesInUK\"]:" +
livesInUK,
),
"submitButtonText" to "forms.buttons.confirmAndCompleteRegistration",
),
),
handleSubmitAndRedirect = { journeyData, _ ->
declarationHandleSubmitAndRedirect(
journeyData,
journeyDataService,
landlordService,
addressDataService,
)
},
saveAfterSubmit = false,
)

private fun countryOfResidenceNextAction(
journeyData: JourneyData,
journeyDataService: JourneyDataService,
): Pair<LandlordRegistrationStepId, Int?> =
if (LandlordJourneyDataHelper.getLivesInUK(journeyDataService, journeyData)!!) {
Pair(LandlordRegistrationStepId.LookupAddress, null)
} else {
Pair(LandlordRegistrationStepId.InternationalAddress, null)
}

private fun selectAddressNextAction(
journeyData: JourneyData,
journeyDataService: JourneyDataService,
): Pair<LandlordRegistrationStepId, Int?> =
if (journeyDataService.getFieldStringValue(
journeyData,
LandlordRegistrationStepId.SelectAddress.urlPathSegment,
"address",
) == MANUAL_ADDRESS_CHOSEN
) {
if (LandlordJourneyDataHelper.isManualAddressChosen(journeyDataService, journeyData)) {
Pair(LandlordRegistrationStepId.ManualAddress, null)
} else {
// TODO: Set nextAction to next journey step
Pair(LandlordRegistrationStepId.CheckAnswers, null)
}

private fun selectContactAddressNextAction(
journeyData: JourneyData,
journeyDataService: JourneyDataService,
): Pair<LandlordRegistrationStepId, Int?> =
if (journeyDataService.getFieldStringValue(
if (LandlordJourneyDataHelper.isManualAddressChosen(
journeyDataService,
journeyData,
LandlordRegistrationStepId.SelectContactAddress.urlPathSegment,
"address",
) == MANUAL_ADDRESS_CHOSEN
isContactAddress = true,
)
) {
Pair(LandlordRegistrationStepId.ManualContactAddress, null)
} else {
// TODO: Set nextAction to next journey step
Pair(LandlordRegistrationStepId.CheckAnswers, null)
}

private fun doesJourneyDataContainVerifiedIdentity(journeyData: JourneyData): Boolean {
val pageData =
objectToStringKeyedMap(journeyData[LandlordRegistrationStepId.VerifyIdentity.urlPathSegment]) ?: mapOf()
return pageData[VerifiedIdentityModel.NAME_KEY] is String &&
pageData[VerifiedIdentityModel.BIRTH_DATE_KEY] is LocalDate
private fun declarationHandleSubmitAndRedirect(
journeyData: JourneyData,
journeyDataService: JourneyDataService,
landlordService: LandlordService,
addressDataService: AddressDataService,
): String {
landlordService.createLandlord(
baseUserId = SecurityContextHolder.getContext().authentication.name,
name = LandlordJourneyDataHelper.getName(journeyDataService, journeyData)!!,
email = LandlordJourneyDataHelper.getEmail(journeyDataService, journeyData)!!,
phoneNumber = LandlordJourneyDataHelper.getPhoneNumber(journeyDataService, journeyData)!!,
addressDataModel =
LandlordJourneyDataHelper.getAddress(
journeyDataService,
journeyData,
addressDataService,
)!!,
internationalAddress =
LandlordJourneyDataHelper.getInternationalAddress(
journeyDataService,
journeyData,
),
dateOfBirth = LandlordJourneyDataHelper.getDOB(journeyDataService, journeyData)!!,
)

journeyDataService.clearJourneyDataFromSession()

return "/$REGISTER_LANDLORD_JOURNEY_URL/$CONFIRMATION_PAGE_PATH_SEGMENT"
isobel-softwire marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,4 @@ enum class LandlordRegistrationStepId(
ManualContactAddress("manual-contact-address"),
CheckAnswers("check-answers"),
Declaration("declaration"),
Confirmation("confirmation"),
}
Loading
Loading