Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -65,20 +65,10 @@ class LandlordController @Inject()(view: LandlordView,
.bindFromRequest()
.fold(
formWithErrors =>
val correctedFormErrors = formWithErrors.errors.map { formError =>
(formError.key, formError.messages) match
case ("", messages) if messages.contains("landlord.radio.emptyText.error") =>
formError.copy(key = "landlord-relationship")
case ("", messages) if messages.contains("landlord.radio.tooLong.error") =>
formError.copy(key = "landlord-relationship")
case _ =>
formError
}
val formWithCorrectedErrors = formWithErrors.copy(errors = correctedFormErrors)
Future.successful(BadRequest(view(
selectedPropertyAddress = request.property.addressFull,
formWithCorrectedErrors,
buildRadios(formWithErrors, LandlordForm.landlordRadio(formWithCorrectedErrors, ngrCharacterCountComponent)),
formWithErrors,
buildRadios(formWithErrors, LandlordForm.landlordRadio(formWithErrors, ngrCharacterCountComponent)),
mode
))),
landlordForm =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,14 @@ class WhatIsYourRentBasedOnController @Inject()(view: WhatIsYourRentBasedOnView,
buildRadios(formWithErrors, ngrRadio(formWithCorrectedErrors)), request.property.addressFull, mode))),
rentBasedOnForm =>
for {
updatedAnswers <- Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.credId)).set(WhatIsYourRentBasedOnPage, RentBasedOn(rentBasedOnForm.radioValue,rentBasedOnForm.rentBasedOnOther)))
updatedAnswers <- Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.credId))
.set(WhatIsYourRentBasedOnPage,
RentBasedOn(rentBasedOnForm.radioValue,
if (rentBasedOnForm.radioValue == "Other")
rentBasedOnForm.rentBasedOnOther
else
None
)))
_ <- sessionRepository.set(updatedAnswers)
} yield Redirect(navigator.nextPage(WhatIsYourRentBasedOnPage, mode, updatedAnswers))
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright 2025 HM Revenue & Customs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.gov.hmrc.ngrraldfrontend.controllers

import play.api.i18n.I18nSupport
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, DataRetrievalAction}
import uk.gov.hmrc.ngrraldfrontend.config.AppConfig
import uk.gov.hmrc.ngrraldfrontend.models.components.NGRRadio.buildRadios
import uk.gov.hmrc.ngrraldfrontend.models.forms.WhatYourRentIncludesForm
import uk.gov.hmrc.ngrraldfrontend.models.forms.WhatYourRentIncludesForm.{answerToForm, form, formToAnswers}
import uk.gov.hmrc.ngrraldfrontend.models.{Mode, UserAnswers, WhatYourRentIncludes}
import uk.gov.hmrc.ngrraldfrontend.navigation.Navigator
import uk.gov.hmrc.ngrraldfrontend.pages.{WhatIsYourRentBasedOnPage, WhatYourRentIncludesPage}
import uk.gov.hmrc.ngrraldfrontend.repo.SessionRepository
import uk.gov.hmrc.ngrraldfrontend.views.html.WhatYourRentIncludesView
import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendController

import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class WhatRentIncludesRatesWaterServiceController @Inject()(whatYourRentIncludesView: WhatYourRentIncludesView,
authenticate: AuthRetrievals,
inputText: InputText,
getData: DataRetrievalAction,
sessionRepository: SessionRepository,
navigator: Navigator,
mcc: MessagesControllerComponents)(implicit appConfig: AppConfig, ec: ExecutionContext)
extends FrontendController(mcc) with I18nSupport {

def show(mode: Mode): Action[AnyContent] = {
(authenticate andThen getData).async { implicit request =>
val preparedForm = request.userAnswers.getOrElse(UserAnswers(request.credId)).get(WhatYourRentIncludesPage) match {
case Some(value) => answerToForm(value, isOTCLease = true)
case None => form(isOTCLease = true)
}
Future.successful(Ok(whatYourRentIncludesView(
form = preparedForm,
radios1 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio1(preparedForm, inputText)),
radios2 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio2),
radios3 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio3),
radios4 = None,
radios5 = None,
radios6 = None,
propertyAddress = request.property.addressFull,
mode = mode
)))
}
}

