Skip to content

Commit 5f821cb

Browse files
scott-goodwinanthoskountouris
authored andcommitted
Merge pull request #64 from hmrc/DTR-1609-checkPurchaserType
DTR-1609: Adds .checkPurchaserType in PuchraserService and tests
2 parents efef4b4 + 26068f8 commit 5f821cb

File tree

11 files changed

+656
-11
lines changed

11 files changed

+656
-11
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2025 HM Revenue & Customs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package controllers.purchaser
18+
19+
import controllers.actions.*
20+
import forms.purchaser.PurchaserCTUTRFormProvider
21+
import models.purchaser.WhoIsMakingThePurchase
22+
import models.purchaser.WhoIsMakingThePurchase.Company
23+
import models.{Mode, NormalMode}
24+
import navigation.Navigator
25+
import pages.purchaser.{NameOfPurchaserPage, PurchaserCTUTRPage, WhoIsMakingThePurchasePage}
26+
import play.api.i18n.{I18nSupport, MessagesApi}
27+
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
28+
import repositories.SessionRepository
29+
import services.purchaser.PurchaserService
30+
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
31+
import views.html.purchaser.PurchaserCTUTRView
32+
33+
import javax.inject.Inject
34+
import scala.concurrent.{ExecutionContext, Future}
35+
36+
class PurchaserCTUTRController @Inject()(
37+
override val messagesApi: MessagesApi,
38+
sessionRepository: SessionRepository,
39+
navigator: Navigator,
40+
identify: IdentifierAction,
41+
getData: DataRetrievalAction,
42+
requireData: DataRequiredAction,
43+
purchaserService: PurchaserService,
44+
formProvider: PurchaserCTUTRFormProvider,
45+
val controllerComponents: MessagesControllerComponents,
46+
view: PurchaserCTUTRView
47+
)(implicit ec: ExecutionContext) extends FrontendBaseController with I18nSupport {
48+
49+
val form = formProvider()
50+
51+
def onPageLoad(mode: Mode): Action[AnyContent] = (identify andThen getData andThen requireData) {
52+
implicit request =>
53+
54+
val userAnswers = request.userAnswers
55+
56+
userAnswers.get(NameOfPurchaserPage) match {
57+
case None => Redirect(controllers.purchaser.routes.NameOfPurchaserController.onPageLoad(NormalMode))
58+
59+
case Some(value) =>
60+
val purchaserName: String = value.fullName
61+
62+
val preparedForm = request.userAnswers.get(PurchaserCTUTRPage) match {
63+
case None => form
64+
case Some(value) => form.fill(value)
65+
}
66+
67+
val continueRoute = Ok(view(preparedForm, purchaserName, mode))
68+
purchaserService.checkPurchaserType(Company, userAnswers, continueRoute)
69+
}
70+
}
71+
72+
def onSubmit(mode: Mode): Action[AnyContent] = (identify andThen getData andThen requireData).async {
73+
implicit request =>
74+
75+
request.userAnswers.get(NameOfPurchaserPage) match {
76+
case None => Future.successful(Redirect(controllers.purchaser.routes.NameOfPurchaserController.onPageLoad(NormalMode)))
77+
78+
case Some(value) =>
79+
val purchaserName: String = value.fullName
80+
81+
form.bindFromRequest().fold(
82+
formWithErrors =>
83+
Future.successful(BadRequest(view(formWithErrors, purchaserName, mode))),
84+
85+
value =>
86+
for {
87+
updatedAnswers <- Future.fromTry(request.userAnswers.set(PurchaserCTUTRPage, value))
88+
_ <- sessionRepository.set(updatedAnswers)
89+
} yield Redirect(navigator.nextPage(PurchaserCTUTRPage, mode, updatedAnswers))
90+
)
91+
}
92+
}
93+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2025 HM Revenue & Customs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package forms.purchaser
18+
19+
import forms.mappings.Mappings
20+
import play.api.data.Form
21+
import play.api.data.validation.Constraints.minLength
22+
23+
import javax.inject.Inject
24+
25+
class PurchaserCTUTRFormProvider @Inject() extends Mappings {
26+
27+
private val formNumberRegex = "^[0-9]*$"
28+
29+
30+
def apply(): Form[String] =
31+
Form(
32+
"value" -> text("purchaser.purchaserCTUTR.error.required")
33+
.verifying(maxLength(13, "purchaser.purchaserCTUTR.error.length"))
34+
.verifying(minLength(10, "purchaser.purchaserCTUTR.error.length"))
35+
.verifying(regexp(formNumberRegex, "purchaser.purchaserCTUTR.error.invalid"))
36+
37+
)
38+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2025 HM Revenue & Customs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package pages.purchaser
18+
19+
import pages.QuestionPage
20+
import play.api.libs.json.JsPath
21+
22+
case object PurchaserCTUTRPage extends QuestionPage[String] {
23+
24+
override def path: JsPath = JsPath \ "purchaserCurrent" \ toString
25+
26+
override def toString: String = "purchaserCTUTR"
27+
}

app/services/purchaser/PurchaserService.scala

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
package services.purchaser
1818

19-
import models.UserAnswers
2019
import models.*
2120
import models.purchaser.*
22-
import models.address.*
23-
import pages.purchaser.{ConfirmNameOfThePurchaserPage, NameOfPurchaserPage}
21+
import pages.purchaser.{ConfirmNameOfThePurchaserPage, NameOfPurchaserPage, WhoIsMakingThePurchasePage}
22+
import play.api.mvc.Result
23+
import play.api.mvc.Results.Redirect
2424

2525
import scala.util.Try
2626

@@ -73,4 +73,14 @@ class PurchaserService {
7373
userAnswers.set(ConfirmNameOfThePurchaserPage, confirmName)
7474
}
7575
}
76+
77+
def checkPurchaserType(purchaserType: WhoIsMakingThePurchase, userAnswers: UserAnswers, continueRoute: Result): Result =
78+
userAnswers.get(WhoIsMakingThePurchasePage) match {
79+
case Some(value) if value == purchaserType =>
80+
continueRoute
81+
case Some(_) =>
82+
Redirect(controllers.routes.GenericErrorController.onPageLoad()) // TODO DTR-1788: redirect to CYA
83+
case None =>
84+
Redirect(controllers.purchaser.routes.WhoIsMakingThePurchaseController.onPageLoad(NormalMode))
85+
}
7686
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2025 HM Revenue & Customs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package viewmodels.checkAnswers.purchaser
18+
19+
import controllers.purchaser.routes
20+
import models.{CheckMode, UserAnswers}
21+
import pages.purchaser.PurchaserCTUTRPage
22+
import play.api.i18n.Messages
23+
import play.twirl.api.HtmlFormat
24+
import uk.gov.hmrc.govukfrontend.views.viewmodels.summarylist.SummaryListRow
25+
import viewmodels.govuk.summarylist.*
26+
import viewmodels.implicits.*
27+
28+
object PurchaserCTUTRSummary {
29+
30+
def row(answers: UserAnswers)(implicit messages: Messages): Option[SummaryListRow] =
31+
answers.get(PurchaserCTUTRPage).map {
32+
answer =>
33+
34+
SummaryListRowViewModel(
35+
key = "purchaser.purchaserCTUTR.checkYourAnswersLabel",
36+
value = ValueViewModel(HtmlFormat.escape(answer).toString),
37+
actions = Seq(
38+
ActionItemViewModel("site.change", controllers.purchaser.routes.PurchaserCTUTRController.onPageLoad(CheckMode).url)
39+
.withVisuallyHiddenText(messages("purchaser.purchaserCTUTR.change.hidden"))
40+
)
41+
)
42+
}
43+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
@*
2+
* Copyright 2025 HM Revenue & Customs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*@
16+
17+
@import viewmodels.InputWidth._
18+
@import viewmodels.LabelSize.Medium
19+
@import views.html.components.h1
20+
@import views.html.components.p
21+
22+
@this(
23+
layout: templates.Layout,
24+
formHelper: FormWithCSRF,
25+
govukErrorSummary: GovukErrorSummary,
26+
govukInput: GovukInput,
27+
govukButton: GovukButton,
28+
h1: h1,
29+
p:p
30+
)
31+
32+
@(form: Form[_], purchaserName: String, mode: Mode)(implicit request: Request[_], messages: Messages)
33+
34+
@layout(pageTitle = title(form, messages("purchaser.purchaserCTUTR.title"))) {
35+
36+
@formHelper(action = controllers.purchaser.routes.PurchaserCTUTRController.onSubmit(mode)) {
37+
38+
@if(form.errors.nonEmpty) {
39+
@govukErrorSummary(ErrorSummaryViewModel(form))
40+
}
41+
42+
<div class="govuk-caption-l">@messages("purchaser.caption")</div>
43+
@h1(messages("purchaser.purchaserCTUTR.h1", purchaserName))
44+
@p(Html(messages("purchaser.purchaserCTUTR.p")))
45+
46+
@govukInput(
47+
InputViewModel(
48+
field = form("value"),
49+
label = LabelViewModel(messages("purchaser.purchaserCTUTR.h2", purchaserName)).asPageHeading(size = Medium)
50+
)
51+
.withWidth(Full)
52+
.withHint(HintViewModel(HtmlContent(Html(messages("purchaser.purchaserCTUTR.hint")))))
53+
)
54+
55+
@govukButton(
56+
ButtonViewModel(messages("site.save.continue"))
57+
)
58+
}
59+
}

conf/app.routes

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,9 @@ POST /about-the-purchaser/enter-national-insurance-number/change
163163
GET /about-the-purchaser/add-national-insurance-number controllers.purchaser.DoesPurchaserHaveNIController.onPageLoad(mode: Mode = NormalMode)
164164
POST /about-the-purchaser/add-national-insurance-number controllers.purchaser.DoesPurchaserHaveNIController.onSubmit(mode: Mode = NormalMode)
165165
GET /about-the-purchaser/add-national-insurance-number/change controllers.purchaser.DoesPurchaserHaveNIController.onPageLoad(mode: Mode = CheckMode)
166-
POST /about-the-purchaser/add-national-insurance-number/change controllers.purchaser.DoesPurchaserHaveNIController.onSubmit(mode: Mode = CheckMode)
166+
POST /about-the-purchaser/add-national-insurance-number/change controllers.purchaser.DoesPurchaserHaveNIController.onSubmit(mode: Mode = CheckMode)
167+
168+
GET /about-the-purchaser/corporation-tax-utr controllers.purchaser.PurchaserCTUTRController.onPageLoad(mode: Mode = NormalMode)
169+
POST /about-the-purchaser/corporation-tax-utr controllers.purchaser.PurchaserCTUTRController.onSubmit(mode: Mode = NormalMode)
170+
GET /about-the-purchaser/corporation-tax-utr/change controllers.purchaser.PurchaserCTUTRController.onPageLoad(mode: Mode = CheckMode)
171+
POST /about-the-purchaser/corporation-tax-utr/change controllers.purchaser.PurchaserCTUTRController.onSubmit(mode: Mode = CheckMode)

conf/messages.en

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,3 +507,14 @@ purchaserDateOfBirth.error.required = The date must include {0}
507507
purchaserDateOfBirth.error.invalid = Enter a valid date
508508
purchaserDateOfBirth.change.hidden = Purchaser’s date of birth
509509
PurchaserDateOfBirth.error.date.range.max = Date cannot be in the future
510+
511+
purchaser.purchaserCTUTR.title = What is the purchaser’s Corporation Tax Unique Taxpayer Reference (UTR)? - About the purchaser
512+
purchaser.purchaserCTUTR.h1 = {0}’s Corporation Tax Unique Taxpayer Reference (UTR)
513+
purchaser.purchaserCTUTR.p = It will be on tax returns and other letters about Corporation Tax. It might be called 'reference', 'UTR' or 'official use'.
514+
purchaser.purchaserCTUTR.h2 = What is {0}’s Corporation Tax UTR?
515+
purchaser.purchaserCTUTR.hint = Their UTR can be 10 or 13 digits long
516+
purchaser.purchaserCTUTR.checkYourAnswersLabel = Corporation Tax Unique Taxpayer Reference (UTR)
517+
purchaser.purchaserCTUTR.error.required = Enter Corporation Tax Unique Taxpayer Reference (UTR)
518+
purchaser.purchaserCTUTR.error.length = Corporation Tax Unique Taxpayer Reference (UTR) must be between 10 and 13 characters
519+
purchaser.purchaserCTUTR.error.invalid = Enter a valid UTR
520+
purchaserCTUTR.change.hidden = Corporation Tax Unique Taxpayer Reference (UTR)

0 commit comments

Comments
 (0)