diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala
index 2a8d9ad6..a3fa14c3 100644
--- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala
+++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala
@@ -16,7 +16,7 @@
package uk.gov.hmrc.ngrraldfrontend.controllers
-import play.api.data.{Form, FormError, Forms}
+import play.api.data.{Form, FormError}
import play.api.i18n.{I18nSupport, Messages}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import play.twirl.api.HtmlFormat
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala
new file mode 100644
index 00000000..03e60268
--- /dev/null
+++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala
@@ -0,0 +1,102 @@
+/*
+ * 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.data.Form
+import play.api.i18n.{I18nSupport, Messages}
+import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
+import play.twirl.api.HtmlFormat
+import uk.gov.hmrc.govukfrontend.views.Aliases.{Hint, PrefixOrSuffix, Text}
+import uk.gov.hmrc.http.NotFoundException
+import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, PropertyLinkingAction}
+import uk.gov.hmrc.ngrraldfrontend.config.AppConfig
+import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm
+import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm.form
+import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId
+import uk.gov.hmrc.ngrraldfrontend.repo.RaldRepo
+import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView
+import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText
+import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendController
+
+import javax.inject.Inject
+import scala.concurrent.{ExecutionContext, Future}
+
+class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: InterimRentSetByTheCourtView,
+ authenticate: AuthRetrievals,
+ hasLinkedProperties: PropertyLinkingAction,
+ inputText: InputText,
+ raldRepo: RaldRepo,
+ mcc: MessagesControllerComponents)(implicit appConfig: AppConfig, ec: ExecutionContext)
+ extends FrontendController(mcc) with I18nSupport {
+
+ def generateInputText(form: Form[InterimRentSetByTheCourtForm], inputFieldName: String)(implicit messages: Messages): HtmlFormat.Appendable = {
+ inputText(
+ form = form,
+ id = inputFieldName,
+ name = inputFieldName,
+ label = messages(s"interimRentSetByTheCourt.label.1"),
+ headingMessageArgs = Seq("govuk-fieldset__legend govuk-fieldset__legend--s"),
+ isPageHeading = true,
+ isVisible = true,
+ classes = Some("govuk-input govuk-input--width-5"),
+ prefix = Some(PrefixOrSuffix(content = Text("£")))
+ )
+ }
+
+ def show: Action[AnyContent] = {
+ (authenticate andThen hasLinkedProperties).async { implicit request =>
+ request.propertyLinking.map(property =>
+ Future.successful(Ok(interimRentSetByTheCourtView(
+ form = form,
+ propertyAddress = property.addressFull,
+ interimAmount = generateInputText(form, "interimAmount")
+ )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo"))
+ }
+ }
+
+ def submit: Action[AnyContent] =
+ (authenticate andThen hasLinkedProperties).async { implicit request =>
+ form.bindFromRequest().fold(
+ formWithErrors => {
+ val correctedFormErrors = formWithErrors.errors.map { formError =>
+ (formError.key, formError.messages) match
+ case (key, messages) if messages.contains("interimRentSetByTheCourt.startDate.before.1900.error") ||
+ messages.contains("interimRentSetByTheCourt.year.required.error") =>
+ formError.copy(key = "date.year")
+ case ("date", messages) =>
+ formError.copy(key = "date.month")
+ case _ =>
+ formError
+ }
+ val formWithCorrectedErrors = formWithErrors.copy(errors = correctedFormErrors)
+ request.propertyLinking.map(property =>
+ Future.successful(BadRequest(interimRentSetByTheCourtView(
+ form = formWithCorrectedErrors,
+ propertyAddress = property.addressFull,
+ interimAmount = generateInputText(formWithCorrectedErrors, "interimAmount")
+ )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo"))
+ },
+ interimRent =>
+ raldRepo.insertInterimRentSetByTheCourt(
+ credId = CredId(request.credId.getOrElse("")),
+ amount = interimRent.amount,
+ date = interimRent.date.makeString
+ )
+ Future.successful(Redirect(routes.CheckRentFreePeriodController.show.url))
+ )
+ }
+ }
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala
index e3d64b64..f5110a62 100644
--- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala
+++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala
@@ -68,7 +68,7 @@ class RentInterimController @Inject()(rentInterimView: RentInterimView,
agreedRentChange = radioValue.radioValue
)
if (radioValue.radioValue == "Yes") {
- Future.successful(Redirect(routes.ProvideDetailsOfFirstSecondRentPeriodController.show.url))
+ Future.successful(Redirect(routes.InterimRentSetByTheCourtController.show.url))
} else {
Future.successful(Redirect(routes.CheckRentFreePeriodController.show.url))
}
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala
new file mode 100644
index 00000000..6f0950f3
--- /dev/null
+++ b/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala
@@ -0,0 +1,27 @@
+/*
+ * 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.models
+
+import play.api.libs.json.{Json, OFormat}
+
+case class InterimRentSetByTheCourt(amount: String,
+ date: String
+ )
+
+object InterimRentSetByTheCourt {
+ implicit val format: OFormat[InterimRentSetByTheCourt] = Json.format[InterimRentSetByTheCourt]
+}
\ No newline at end of file
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala
new file mode 100644
index 00000000..4cae8fd2
--- /dev/null
+++ b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala
@@ -0,0 +1,55 @@
+/*
+ * 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.models
+
+import play.api.data.Forms.{mapping, text}
+import play.api.data.Mapping
+import play.api.libs.json.{Json, OFormat}
+
+import java.time.LocalDate
+import java.time.format.{DateTimeFormatter, TextStyle}
+import java.util.Locale
+
+final case class NGRMonthYear(month: String, year: String) {
+ def makeString: String = {
+ val monthStr = f"${month.toIntOption.getOrElse(0)}%02d"
+ s"$year-$monthStr"
+ }
+}
+
+object NGRMonthYear {
+ implicit val format: OFormat[NGRMonthYear] = Json.format[NGRMonthYear]
+
+ def formatDate(dateString: String): String = {
+ val date = LocalDate.parse(dateString)
+ val outputFormatter = DateTimeFormatter.ofPattern("MMMM yyyy", Locale.UK)
+ date.format(outputFormatter)
+ }
+
+
+ def unapply(ngrMonthYear: NGRMonthYear): Option[(String, String)] =
+ Some(ngrMonthYear.month, ngrMonthYear.year)
+}
+
+trait MonthYearMappings {
+ def monthYearMapping: Mapping[NGRMonthYear] = {
+ mapping(
+ "month" -> text().transform(_.strip(), identity),
+ "year" -> text().transform(_.strip(), identity),
+ )(NGRMonthYear.apply)(NGRMonthYear.unapply)
+ }
+}
\ No newline at end of file
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala
index f8887264..8d39f6fe 100644
--- a/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala
+++ b/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala
@@ -40,7 +40,8 @@ final case class RaldUserAnswers(
hasAnotherRentPeriod: Option[Boolean] = None,
whatYourRentIncludes: Option[WhatYourRentIncludes] = None,
doesYourRentIncludeParking: Option[Boolean] = None,
- howManyParkingSpacesOrGaragesIncludedInRent: Option[HowManyParkingSpacesOrGarages] = None
+ howManyParkingSpacesOrGaragesIncludedInRent: Option[HowManyParkingSpacesOrGarages] = None ,
+ interimRentSetByTheCourt: Option[InterimRentSetByTheCourt] = None
)
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala
index 033bb475..ee6bba3b 100644
--- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala
+++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala
@@ -68,6 +68,23 @@ trait CommonFormValidators {
}
}
+ protected def isMonthYearEmpty[A](errorKeys: Map[DateErrorKeys, String]): Constraint[A] =
+ Constraint((input: A) =>
+ monthYearEmptyValidation(input.asInstanceOf[NGRMonthYear], errorKeys)
+ )
+
+ protected def isMonthYearValid[A](errorKey: String): Constraint[A] =
+ Constraint((input: A) =>
+ val date = input.asInstanceOf[NGRMonthYear]
+ monthYearValidation(date, errorKey)
+ )
+
+ protected def isMonthYearAfter1900[A](errorKey: String): Constraint[A] =
+ Constraint((input: A) =>
+ val date = input.asInstanceOf[NGRMonthYear]
+ monthYearAfter1900Validation(date, errorKey)
+ )
+
protected def isDateEmpty[A](errorKeys: Map[DateErrorKeys, String]): Constraint[A] =
Constraint((input: A) =>
dateEmptyValidation(input.asInstanceOf[NGRDate], errorKeys)
@@ -96,15 +113,45 @@ trait CommonFormValidators {
case (false, false, true) => Invalid(errorKeys.get(Year).getOrElse(""))
case (_, _, _) => Valid
+ protected def monthYearEmptyValidation(date: NGRMonthYear, errorKeys: Map[DateErrorKeys, String]): ValidationResult =
+ (date.month.isEmpty, date.year.isEmpty) match
+ case (true, true) => Invalid(errorKeys.get(Required).getOrElse(""))
+ case (true, false) => Invalid(errorKeys.get(Month).getOrElse(""))
+ case (false, true) => Invalid(errorKeys.get(Year).getOrElse(""))
+ case (_, _) => Valid
+
protected def dateValidation(date: NGRDate, errorKey: String) =
if (Try(date.ngrDate).isFailure || (Try(date.ngrDate).isSuccess && date.year.length > 4))
Invalid(errorKey)
else
Valid
-
+
+
+ private def monthYearAfter1900Validation(date: NGRMonthYear, errorKey: String) =
+ val maybeYear = date.year.toIntOption
+ maybeYear match {
+ case Some(year) =>
+ if (year < 1900)
+ Invalid (errorKey)
+ else
+ Valid
+ case None => Invalid(errorKey)
+ }
+
private def dateAfter1900Validation(date: NGRDate, errorKey: String) =
if (Try(date.ngrDate).isSuccess && date.year.toInt < 1900)
Invalid(errorKey)
else
Valid
+
+ protected def monthYearValidation(date: NGRMonthYear, errorKey: String) = {
+ val maybeMonth = date.month.toIntOption
+ val maybeYear = date.year.toIntOption
+ (maybeMonth, maybeYear) match {
+ case (Some(month), Some(year)) if month > 0 && month <= 12 && (month + year != 0) =>
+ Valid
+ case _ =>
+ Invalid(errorKey)
+ }
+ }
}
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala
index 1d946975..592bf17e 100644
--- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala
+++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala
@@ -41,7 +41,7 @@ object HowMuchIsTotalAnnualRentForm extends CommonFormValidators {
val form: Form[HowMuchIsTotalAnnualRentForm] = Form(
mapping(
annualRent -> text()
- .transform[String](_.strip(), identity)
+ .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity)
.verifying(
firstError(
isNotEmpty(annualRent, annualRentEmptyError),
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala
new file mode 100644
index 00000000..5daa5d7e
--- /dev/null
+++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala
@@ -0,0 +1,73 @@
+/*
+ * 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.models.forms
+
+import play.api.data.*
+import play.api.data.Forms.*
+import play.api.data.format.Formatter
+import play.api.libs.json.{Json, OFormat}
+import uk.gov.hmrc.ngrraldfrontend.models.*
+
+import scala.math.BigDecimal.RoundingMode
+import scala.util.Try
+
+
+final case class InterimRentSetByTheCourtForm(amount: BigDecimal, date: NGRMonthYear)
+
+object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearMappings {
+ implicit val format: OFormat[InterimRentSetByTheCourtForm] = Json.format[InterimRentSetByTheCourtForm]
+
+ private lazy val howMuchEmptyError = "interimRentSetByTheCourt.interimAmount.required.error"
+ private lazy val howMuchMaxError = "interimRentSetByTheCourt.interimAmount.tooLarge.error"
+ private lazy val howMuchFormatError = "interimRentSetByTheCourt.interimAmount.format.error"
+
+ def unapply(interimRentSetByTheCourtForm: InterimRentSetByTheCourtForm): Option[(BigDecimal, NGRMonthYear)] = Some(interimRentSetByTheCourtForm.amount, interimRentSetByTheCourtForm.date)
+
+ private def errorKeys(whichDate: String): Map[DateErrorKeys, String] = Map(
+ Required -> s"$whichDate.required.error",
+ Month -> s"$whichDate.month.required.error",
+ Year -> s"$whichDate.year.required.error"
+ )
+
+ val form: Form[InterimRentSetByTheCourtForm] = Form(
+ mapping(
+ "interimAmount" -> text()
+ .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity)
+ .verifying(
+ firstError(
+ isNotEmpty("interimAmount", howMuchEmptyError),
+ regexp(amountRegex.pattern(), howMuchFormatError)
+ )
+ )
+ .transform[BigDecimal](BigDecimal(_).setScale(2, RoundingMode.HALF_UP), _.toString)
+ .verifying(
+ maximumValue[BigDecimal](BigDecimal("9999999.99"), howMuchMaxError)
+ ),
+ "date" -> monthYearMapping
+ .verifying(
+ firstError(
+ isMonthYearEmpty(errorKeys("interimRentSetByTheCourt")),
+ isMonthYearValid("interimRentSetByTheCourt.monthYear.format.error"),
+ isMonthYearAfter1900("interimRentSetByTheCourt.startDate.before.1900.error")
+ )
+ ),
+ )(InterimRentSetByTheCourtForm.apply)(InterimRentSetByTheCourtForm.unapply)
+ )
+
+}
+
+
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala
index 68823ba3..94cfb082 100644
--- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala
+++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala
@@ -110,7 +110,7 @@ object ProvideDetailsOfFirstSecondRentPeriodForm extends CommonFormValidators wi
firstRentPeriodRadio -> radioText(radioFirstPeriodRequiredError),
RentPeriodAmount -> optional(
text()
- .transform[String](_.strip(), identity)
+ .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity)
),
secondDateStartInput -> dateMapping
.verifying(
@@ -129,7 +129,7 @@ object ProvideDetailsOfFirstSecondRentPeriodForm extends CommonFormValidators wi
)
),
SecondRentPeriodAmount -> text()
- .transform[String](_.strip(), identity)
+ .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity)
.verifying(
firstError(
isNotEmpty(SecondRentPeriodAmount, annualRentEmptyError),
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala b/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala
index b2f3f11a..a58bd9a4 100644
--- a/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala
+++ b/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala
@@ -254,6 +254,13 @@ case class RaldRepo @Inject()(mongo: MongoComponent,
findAndUpdateByCredId(credId, updates: _*)
}
+ def insertInterimRentSetByTheCourt(credId: CredId, amount: BigDecimal, date: String) = {
+ val updates = Seq(
+ Updates.set("interimRentSetByTheCourt.amount", amount.toString()),
+ Updates.set("interimRentSetByTheCourt.date", date),
+ )
+ findAndUpdateByCredId(credId, updates: _*)
+ }
def findByCredId(credId: CredId): Future[Option[RaldUserAnswers]] = {
collection.find(
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html
new file mode 100644
index 00000000..3dbd14fd
--- /dev/null
+++ b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html
@@ -0,0 +1,50 @@
+@*
+ * 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.
+ *@
+
+@import uk.gov.hmrc.govukfrontend.views.html.components._
+@import uk.gov.hmrc.govukfrontend.views.Aliases._
+@import uk.gov.hmrc.ngrraldfrontend.views.html.components._
+@import uk.gov.hmrc.ngrraldfrontend.viewmodels.govuk.all._
+@import uk.gov.hmrc.ngrraldfrontend.config.AppConfig
+@import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm
+
+@this(
+ layout: Layout,
+ formHelper: FormWithCSRF,
+ inputDateForMonthYear: components.InputDateForMonthYear,
+ govukErrorSummary: GovukErrorSummary,
+ saveAndContinueButton: saveAndContinueButton
+)
+
+@(form:Form[InterimRentSetByTheCourtForm], propertyAddress: String, interimAmount: Html)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig)
+
+@layout(pageTitle = Some(messages("interimRentSetByTheCourt.title")), showBackLink = true, fullWidth = false) {
+ @formHelper(action = uk.gov.hmrc.ngrraldfrontend.controllers.routes.InterimRentSetByTheCourtController.submit, Symbol("autoComplete") -> "off") {
+ @if(form.errors.nonEmpty) {
+ @govukErrorSummary(ErrorSummaryViewModel(form))
+ }
+ @propertyAddress
+
@messages("interimRentSetByTheCourt.title")
+ @interimAmount
+ @inputDateForMonthYear(
+ form,
+ legendContent = messages("interimRentSetByTheCourt.label.2"),
+ legendAsPageHeading = false,
+ hintText = Some(messages("interimRentSetByTheCourt.hint.2"))
+ )
+ @saveAndContinueButton(msg = messages("service.continue"), isStartButton = false)
+ }
+}
\ No newline at end of file
diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputDateForMonthYear.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputDateForMonthYear.scala.html
new file mode 100644
index 00000000..33e5af54
--- /dev/null
+++ b/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputDateForMonthYear.scala.html
@@ -0,0 +1,70 @@
+@*
+ * 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.
+ *@
+
+@import uk.gov.hmrc.govukfrontend.views.html.components._
+
+@this(govukDateInput: GovukDateInput)
+
+@(
+ form: Form[_],
+ legendContent: String,
+ legendClasses: String = "govuk-fieldset__legend--xl",
+ id: String = "date",
+ hintText: Option[String] = None,
+ legendAsPageHeading: Boolean = true)(implicit messages: Messages)
+
+@govukDateInput(DateInput(
+ fieldset = Some(Fieldset(
+ legend = Some(
+ Legend(
+ content = Text(messages(legendContent)),
+ isPageHeading = legendAsPageHeading,
+ classes = if(legendAsPageHeading){legendClasses}else{"govuk-fieldset__legend--m"}
+ )
+ )
+ )),
+ id = id,
+ items = Seq(
+ InputItem(
+ id = s"$id.month",
+ classes = s"govuk-input--width-2${if(
+ form(s"$id.month").hasErrors
+ || form.errors.exists(_.key.contains("date"))
+ || form.errors.exists(_.args.contains("month")))" govuk-input--error" else ""}",
+ name = s"$id.month",
+ label = Some(messages("date.month")),
+ value = form(s"$id.month").value
+ ),
+ InputItem(
+ id = s"$id.year",
+ classes = s"govuk-input--width-4${if(
+ form(s"$id.year").hasErrors
+ || form.errors.exists(_.key.contains("date"))
+ || form.errors.exists(_.args.contains("year")))" govuk-input--error" else ""}",
+ name = s"$id.year",
+ label = Some(messages("date.year")),
+ value = form(s"$id.year").value
+ )
+ ),
+ hint = hintText.map(hint => Hint(content = Text(messages(hint)))),
+ errorMessage = form.errors.find(err =>
+ err.key == id || err.key == s"$id.month" || err.key == s"$id.year" || err.key == "date"
+ ).map { err =>
+ ErrorMessage.errorMessageWithDefaultStringsTranslated(
+ content = Text(messages(err.message, err.args: _*))
+ )
+ }
+))
\ No newline at end of file
diff --git a/conf/app.routes b/conf/app.routes
index 9b65aefd..273b4444 100644
--- a/conf/app.routes
+++ b/conf/app.routes
@@ -1,46 +1,48 @@
# microservice specific routes
--> /hmrc-frontend hmrcfrontend.Routes
-GET /assets/*file controllers.Assets.versioned(path = "/public", file: Asset)
-GET /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.show
-POST /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.submit
-GET /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.show
-POST /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.submit
-GET /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.show
-POST /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.submit
-GET /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.show
-POST /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.submit
-GET /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.show
-POST /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.submit
-GET /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.show
-POST /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.submit
-GET /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.show
-POST /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.submit
-GET /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.show
-POST /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.submit
-GET /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.show
-POST /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.submit
-GET /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.show
-POST /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.submit
-GET /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.show
-POST /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.submit
-GET /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.show
-POST /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.submit
-GET /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.show
-POST /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.submit
-GET /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.show
-POST /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.submit
-GET /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.show
-POST /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.submit
-GET /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.show
-POST /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.submit
-GET /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.show
-POST /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.submit
-GET /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.show
-POST /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.submit
-GET /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.show
-POST /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.submit
-GET /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.show
-POST /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.submit
+-> /hmrc-frontend hmrcfrontend.Routes
+GET /assets/*file controllers.Assets.versioned(path = "/public", file: Asset)
+GET /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.show
+POST /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.submit
+GET /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.show
+POST /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.submit
+GET /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.show
+POST /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.submit
+GET /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.show
+POST /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.submit
+GET /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.show
+POST /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.submit
+GET /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.show
+POST /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.submit
+GET /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.show
+POST /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.submit
+GET /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.show
+POST /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.submit
+GET /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.show
+POST /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.submit
+GET /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.show
+POST /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.submit
+GET /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.show
+POST /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.submit
+GET /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.show
+POST /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.submit
+GET /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.show
+POST /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.submit
+GET /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.show
+POST /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.submit
+GET /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.show
+POST /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.submit
+GET /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.show
+POST /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.submit
+GET /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.show
+POST /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.submit
+GET /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.show
+POST /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.submit
+GET /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.show
+POST /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.submit
+GET /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.show
+POST /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.submit
GET /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.show
-POST /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.submit
\ No newline at end of file
+POST /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.submit
+GET /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.show
+POST /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.submit
\ No newline at end of file
diff --git a/conf/messages b/conf/messages
index 456567b9..bdc13cf4 100644
--- a/conf/messages
+++ b/conf/messages
@@ -343,7 +343,6 @@ howManyParkingSpacesOrGaragesIncludedInRent.hint = If spaces are in communal car
howManyParkingSpacesOrGaragesIncludedInRent.uncoveredSpaces.label = Uncovered spaces
howManyParkingSpacesOrGaragesIncludedInRent.coveredSpaces.label = Covered spaces
howManyParkingSpacesOrGaragesIncludedInRent.garages.label = Garages
-
howManyParkingSpacesOrGaragesIncludedInRent.error.required = Total number of uncovered spaces, covered spaces and garages included in your rent must be more than 0
howManyParkingSpacesOrGaragesIncludedInRent.allFields.error.required = Enter how many parking spaces or garages are included in your rent
howManyParkingSpacesOrGaragesIncludedInRent.uncoveredSpaces.wholeNum.error = Number of uncovered parking spaces included in your rent must be a number, like 9
@@ -352,3 +351,20 @@ howManyParkingSpacesOrGaragesIncludedInRent.garages.wholeNum.error = Number of g
howManyParkingSpacesOrGaragesIncludedInRent.uncoveredSpaces.tooHigh.error = Number of uncovered parking spaces included in your rent must be 9,999 or less
howManyParkingSpacesOrGaragesIncludedInRent.coveredSpaces.tooHigh.error = Number of covered parking spaces included in your rent must be 9,999 or less
howManyParkingSpacesOrGaragesIncludedInRent.garages.tooHigh.error = Number of garages included in your rent must be 9,999 or less
+
+#InterimRentSetByTheCourt
+interimRentSetByTheCourt.title = Interim rent set by the court
+interimRentSetByTheCourt.label.1 = How much was the interim rent?
+interimRentSetByTheCourt.label.2 = When did you start paying the interim rent?
+interimRentSetByTheCourt.hint.2 = For example, 6 2026
+date.month = Month
+date.year = Year
+
+interimRentSetByTheCourt.interimAmount.required.error = Enter how much the interim rent was, in pounds
+interimRentSetByTheCourt.interimAmount.tooLarge.error = Interim rent must be £9,999,999.99 or less
+interimRentSetByTheCourt.interimAmount.format.error = Interim rent must be a number, like 50,000
+interimRentSetByTheCourt.monthYear.format.error = Date your interim rent started must be a real date
+interimRentSetByTheCourt.required.error = Enter the date you started paying interim rent
+interimRentSetByTheCourt.month.required.error = Date you started paying the interim rent must include a month
+interimRentSetByTheCourt.year.required.error = Date you started paying the interim rent must include a year
+interimRentSetByTheCourt.startDate.before.1900.error = The date you started paying interim rent must be 1900 or after
\ No newline at end of file
diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala
new file mode 100644
index 00000000..284a8f3c
--- /dev/null
+++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala
@@ -0,0 +1,145 @@
+/*
+ * 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
+
+
+
+/*
+ * 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.
+ */
+
+
+import play.api.http.Status.{BAD_REQUEST, OK, SEE_OTHER}
+import play.api.test.FakeRequest
+import play.api.test.Helpers.{await, contentAsString, defaultAwaitTimeout, redirectLocation, status}
+import uk.gov.hmrc.http.{HeaderNames, NotFoundException}
+import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport
+import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView
+import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText
+
+class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport {
+ val pageTitle = "Interim rent set by the court"
+ val view: InterimRentSetByTheCourtView = inject[InterimRentSetByTheCourtView]
+ val controller: InterimRentSetByTheCourtController = new InterimRentSetByTheCourtController(
+ interimRentSetByTheCourtView = view,
+ authenticate = mockAuthJourney,
+ hasLinkedProperties = mockPropertyLinkingAction,
+ inputText = mockInputText,
+ raldRepo = mockRaldRepo,
+ mcc = mcc)(mockConfig)
+
+ "InterimRentSetByTheCourtController" must {
+ "method show" must {
+ "Return OK and the correct view" in {
+ val result = controller.show()(authenticatedFakeRequest())
+ status(result) mustBe OK
+ val content = contentAsString(result)
+ content must include(pageTitle)
+ }
+ "Return NotFoundException when property is not found in the mongo" in {
+ mockRequestWithoutProperty()
+ val exception = intercept[NotFoundException] {
+ await(controller.show(authenticatedFakeRequest()))
+ }
+ exception.getMessage contains "Couldn't find property in mongo" mustBe true
+ }
+ }
+
+ "method submit" must {
+ "Return OK and the correct view" in {
+ val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit)
+ .withFormUrlEncodedBody(
+ "interimAmount" -> "10000",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ .withHeaders(HeaderNames.authorisation -> "Bearer 1")
+
+ val result = controller.submit()(authenticatedFakeRequest(fakePostRequest))
+ status(result) mustBe SEE_OTHER
+ redirectLocation(result) mustBe Some(routes.CheckRentFreePeriodController.show.url)
+ }
+ "Return BAD_REQUEST for missing how much input and the correct view" in {
+ mockRequest()
+ val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit)
+ .withFormUrlEncodedBody(
+ "interimAmount" -> "",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ .withHeaders(HeaderNames.authorisation -> "Bearer 1")
+
+ val result = controller.submit()(authenticatedFakeRequest(fakePostRequest))
+ status(result) mustBe BAD_REQUEST
+ val content = contentAsString(result)
+ content must include("Enter how much the interim rent was, in pounds")
+ }
+ "Return BAD_REQUEST for missing month input and the correct view" in {
+ mockRequest()
+ val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit)
+ .withFormUrlEncodedBody(
+ "interimAmount" -> "1000",
+ "date.month" -> "",
+ "date.year" -> "1990"
+ )
+ .withHeaders(HeaderNames.authorisation -> "Bearer 1")
+
+ val result = controller.submit()(authenticatedFakeRequest(fakePostRequest))
+ status(result) mustBe BAD_REQUEST
+ val content = contentAsString(result)
+ content must include("Date you started paying the interim rent must include a month")
+ }
+ "Return BAD_REQUEST for missing year input and the correct view" in {
+ mockRequest()
+ val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit)
+ .withFormUrlEncodedBody(
+ "interimAmount" -> "1000",
+ "date.month" -> "1",
+ "date.year" -> ""
+ )
+ .withHeaders(HeaderNames.authorisation -> "Bearer 1")
+
+ val result = controller.submit()(authenticatedFakeRequest(fakePostRequest))
+ status(result) mustBe BAD_REQUEST
+ val content = contentAsString(result)
+ content must include("Date you started paying the interim rent must include a year")
+ }
+ "Return Exception if no address is in the mongo" in {
+ mockRequestWithoutProperty()
+ val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit)
+ .withFormUrlEncodedBody(("how–much–is–total–annual–rent-value", ""))
+ .withHeaders(HeaderNames.authorisation -> "Bearer 1")
+ val exception = intercept[NotFoundException] {
+ await(controller.submit()(authenticatedFakeRequest(fakePostRequest)))
+ }
+ exception.getMessage contains "Couldn't find property in mongo" mustBe true
+ }
+ }
+ }
+}
diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala
index 23d682e8..50d05066 100644
--- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala
+++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala
@@ -53,7 +53,7 @@ class RentInterimControllerSpec extends ControllerSpecSupport {
val result = controller.submit()(authenticatedFakeRequest(fakePostRequest))
status(result) mustBe SEE_OTHER
- redirectLocation(result) mustBe Some(routes.ProvideDetailsOfFirstSecondRentPeriodController.show.url)
+ redirectLocation(result) mustBe Some(routes.InterimRentSetByTheCourtController.show.url)
}
"Return OK and the correct view when no is selected" in {
val fakePostRequest = FakeRequest(routes.WhatTypeOfLeaseRenewalController.submit)
diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourtSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourtSpec.scala
new file mode 100644
index 00000000..b9e92844
--- /dev/null
+++ b/test/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourtSpec.scala
@@ -0,0 +1,44 @@
+/*
+ * 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.models
+
+import play.api.libs.json.{JsValue, Json}
+import uk.gov.hmrc.ngrraldfrontend.helpers.TestSupport
+
+class InterimRentSetByTheCourtSpec extends TestSupport {
+
+ val interimRentSetByTheCourt: InterimRentSetByTheCourt = InterimRentSetByTheCourt(amount = "1000.00", date = "2020-1")
+
+ val interimRentSetByTheCourtJson: JsValue = Json.parse(
+ """
+ |{
+ |"amount": "1000.00",
+ |"date":"2020-1"
+ |}
+ |""".stripMargin
+ )
+
+ "RentBasedOn" should {
+ "deserialize to json" in {
+ Json.toJson(interimRentSetByTheCourt) mustBe interimRentSetByTheCourtJson
+ }
+ "serialize to json" in {
+ interimRentSetByTheCourtJson.as[InterimRentSetByTheCourt] mustBe interimRentSetByTheCourt
+ }
+ }
+}
+
diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala
index 77e5b970..bfd96dda 100644
--- a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala
+++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala
@@ -37,6 +37,16 @@ class HowMuchIsTotalAnnualRentFormSpec extends AnyWordSpec with Matchers {
boundForm.value shouldBe Some(HowMuchIsTotalAnnualRentForm(BigDecimal("123456.78")))
}
+ "bind amount with commas" in {
+ val data = Map(
+ "how–much–is–total–annual–rent-value" -> "9,999,999.99",
+ )
+ val boundForm = HowMuchIsTotalAnnualRentForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe false
+ boundForm.value shouldBe Some(HowMuchIsTotalAnnualRentForm(BigDecimal("9999999.99")))
+ }
+
"fail to bind empty input" in {
val data = Map("how–much–is–total–annual–rent-value" -> "")
val boundForm = HowMuchIsTotalAnnualRentForm.form.bind(data)
diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala
new file mode 100644
index 00000000..b499801b
--- /dev/null
+++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala
@@ -0,0 +1,258 @@
+/*
+ * 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.models.forms
+
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.matchers.should.Matchers.{should, shouldBe}
+import org.scalatest.wordspec.AnyWordSpec
+import play.api.data.FormError
+import play.api.libs.json.Json
+import uk.gov.hmrc.ngrraldfrontend.models.NGRMonthYear
+
+import scala.collection.immutable.ArraySeq
+
+class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers {
+
+ "InterimRentSetByTheCourtForm" should {
+
+ "bind valid input" in {
+ val data = Map(
+ "interimAmount" -> "123456.78",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe false
+ boundForm.value shouldBe Some(InterimRentSetByTheCourtForm(
+ amount = BigDecimal(123456.78),
+ date = NGRMonthYear(month = "1", year = "1990")
+ ))
+ }
+
+ "fail to bind empty input" in {
+ val data = Map.empty[String, String]
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe true
+ boundForm.errors should contain(FormError("interimAmount", "error.required"))
+ }
+
+ "fail to bind non-numeric input for how much input field" in {
+ val data = Map(
+ "interimAmount" -> "hello",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+ boundForm.hasErrors shouldBe true
+ boundForm.errors shouldBe List(FormError("interimAmount", List("interimRentSetByTheCourt.interimAmount.format.error"), ArraySeq("""([0-9]+\.[0-9]+|[0-9]+)""")))
+ }
+
+ "fail to bind input greater than 9999999.99 for how much input field" in {
+ val data = Map(
+ "interimAmount" -> "123456789.78",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.errors shouldBe List(FormError("interimAmount", List("interimRentSetByTheCourt.interimAmount.tooLarge.error"), ArraySeq(9999999.99)))
+ }
+
+ "bind edge case of exactly 9999999.99" in {
+ val data = Map(
+ "interimAmount" -> "9999999.99",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe false
+ boundForm.value shouldBe Some(InterimRentSetByTheCourtForm(
+ amount = BigDecimal("9999999.99"),
+ date = NGRMonthYear(month = "1", year = "1990")
+ ))
+ }
+
+ "bind and drop decimal places to make 2" in {
+ val data = Map(
+ "interimAmount" -> "11.123",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe false
+ boundForm.value shouldBe Some(InterimRentSetByTheCourtForm(
+ amount = BigDecimal("11.12"),
+ date = NGRMonthYear(month = "1", year = "1990")
+ ))
+ }
+
+ "bind and round the decimal places up" in {
+ val data = Map(
+ "interimAmount" -> "11.125",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe false
+ boundForm.value shouldBe Some(InterimRentSetByTheCourtForm(
+ amount = BigDecimal("11.13"),
+ date = NGRMonthYear(month = "1", year = "1990")
+ ))
+ }
+
+ "bind decimal with two .00" in {
+ val data = Map(
+ "interimAmount" -> "11.00",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe false
+ boundForm.value shouldBe Some(InterimRentSetByTheCourtForm(
+ amount = BigDecimal("11.00"),
+ date = NGRMonthYear(month = "1", year = "1990")
+ ))
+ }
+
+ "bind amount with commas" in {
+ val data = Map(
+ "interimAmount" -> "9,999,999.99",
+ "date.month" -> "1",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.hasErrors shouldBe false
+ boundForm.value shouldBe Some(InterimRentSetByTheCourtForm(
+ amount = BigDecimal("9999999.99"),
+ date = NGRMonthYear(month = "1", year = "1990")
+ ))
+ }
+
+ "fail to bind incorrect month for month input field" in {
+ val data = Map(
+ "interimAmount" -> "123456.78",
+ "date.month" -> "13",
+ "date.year" -> "1990"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.monthYear.format.error"))
+ }
+ "fail to bind year before 1900 for year input field" in {
+ val data = Map(
+ "interimAmount" -> "123456.78",
+ "date.month" -> "10",
+ "date.year" -> "1899"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.startDate.before.1900.error"))
+ }
+
+ "fail to bind missing month input" in {
+ val data = Map(
+ "interimAmount" -> "123456.78",
+ "date.month" -> "",
+ "date.year" -> "1899"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.month.required.error"))
+ }
+
+ "fail to bind missing year input" in {
+ val data = Map(
+ "interimAmount" -> "123456.78",
+ "date.month" -> "1",
+ "date.year" -> ""
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.year.required.error"))
+ }
+
+ "fail to bind non numeric format for month input" in {
+ val data = Map(
+ "interimAmount" -> "123456.78",
+ "date.month" -> "hello",
+ "date.year" -> "1999"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.monthYear.format.error"))
+ }
+
+ "fail to bind non numeric format for year input" in {
+ val data = Map(
+ "interimAmount" -> "123456.78",
+ "date.month" -> "1",
+ "date.year" -> "hello"
+ )
+ val boundForm = InterimRentSetByTheCourtForm.form.bind(data)
+
+ boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.monthYear.format.error"))
+ }
+
+ }
+
+ "serialize to JSON correctly" in {
+ val form = InterimRentSetByTheCourtForm(
+ amount = BigDecimal("9999999.99"),
+ date = NGRMonthYear(month = "1", year = "1990")
+ )
+ val json = Json.toJson(form)
+
+ json shouldBe Json.obj(
+ "amount" -> 9999999.99,
+ "date" -> Json.obj(
+ "month" -> "1",
+ "year" -> "1990"
+ )
+ )
+ }
+
+ "deserialize from JSON correctly" in {
+ val json = Json.obj(
+ "amount" -> 9999999.99,
+ "date" -> Json.obj(
+ "month" -> "1",
+ "year" -> "1990"
+ )
+ )
+ val result = json.validate[InterimRentSetByTheCourtForm]
+
+ result.isSuccess shouldBe true
+ result.get shouldBe InterimRentSetByTheCourtForm(
+ amount = BigDecimal(9999999.99),
+ date = NGRMonthYear(month = "1", year = "1990")
+ )
+ }
+
+ "fail deserialization if value is missing" in {
+ val json = Json.obj()
+ val result = json.validate[InterimRentSetByTheCourtForm]
+
+ result.isError shouldBe true
+ }
+}
\ No newline at end of file
diff --git a/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala
index df05ff85..cf2974a4 100644
--- a/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala
+++ b/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala
@@ -505,6 +505,18 @@ class RaldRepoSpec extends TestSupport with TestData
actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, doesYourRentIncludeParking = Some(true)))
}
+ "insert interim rent amount and start date" in {
+ await(repository.insertInterimRentSetByTheCourt(credId, 10000.12, "2020-1"))
+ val actual = await(repository.findByCredId(credId))
+ actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, interimRentSetByTheCourt = Some(InterimRentSetByTheCourt(amount = "10000.12", date = "2020-1"))))
+ }
+
+ "insert interim rent amount With decimal of .00 and start date" in {
+ await(repository.insertInterimRentSetByTheCourt(credId, 10000.00, "2020-1"))
+ val actual = await(repository.findByCredId(credId))
+ actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, interimRentSetByTheCourt = Some(InterimRentSetByTheCourt(amount = "10000.0", date = "2020-1"))))
+ }
+
"insert has parking included in rent successfully with no" in {
await(repository.insertDoesYourRentIncludeParking(credId, "No"))
val actual = await(repository.findByCredId(credId))
diff --git a/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala
new file mode 100644
index 00000000..a29c106d
--- /dev/null
+++ b/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala
@@ -0,0 +1,110 @@
+/*
+ * 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.views
+
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Document
+import play.api.data.Form
+import play.api.i18n.Messages
+import play.twirl.api.HtmlFormat
+import uk.gov.hmrc.govukfrontend.views.Aliases.{PrefixOrSuffix, Text}
+import uk.gov.hmrc.ngrraldfrontend.helpers.ViewBaseSpec
+import uk.gov.hmrc.ngrraldfrontend.models.NGRMonthYear
+import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm
+import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView
+import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText
+
+class InterimRentSetByTheCourtViewSpec extends ViewBaseSpec {
+ lazy val view: InterimRentSetByTheCourtView = inject[InterimRentSetByTheCourtView]
+
+ object Strings {
+ val heading = "Interim rent set by the court"
+ val label1 = "How much was the interim rent?"
+ val label2 = "When did you start paying the interim rent?"
+ val hint2 = "For example, 6 2026"
+ val saveAndContinue = "Continue"
+ }
+
+ object Selectors {
+ val heading = "#main-content > div > div.govuk-grid-column-two-thirds > form > h1"
+ val label1 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(3) > h1"
+ val label2 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(4) > fieldset > legend"
+ val hint2 = "#date-hint"
+ val saveAndContinue = "#continue"
+ }
+
+ val address = "5 Brixham Marina, Berry Head Road, Brixham, Devon, TQ5 9BW"
+
+ val form = InterimRentSetByTheCourtForm.form.fillAndValidate(InterimRentSetByTheCourtForm(amount = BigDecimal(1000), date = NGRMonthYear(month = "1", year = "2020")))
+ val mockInputText: InputText = inject[InputText]
+ def generateInputText(form: Form[InterimRentSetByTheCourtForm], inputFieldName: String)(implicit messages: Messages): HtmlFormat.Appendable = {
+ mockInputText(
+ form = form,
+ id = inputFieldName,
+ name = inputFieldName,
+ label = messages(s"interimRentSetByTheCourt.label.1"),
+ headingMessageArgs = Seq("govuk-fieldset__legend govuk-fieldset__legend--s"),
+ isPageHeading = true,
+ isVisible = true,
+ classes = Some("govuk-input govuk-input--width-5"),
+ prefix = Some(PrefixOrSuffix(content = Text("£")))
+ )
+ }
+
+ val howMuch: HtmlFormat.Appendable = generateInputText(form, "howMuch")
+
+ "InterimRentSetByTheCourtView" must {
+ val interimRentSetByTheCourtView = view(form, address, howMuch)
+ lazy implicit val document: Document = Jsoup.parse(interimRentSetByTheCourtView.body)
+ val htmlApply = view.apply(form, address, howMuch).body
+ val htmlRender = view.render(form, address, howMuch, request, messages, mockConfig).body
+ lazy val htmlF = view.f(form, address, howMuch)
+
+ "htmlF is not empty" in {
+ htmlF.toString() must not be empty
+ }
+
+ "apply must be the same as render" in {
+ htmlApply mustBe htmlRender
+ }
+
+ "render is not empty" in {
+ htmlRender must not be empty
+ }
+
+ "show correct heading" in {
+ elementText(Selectors.heading) mustBe Strings.heading
+ }
+
+ "show correct label for how much field" in {
+ elementText(Selectors.label1) mustBe Strings.label1
+ }
+
+ "show correct label for month and year fields" in {
+ elementText(Selectors.label2) mustBe Strings.label2
+ }
+
+ "show correct hint for the month and year fields" in {
+ elementText(Selectors.hint2) mustBe Strings.hint2
+ }
+
+ "show correct continue button" in {
+ elementText(Selectors.saveAndContinue) mustBe Strings.saveAndContinue
+ }
+ }
+}
+