def submit(mode: Mode): Action[AnyContent] =
(authenticate andThen getData).async { implicit request =>
form(isOTCLease = true).bindFromRequest().fold(
formWithErrors => {
Future.successful(BadRequest(whatYourRentIncludesView(
form = formWithErrors,
radios1 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio1(formWithErrors, inputText)),
radios2 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio2),
radios3 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio3),
radios4 = None,
radios5 = None,
radios6 = None,
propertyAddress = request.property.addressFull,
mode = mode
)))
},
whatYourRentIncludesForm =>
for {
updatedAnswers <- Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.credId))
.set(WhatYourRentIncludesPage, formToAnswers(whatYourRentIncludesForm, isOTCLease = true)))
_ <- sessionRepository.set(updatedAnswers)
} yield Redirect(navigator.nextPage(WhatYourRentIncludesPage, mode, updatedAnswers))
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ import uk.gov.hmrc.ngrraldfrontend.models.forms.WhatTypeOfAgreementForm
import uk.gov.hmrc.ngrraldfrontend.models.forms.WhatTypeOfAgreementForm.form
import uk.gov.hmrc.ngrraldfrontend.models.{Mode, UserAnswers}
import uk.gov.hmrc.ngrraldfrontend.navigation.Navigator
import uk.gov.hmrc.ngrraldfrontend.pages.WhatTypeOfAgreementPage
import uk.gov.hmrc.ngrraldfrontend.pages.{WhatIsYourRentBasedOnPage, WhatTypeOfAgreementPage}
import uk.gov.hmrc.ngrraldfrontend.repo.SessionRepository
import uk.gov.hmrc.ngrraldfrontend.views.html.WhatTypeOfAgreementView
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendController

import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try

@Singleton
class WhatTypeOfAgreementController @Inject()(view: WhatTypeOfAgreementView,
Expand Down Expand Up @@ -77,8 +78,12 @@ class WhatTypeOfAgreementController @Inject()(view: WhatTypeOfAgreementView,
for {
updatedAnswers <- Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.credId))
.set(WhatTypeOfAgreementPage, whatTypeOfAgreementForm.radioValue))
_ <- sessionRepository.set(updatedAnswers)
} yield Redirect(navigator.nextPage(WhatTypeOfAgreementPage,mode,updatedAnswers))
//Remove Rent Based on answer if agreement type is verbal
newAnswers <- whatTypeOfAgreementForm.radioValue match
case "Verbal" => Future(updatedAnswers.remove(WhatIsYourRentBasedOnPage))
case _ => Future(Try(updatedAnswers))
_ <- sessionRepository.set(newAnswers.get)
} yield Redirect(navigator.nextPage(WhatTypeOfAgreementPage,mode,newAnswers.get))
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ class WhatYourRentIncludesController @Inject()(whatYourRentIncludesView: WhatYou
def show(mode: Mode): Action[AnyContent] = {
(authenticate andThen getData).async { implicit request =>
val preparedForm = request.userAnswers.getOrElse(UserAnswers(request.credId)).get(WhatYourRentIncludesPage) match {
case Some(value) => answerToForm(value)
case None => form
case Some(value) => answerToForm(value, isOTCLease = false)
case None => form(isOTCLease = false)
}
Future.successful(Ok(whatYourRentIncludesView(
form = preparedForm,
radios1 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio1(preparedForm, inputText)),
radios2 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio2),
radios3 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio3),
radios4 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio4),
radios5 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio5),
radios6 = buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio6),
radios4 = Some(buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio4)),
radios5 = Some(buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio5)),
radios6 = Some(buildRadios(preparedForm, WhatYourRentIncludesForm.ngrRadio6)),
propertyAddress = request.property.addressFull,
mode = mode
)))
Expand All @@ -66,31 +66,24 @@ class WhatYourRentIncludesController @Inject()(whatYourRentIncludesView: WhatYou

def submit(mode: Mode): Action[AnyContent] =
(authenticate andThen getData).async { implicit request =>
form.bindFromRequest().fold(
form(isOTCLease = false).bindFromRequest().fold(
formWithErrors => {
val correctedFormErrors = formWithErrors.errors.map { formError =>
(formError.key, formError.messages) match
case ("", messages) =>
formError.copy(key = "bedroomNumbers")
case _ => formError
}
val formWithCorrectedErrors = formWithErrors.copy(errors = correctedFormErrors)
Future.successful(BadRequest(whatYourRentIncludesView(
form = formWithCorrectedErrors,
radios1 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio1(formWithCorrectedErrors, inputText)),
form = formWithErrors,
radios1 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio1(formWithErrors, inputText)),
radios2 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio2),
radios3 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio3),
radios4 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio4),
radios5 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio5),
radios6 = buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio6),
radios4 = Some(buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio4)),
radios5 = Some(buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio5)),
radios6 = Some(buildRadios(formWithErrors, WhatYourRentIncludesForm.ngrRadio6)),
propertyAddress = request.property.addressFull,
mode = mode
)))
},
whatYourRentIncludesForm =>
for {
updatedAnswers <- Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.credId))
.set(WhatYourRentIncludesPage, formToAnswers(whatYourRentIncludesForm)))
.set(WhatYourRentIncludesPage, formToAnswers(whatYourRentIncludesForm, isOTCLease = false)))
_ <- sessionRepository.set(updatedAnswers)
} yield Redirect(navigator.nextPage(WhatYourRentIncludesPage, mode, updatedAnswers))
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ case class WhatYourRentIncludes(
livingAccommodation: Boolean,
rentPartAddress: Boolean,
rentEmptyShell: Boolean,
rentIncBusinessRates: Boolean,
rentIncWaterCharges: Boolean,
rentIncService: Boolean,
rentIncBusinessRates: Option[Boolean],
rentIncWaterCharges: Option[Boolean],
rentIncService: Option[Boolean],
bedroomNumbers: Option[Int]
)

