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-689: Creates UpdateJourney base class #239

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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 @@ -17,7 +17,6 @@ import uk.gov.communities.prsdb.webapp.constants.UPDATE_PATH_SEGMENT
import uk.gov.communities.prsdb.webapp.exceptions.PrsdbWebException
import uk.gov.communities.prsdb.webapp.forms.journeys.PageData
import uk.gov.communities.prsdb.webapp.forms.journeys.UpdateLandlordDetailsJourney
import uk.gov.communities.prsdb.webapp.forms.steps.UpdateLandlordDetailsStepId
import uk.gov.communities.prsdb.webapp.helpers.DateTimeHelper
import uk.gov.communities.prsdb.webapp.models.viewModels.summaryModels.LandlordViewModel
import uk.gov.communities.prsdb.webapp.services.AddressDataService
Expand All @@ -39,14 +38,12 @@ class LandlordDetailsController(
model: Model,
principal: Principal,
): String {
updateDetailsJourney.initialiseJourneyDataIfNotInitialised(principal.name)
addLandlordDetailsToModel(model, principal, includeChangeLinks = true)
// TODO: PRSD-355 Remove this way of showing submit button
model.addAttribute("shouldShowSubmitButton", true)
addLandlordDetailsToModel(model, principal, includeChangeLinks = true)
return updateDetailsJourney.populateModelAndGetViewName(
UpdateLandlordDetailsStepId.UpdateDetails,
model,
null,
return updateDetailsJourney.populateModelAndGetViewNameForUpdateStep(
updateEntityId = principal.name,
model = model,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ abstract class Journey<T : StepId>(

protected abstract val journeyPathSegment: String

protected val defaultJourneyDataKey = journeyType.name

fun getStepId(stepName: String): T {
val step = steps.singleOrNull { step -> step.id.urlPathSegment == stepName }
if (step == null) {
Expand All @@ -44,7 +46,7 @@ abstract class Journey<T : StepId>(
principalName: String,
journeyDataKey: String? = null,
) {
val data = journeyDataService.getJourneyDataFromSession(journeyDataKeyOrDefault(journeyDataKey))
val data = journeyDataService.getJourneyDataFromSession(journeyDataKey ?: defaultJourneyDataKey)
if (data.isEmpty()) {
/* TODO PRSD-589 Currently this looks the context up from the database,
takes the id, then passes the id to another method which retrieves it
Expand All @@ -58,14 +60,14 @@ abstract class Journey<T : StepId>(
}

fun populateModelAndGetViewName(
stepId: StepId,
stepId: T,
model: Model,
subPageNumber: Int?,
submittedPageData: PageData? = null,
journeyDataKey: String? = null,
): String {
val journeyData: JourneyData =
journeyDataService.getJourneyDataFromSession(journeyDataKeyOrDefault(journeyDataKey))
journeyDataService.getJourneyDataFromSession(journeyDataKey ?: defaultJourneyDataKey)
val requestedStep = getStep(stepId)
if (!isStepReachable(requestedStep, subPageNumber)) {
return "redirect:${getUnreachableStepRedirect(journeyData)}"
Expand Down Expand Up @@ -95,12 +97,17 @@ abstract class Journey<T : StepId>(
principal: Principal,
journeyDataKey: String? = null,
): String {
val journeyDataKeyOrDefault = journeyDataKeyOrDefault(journeyDataKey)
val journeyData = journeyDataService.getJourneyDataFromSession(journeyDataKeyOrDefault)
val journeyData = journeyDataService.getJourneyDataFromSession(journeyDataKey ?: defaultJourneyDataKey)

val currentStep = getStep(stepId)
if (!currentStep.isSatisfied(validator, pageData)) {
return populateModelAndGetViewName(stepId, model, subPageNumber, pageData, journeyDataKeyOrDefault)
return populateModelAndGetViewName(
stepId,
model,
subPageNumber,
pageData,
journeyDataKey ?: defaultJourneyDataKey,
)
}

val newJourneyData = currentStep.updatedJourneyData(journeyData, pageData, subPageNumber)
Expand All @@ -114,7 +121,7 @@ abstract class Journey<T : StepId>(
if (currentStep.handleSubmitAndRedirect != null) {
return "redirect:${currentStep.handleSubmitAndRedirect!!(newJourneyData, subPageNumber)}"
}
val (newStepId: StepId?, newSubPageNumber: Int?) = currentStep.nextAction(newJourneyData, subPageNumber)
val (newStepId: T?, newSubPageNumber: Int?) = currentStep.nextAction(newJourneyData, subPageNumber)
if (newStepId == null) {
throw IllegalStateException("Cannot compute next step from step ${currentStep.id.urlPathSegment}")
}
Expand Down Expand Up @@ -143,13 +150,11 @@ abstract class Journey<T : StepId>(

protected open fun getUnreachableStepRedirect(journeyData: JourneyData) = initialStepId.urlPathSegment

protected fun <T : StepId> createSingleSectionWithSingleTaskFromSteps(
protected fun createSingleSectionWithSingleTaskFromSteps(
initialStepId: T,
steps: Set<Step<T>>,
): List<JourneySection<T>> = listOf(JourneySection.withOneTask(JourneyTask(initialStepId, steps)))

protected fun journeyDataKeyOrDefault(journeyDataKey: String?) = journeyDataKey ?: journeyType.name

private fun getSectionHeaderInfo(step: Step<T>): SectionHeaderViewModel? {
val sectionContainingStep = sections.single { it.isStepInSection(step.id) }
if (sectionContainingStep.headingKey == null) {
Expand All @@ -162,7 +167,7 @@ abstract class Journey<T : StepId>(
)
}

private fun getStep(stepId: StepId) =
private fun getStep(stepId: T) =
steps.singleOrNull { step -> step.id == stepId }
?: throw ResponseStatusException(
HttpStatus.NOT_FOUND,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ abstract class JourneyWithTaskList<T : StepId>(
model: Model,
journeyDataKey: String? = null,
): String {
val journeyData = journeyDataService.getJourneyDataFromSession(journeyDataKeyOrDefault(journeyDataKey))
val journeyData = journeyDataService.getJourneyDataFromSession(journeyDataKey ?: defaultJourneyDataKey)
model.addAttribute("taskListViewModel", taskListFactory.getTaskListViewModel(journeyData))
return "taskList"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class LaUserRegistrationJourney(
override val journeyPathSegment = REGISTER_LA_USER_JOURNEY_URL

fun initialiseJourneyData(token: String) {
val journeyData = journeyDataService.getJourneyDataFromSession(journeyType.name)
val journeyData = journeyDataService.getJourneyDataFromSession(defaultJourneyDataKey)
val formData: PageData = mapOf("emailAddress" to invitationService.getEmailAddressForToken(token))
val emailStep = steps.single { step -> step.id == RegisterLaUserStepId.Email }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.communities.prsdb.webapp.forms.journeys

import org.springframework.ui.Model
import org.springframework.validation.Validator
import uk.gov.communities.prsdb.webapp.constants.enums.JourneyType
import uk.gov.communities.prsdb.webapp.forms.steps.StepDetails
Expand All @@ -12,12 +13,33 @@ abstract class UpdateJourney<T : StepId>(
validator: Validator,
journeyDataService: JourneyDataService,
) : Journey<T>(journeyType, validator, journeyDataService) {
abstract val updateStepId: StepId
abstract val updateStepId: T

protected val originalDataKey = "ORIGINAL_$journeyType.name"
private val originalDataKey = "ORIGINAL_${journeyType.name}"

protected abstract fun createOriginalJourneyData(updateEntityId: String): JourneyData

protected open fun initialiseJourneyDataIfNotInitialised(updateEntityId: String) {
val journeyData = journeyDataService.getJourneyDataFromSession(defaultJourneyDataKey)
if (!isJourneyDataInitialised(journeyData)) {
val newJourneyData = journeyData + (originalDataKey to createOriginalJourneyData(updateEntityId))
journeyDataService.setJourneyDataInSession(newJourneyData)
}
}

fun populateModelAndGetViewNameForUpdateStep(
updateEntityId: String,
model: Model,
subPageNumber: Int? = null,
submittedPageData: PageData? = null,
journeyDataKey: String? = null,
): String {
initialiseJourneyDataIfNotInitialised(updateEntityId)
return super.populateModelAndGetViewName(updateStepId, model, subPageNumber, submittedPageData, journeyDataKey)
}

override fun getUnreachableStepRedirect(journeyData: JourneyData) =
if (journeyData[originalDataKey] == null) {
if (!isJourneyDataInitialised(journeyData)) {
updateStepId.urlPathSegment
} else {
last().step.id.urlPathSegment
Expand All @@ -38,4 +60,6 @@ abstract class UpdateJourney<T : StepId>(

return ReachableStepDetailsIterator(updatedData, steps, initialStepId, validator)
}

private fun isJourneyDataInitialised(journeyData: JourneyData): Boolean = journeyData.containsKey(originalDataKey)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import uk.gov.communities.prsdb.webapp.constants.UPDATE_LANDLORD_DETAILS_URL
import uk.gov.communities.prsdb.webapp.constants.enums.JourneyType
import uk.gov.communities.prsdb.webapp.controllers.LandlordDetailsController
import uk.gov.communities.prsdb.webapp.database.entity.Address
import uk.gov.communities.prsdb.webapp.database.entity.Landlord
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.steps.Step
Expand Down Expand Up @@ -42,7 +41,7 @@ class UpdateLandlordDetailsJourney(
validator = validator,
journeyDataService = journeyDataService,
) {
override val initialStepId = UpdateLandlordDetailsStepId.UpdateEmail
final override val initialStepId = UpdateLandlordDetailsStepId.UpdateEmail
override val updateStepId = UpdateLandlordDetailsStepId.UpdateDetails

override val journeyPathSegment: String = UPDATE_LANDLORD_DETAILS_URL
Expand Down Expand Up @@ -244,18 +243,9 @@ class UpdateLandlordDetailsJourney(
return LandlordDetailsController.LANDLORD_DETAILS_ROUTE
}

fun initialiseJourneyDataIfNotInitialised(landlordId: String) {
val journeyData = journeyDataService.getJourneyDataFromSession(journeyType.name)
if (!journeyData.containsKey(originalDataKey)) {
val landlord = landlordService.retrieveLandlordByBaseUserId(landlordId)!!
val newJourneyData =
journeyData + (originalDataKey to createOriginalLandlordJourneyData(landlord))
journeyDataService.setJourneyDataInSession(newJourneyData)
addressDataService.setAddressData(listOf(AddressDataModel.fromAddress(landlord.address)))
}
}
override fun createOriginalJourneyData(updateEntityId: String): JourneyData {
val landlord = landlordService.retrieveLandlordByBaseUserId(updateEntityId)!!

private fun createOriginalLandlordJourneyData(landlord: Landlord): JourneyData {
val originalLandlordData =
mutableMapOf(
UpdateLandlordDetailsStepId.UpdateEmail.urlPathSegment to mapOf("emailAddress" to landlord.email),
Expand All @@ -280,9 +270,19 @@ class UpdateLandlordDetailsJourney(
"postcode" to landlord.address.getPostcodeSearchTerm(),
)
}

return originalLandlordData
}

override fun initialiseJourneyDataIfNotInitialised(updateEntityId: String) {
super.initialiseJourneyDataIfNotInitialised(updateEntityId)

val landlord = landlordService.retrieveLandlordByBaseUserId(updateEntityId)!!
if (addressDataService.getAddressData(landlord.address.singleLineAddress) == null) {
addressDataService.setAddressData(listOf(AddressDataModel.fromAddress(landlord.address)))
}
}

private fun Address.getHouseNameOrNumber(): String = buildingName ?: buildingNumber ?: singleLineAddress

private fun Address.getPostcodeSearchTerm(): String = postcode ?: singleLineAddress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,27 @@ class JourneyDataService(
return getJourneyDataFromSession()
}

fun getJourneyDataFromSession(): JourneyData = objectToStringKeyedMap(session.getAttribute(journeyDataKey)) ?: mapOf()
fun getJourneyDataFromSession(): JourneyData =
try {
objectToStringKeyedMap(session.getAttribute(journeyDataKey)) ?: mapOf()
} catch (exception: UninitializedPropertyAccessException) {
throw PrsdbWebException("journeyDataKey has not been set")
}

fun setJourneyDataInSession(journeyData: JourneyData) {
session.setAttribute(journeyDataKey, journeyData)
try {
session.setAttribute(journeyDataKey, journeyData)
} catch (exception: UninitializedPropertyAccessException) {
throw PrsdbWebException("journeyDataKey has not been set")
}
}

fun clearJourneyDataFromSession() {
session.setAttribute(journeyDataKey, null)
try {
session.setAttribute(journeyDataKey, null)
} catch (exception: UninitializedPropertyAccessException) {
throw PrsdbWebException("journeyDataKey has not been set")
}
}

fun getContextId(): Long? = session.getAttribute("contextId") as? Long
Expand Down
Loading