From e10f67ee3bc9064b0f2936d7894f53c20bdfc7ad Mon Sep 17 00:00:00 2001 From: Tevyn Allen <59606793+TevynAllen@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:48:35 +0100 Subject: [PATCH] PIL-947 - Add threshold met knock back page (#20) * PIL-947 - Add threshold met knock back page * Apply scalafix --- ...nues750In2AccountingPeriodController.scala | 9 ++- app/navigation/BtnNavigator.scala | 13 ++-- app/views/btn/BtnThresholdMetView.scala.html | 36 +++++++++++ conf/app.routes | 1 + conf/messages.en | 14 ++++- ...750In2AccountingPeriodControllerSpec.scala | 28 ++++++++- test/navigation/BtnNavigatorSpec.scala | 2 +- test/views/btn/BtnThresholdMetViewSpec.scala | 60 +++++++++++++++++++ 8 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 app/views/btn/BtnThresholdMetView.scala.html create mode 100644 test/views/btn/BtnThresholdMetViewSpec.scala diff --git a/app/controllers/btn/BtnRevenues750In2AccountingPeriodController.scala b/app/controllers/btn/BtnRevenues750In2AccountingPeriodController.scala index e6d7e03..a0eb519 100644 --- a/app/controllers/btn/BtnRevenues750In2AccountingPeriodController.scala +++ b/app/controllers/btn/BtnRevenues750In2AccountingPeriodController.scala @@ -27,7 +27,7 @@ import play.api.i18n.{I18nSupport, MessagesApi} import play.api.mvc.{Action, AnyContent, MessagesControllerComponents} import repositories.SessionRepository import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController -import views.html.btn.BtnRevenues750In2AccountingPeriodView +import views.html.btn.{BtnRevenues750In2AccountingPeriodView, BtnThresholdMetView} import javax.inject.{Inject, Named} import scala.concurrent.{ExecutionContext, Future} @@ -41,7 +41,8 @@ class BtnRevenues750In2AccountingPeriodController @Inject() ( requireData: DataRequiredAction, formProvider: BtnRevenues750In2AccountingPeriodFormProvider, val controllerComponents: MessagesControllerComponents, - view: BtnRevenues750In2AccountingPeriodView + view: BtnRevenues750In2AccountingPeriodView, + thresholdMetView: BtnThresholdMetView )(implicit ec: ExecutionContext, appConfig: FrontendAppConfig) extends FrontendBaseController with I18nSupport { @@ -69,4 +70,8 @@ class BtnRevenues750In2AccountingPeriodController @Inject() ( } yield Redirect(navigator.nextPage(BtnRevenues750In2AccountingPeriodPage, mode, updatedAnswers)) ) } + + def onPageLoadThresholdMet: Action[AnyContent] = (identify andThen getData andThen requireData) { implicit request => + Ok(thresholdMetView()) + } } diff --git a/app/navigation/BtnNavigator.scala b/app/navigation/BtnNavigator.scala index afa6de7..d9a9cc4 100644 --- a/app/navigation/BtnNavigator.scala +++ b/app/navigation/BtnNavigator.scala @@ -16,7 +16,6 @@ package navigation -import controllers.routes import models._ import pages._ import play.api.mvc.Call @@ -37,7 +36,7 @@ class BtnNavigator @Inject() { case EntitiesBothInUKAndOutsidePage => entitiesBothInUKAndOutside case BtnRevenues750In2AccountingPeriodPage => btnRevenues750In2AccountingPeriod case BtnRevenues750InNext2AccountingPeriodsPage => btnRevenues750InNext2AccountingPeriods - case _ => _ => routes.IndexController.onPageLoad + case _ => _ => controllers.routes.IndexController.onPageLoad } private def entitiesBothInUKAndOutside(userAnswers: UserAnswers): Call = @@ -50,19 +49,19 @@ class BtnNavigator @Inject() { controllers.btn.routes.BtnEntitiesBothInUKAndOutsideController.onPageLoadAmendGroupDetails() } } - .getOrElse(routes.JourneyRecoveryController.onPageLoad()) + .getOrElse(controllers.routes.JourneyRecoveryController.onPageLoad()) private def btnRevenues750In2AccountingPeriod(userAnswers: UserAnswers): Call = userAnswers .get(BtnRevenues750In2AccountingPeriodPage) .map { provided => if (provided) { - controllers.routes.UnderConstructionController.onPageLoad + controllers.btn.routes.BtnRevenues750In2AccountingPeriodController.onPageLoadThresholdMet } else { controllers.btn.routes.BtnRevenues750InNext2AccountingPeriodsController.onPageLoad(NormalMode) } } - .getOrElse(routes.JourneyRecoveryController.onPageLoad()) + .getOrElse(controllers.routes.JourneyRecoveryController.onPageLoad()) private def btnRevenues750InNext2AccountingPeriods(userAnswers: UserAnswers): Call = userAnswers @@ -74,11 +73,11 @@ class BtnNavigator @Inject() { controllers.routes.UnderConstructionController.onPageLoad } } - .getOrElse(routes.JourneyRecoveryController.onPageLoad()) + .getOrElse(controllers.routes.JourneyRecoveryController.onPageLoad()) private val checkRouteMap: Page => UserAnswers => Call = { case EntitiesBothInUKAndOutsidePage => _ => controllers.routes.UnderConstructionController.onPageLoad - case _ => _ => routes.IndexController.onPageLoad + case _ => _ => controllers.routes.IndexController.onPageLoad } } diff --git a/app/views/btn/BtnThresholdMetView.scala.html b/app/views/btn/BtnThresholdMetView.scala.html new file mode 100644 index 0000000..a7f6cd3 --- /dev/null +++ b/app/views/btn/BtnThresholdMetView.scala.html @@ -0,0 +1,36 @@ +@* + * Copyright 2024 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 views.html.components.gds._ +@import uk.gov.hmrc.govukfrontend.views.viewmodels.content.HtmlContent +@import config.FrontendAppConfig +@import models.MneOrDomestic.UkAndOther + +@this( + layout: templates.Layout, + heading: Heading, + p: ParagraphBody, + paragraphMessageWithLink: ParagraphMessageWithLink +) + +@()(implicit request: Request[_], appConfig: FrontendAppConfig, messages: Messages) + +@layout(pageTitle = messages("btn.thresholdMet.title")) { + @heading(messages("btn.thresholdMet.heading"), classes = "govuk-heading-l") + @p(messages("btn.thresholdMet.p1")) + @p(messages("btn.thresholdMet.p2")) + @paragraphMessageWithLink(linkMessage = messages("btn.thresholdMet.link"), linkUrl = controllers.uktr.routes.UkTaxReturnStartController.onPageLoad.url, linkFullStop = true) +} diff --git a/conf/app.routes b/conf/app.routes index c703628..15068c8 100644 --- a/conf/app.routes +++ b/conf/app.routes @@ -62,6 +62,7 @@ GET /below-threshold-notification/annual-revenues POST /below-threshold-notification/annual-revenues controllers.btn.BtnRevenues750In2AccountingPeriodController.onSubmit(mode: Mode = NormalMode) GET /below-threshold-notification/change-annual-revenues controllers.btn.BtnRevenues750In2AccountingPeriodController.onPageLoad(mode: Mode = CheckMode) POST /below-threshold-notification/change-annual-revenues controllers.btn.BtnRevenues750In2AccountingPeriodController.onSubmit(mode: Mode = CheckMode) +GET /below-threshold-notification/threshold-met controllers.btn.BtnRevenues750In2AccountingPeriodController.onPageLoadThresholdMet GET /below-threshold-notification/future-annual-revenues controllers.btn.BtnRevenues750InNext2AccountingPeriodsController.onPageLoad(mode: Mode = NormalMode) POST /below-threshold-notification/future-annual-revenues controllers.btn.BtnRevenues750InNext2AccountingPeriodsController.onSubmit(mode: Mode = NormalMode) diff --git a/conf/messages.en b/conf/messages.en index 6fb424d..d4002dd 100644 --- a/conf/messages.en +++ b/conf/messages.en @@ -157,6 +157,12 @@ uktr.UkTaxReturnStart.p6.link = Choose a supplier to submit your UKTR from this uktr.UkTaxReturnStart.inactive.subheading = Important uktr.UkTaxReturnStart.inactive.p1 = Your account has a Below Threshold Notification (BTN) and is inactive. Submit a UK tax return (UKTR) to re-activate your account. +############################################### +# +# Below Threshold Notification +# +############################################### + btn.BtnBeforeStart.title = Below Threshold Notification btn.BtnBeforeStart.header = Below Threshold Notification btn.BtnBeforeStart.p1 = A Below-Threshold Notification removes your group’s obligation to submit a UKTR for the current accounting period and all future ones. @@ -205,7 +211,6 @@ btn.btnEntitiesBothInUKAndOutside.amend.p2 = If this has changed, you must btn.btnEntitiesBothInUKAndOutside.amend.p2.link = amend your group’s details btn.btnEntitiesBothInUKAndOutside.amend.p2.end = to update the location of your entities before submitting a BTN. - btnRevenues750In2AccountingPeriod.title = Did the group have consolidated annual revenues of €750 million or more in at least 2 of the previous 4 accounting periods? btnRevenues750In2AccountingPeriod.heading = Did the group have consolidated annual revenues of €750 million or more in at least 2 of the previous 4 accounting periods? btnRevenues750In2AccountingPeriod.checkYourAnswersLabel = Did the group have consolidated annual revenues of €750 million or more in at least 2 of the previous 4 accounting periods. @@ -223,3 +228,10 @@ btn.btnSubmitUKTR.heading = Based on your answer, your group must submit a UK Ta btn.btnSubmitUKTR.p1 = Based on your answer, you cannot submit a Below-Threshold Notification as the group is expected to make consolidated annual revenues of €750 million or more within the next 2 accounting periods. btn.btnSubmitUKTR.p2 = You can submit a nil return UK Tax Return if your group is not due to pay any Domestic Top-up Tax for their current accounting period. btn.btnSubmitUKTR.link = Find out more about submitting a late or new UK Tax Return + +btn.thresholdMet.title = Based on your answer, your group must submit a UK Tax Return +btn.thresholdMet.heading = Based on your answer, your group must submit a UK Tax Return +btn.thresholdMet.p1 = Based on your answer, you cannot submit a Below-Threshold Notification as your group has made consolidated annual revenues of €750 million or more in at least 2 of the previous 4 accounting periods. +btn.thresholdMet.p2 = Your group must still submit a UK Tax Return. +btn.thresholdMet.link = Find out more about submitting a UKTR +############################################### diff --git a/test/controllers/btn/BtnRevenues750In2AccountingPeriodControllerSpec.scala b/test/controllers/btn/BtnRevenues750In2AccountingPeriodControllerSpec.scala index 7ac4653..bb65a1f 100644 --- a/test/controllers/btn/BtnRevenues750In2AccountingPeriodControllerSpec.scala +++ b/test/controllers/btn/BtnRevenues750In2AccountingPeriodControllerSpec.scala @@ -32,7 +32,7 @@ import repositories.SessionRepository import uk.gov.hmrc.auth.core.AffinityGroup.Agent import uk.gov.hmrc.auth.core._ import uk.gov.hmrc.auth.core.retrieve.{Credentials, ~} -import views.html.btn.BtnRevenues750In2AccountingPeriodView +import views.html.btn.{BtnRevenues750In2AccountingPeriodView, BtnThresholdMetView} import java.util.UUID import scala.concurrent.Future @@ -44,6 +44,7 @@ class BtnRevenues750In2AccountingPeriodControllerSpec extends SpecBase with Mock lazy val btnRevenues750In2AccountingPeriodRoute: String = controllers.btn.routes.BtnRevenues750In2AccountingPeriodController.onPageLoad(NormalMode).url + lazy val thresholdMetRoute: String = controllers.btn.routes.BtnRevenues750In2AccountingPeriodController.onPageLoadThresholdMet.url private type RetrievalsType = Option[String] ~ Enrolments ~ Option[AffinityGroup] ~ Option[CredentialRole] ~ Option[Credentials] @@ -160,7 +161,7 @@ class BtnRevenues750In2AccountingPeriodControllerSpec extends SpecBase with Mock val result = route(application, request).value status(result) mustEqual SEE_OTHER - redirectLocation(result).value mustEqual controllers.routes.UnderConstructionController.onPageLoad.url + redirectLocation(result).value mustEqual thresholdMetRoute } } @@ -184,5 +185,28 @@ class BtnRevenues750In2AccountingPeriodControllerSpec extends SpecBase with Mock } } + "must return OK and the correct view for a GET threshold met" in { + + val application = applicationBuilder(userAnswers = Some(emptyUserAnswers), enrolments) + .overrides( + bind[SessionRepository].toInstance(mockSessionRepository) + ) + .build() + + running(application) { + val request = FakeRequest(GET, thresholdMetRoute) + when(mockSessionRepository.get(any())) + .thenReturn(Future.successful(Some(emptyUserAnswers))) + when(mockSessionRepository.set(any())) + .thenReturn(Future.successful(true)) + + val result = route(application, request).value + + val view = application.injector.instanceOf[BtnThresholdMetView] + status(result) mustEqual OK + contentAsString(result) mustEqual view()(request, appConfig(application), messages(application)).toString + } + } + } } diff --git a/test/navigation/BtnNavigatorSpec.scala b/test/navigation/BtnNavigatorSpec.scala index 38c83d6..43a667c 100644 --- a/test/navigation/BtnNavigatorSpec.scala +++ b/test/navigation/BtnNavigatorSpec.scala @@ -51,7 +51,7 @@ class BtnNavigatorSpec extends SpecBase { NormalMode, emptyUserAnswers.setOrException(BtnRevenues750In2AccountingPeriodPage, true) ) mustBe - controllers.routes.UnderConstructionController.onPageLoad + controllers.btn.routes.BtnRevenues750In2AccountingPeriodController.onPageLoadThresholdMet } "go from BtnRevenues750In2AccountingPeriodPage period page to UnderConstruction page " in { diff --git a/test/views/btn/BtnThresholdMetViewSpec.scala b/test/views/btn/BtnThresholdMetViewSpec.scala new file mode 100644 index 0000000..5a1f0e2 --- /dev/null +++ b/test/views/btn/BtnThresholdMetViewSpec.scala @@ -0,0 +1,60 @@ +/* + * Copyright 2024 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 views.btn + +import base.ViewSpecBase +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import views.html.btn.BtnThresholdMetView + +class BtnThresholdMetViewSpec extends ViewSpecBase { + + val page: BtnThresholdMetView = inject[BtnThresholdMetView] + val view: Document = Jsoup.parse(page()(request, appConfig, messages).toString()) + + "Btn Threshold Met View" should { + + "have a back link" in { + view.getElementsByClass("govuk-back-link").text must include("Back") + } + + "have a title" in { + view.getElementsByTag("title").text must include("Based on your answer, your group must submit a UK Tax Return") + } + + "have a h1 heading" in { + view.getElementsByTag("h1").text must include("Based on your answer, your group must submit a UK Tax Return") + } + + "have paragraph content" in { + view.getElementsByClass("govuk-body").first().text() must include( + "Based on your answer, you cannot submit a Below-Threshold Notification as your group has made consolidated annual revenues of €750 million or more in at least 2 of the previous 4 accounting periods." + ) + view.getElementsByClass("govuk-body").get(1).text() must include( + "Your group must still submit a UK Tax Return." + ) + } + + "have a link" in { + val link = view.getElementsByClass("govuk-body").last().getElementsByTag("a") + + link.text must include("Find out more about submitting a UKTR") + link.attr("href") must include("/report-pillar2-submission-top-up-taxes/uk-tax-return") + } + + } +}