Expand Down
56 changes: 26 additions & 30 deletions app/uk/gov/hmrc/ngrraldfrontend/models/forms/LandlordForm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

package uk.gov.hmrc.ngrraldfrontend.models.forms

import play.api.data.Form
import play.api.data.Forms.{mapping, optional, text}
import play.api.data.{Form, FormError}
import play.api.data.Forms.{mapping, optional, text, of}
import play.api.data.format.Formatter
import play.api.data.validation.{Constraint, Invalid, Valid}
import play.api.i18n.*
import play.api.libs.json.{Json, OFormat}
Expand All @@ -39,7 +40,7 @@ object LandlordForm extends CommonFormValidators with Mappings{
private lazy val landlordNameEmptyError = "landlord.name.empty.error"
private lazy val landlordNameTooLongError = "landlord.name.empty.tooLong.error"
private lazy val radioUnselectedError = "landlord.radio.empty.error"
private lazy val landlordRelationshipEmptyError = "landlord.radio.emptyText.error"
private lazy val landlordRelationshipEmptyError = "landlord.relationship.empty.error"
private lazy val landlordRelationshipTooLongError = "landlord.radio.tooLong.error"

private val landlord = "landlord-name-value"
Expand Down Expand Up @@ -96,24 +97,28 @@ object LandlordForm extends CommonFormValidators with Mappings{
landlordForm.hasRelationship.toBoolean,
if (landlordForm.hasRelationship.toBoolean) landlordForm.landlordRelationship else None
)

private def isLandlordRelationshipTextEmpty[A]: Constraint[A] =
Constraint((input: A) =>
val landlordForm = input.asInstanceOf[LandlordForm]
if (landlordForm.hasRelationship.equals("true") && landlordForm.landlordRelationship.getOrElse("").isBlank)
Invalid(landlordRelationshipEmptyError)
else
Valid
)

private def isLandlordRelationshipTextMaxLength[A]: Constraint[A] =
Constraint((input: A) =>
val landlordForm = input.asInstanceOf[LandlordForm]
if (landlordForm.hasRelationship.equals("true") && landlordForm.landlordRelationship.getOrElse("").length > 250)
Invalid(landlordRelationshipTooLongError)
else
Valid
)
private def relationshipFormatter(args: Seq[String] = Seq.empty): Formatter[Option[String]] = new Formatter[Option[String]] {
override def bind(key: String, data: Map[String, String]): Either[Seq[FormError], Option[String]] =
val hasRelationship = data.get(landlordRadio).exists(_ == "true")
data.get(key) match {
case None if hasRelationship => Left(Seq(FormError(key, landlordRelationshipEmptyError, args)))
case Some(s) if hasRelationship => isLandlordRelationshipValid(s.trim, key, args)
case Some(s) => Right(Some(s))
case None => Right(None)
}

override def unbind(key: String, value: Option[String]): Map[String, String] =
Map(key -> value.getOrElse(""))
}

private def isLandlordRelationshipValid(relationship: String, key: String, args: Seq[String] = Seq.empty): Either[Seq[FormError], Option[String]] =
if (relationship.isEmpty)
Left(Seq(FormError(key, landlordRelationshipEmptyError, args)))
else if (relationship.length > 250)
Left(Seq(FormError(key, landlordRelationshipTooLongError, args)))
else
Right(Some(relationship))

def form: Form[LandlordForm] = {
Form(
Expand All @@ -127,17 +132,8 @@ object LandlordForm extends CommonFormValidators with Mappings{

),
landlordRadio -> radioText(radioUnselectedError),
landlordRelationshipYes -> optional(
play.api.data.Forms.text
.transform[String](_.strip(), identity)
)
landlordRelationshipYes -> of(relationshipFormatter())
)(LandlordForm.apply)(LandlordForm.unapply)
.verifying(
firstError(
isLandlordRelationshipTextEmpty,
isLandlordRelationshipTextMaxLength
)
)
)
}
}
Loading