Skip to content

Commit

Permalink
Merge pull request #6 from hmrc/ADR-743
Browse files Browse the repository at this point in the history
ADR-743 Add product name page
  • Loading branch information
yasaracar authored Nov 21, 2023
2 parents f17164d + 02a6325 commit 4ef63a2
Show file tree
Hide file tree
Showing 16 changed files with 470 additions and 6 deletions.
71 changes: 71 additions & 0 deletions app/controllers/ProductNameController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2023 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 controllers

import connectors.CacheConnector
import controllers.actions._
import forms.ProductNameFormProvider

import javax.inject.Inject
import models.{Mode, UserAnswers}
import navigation.Navigator
import pages.ProductNamePage
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import views.html.ProductNameView

import scala.concurrent.{ExecutionContext, Future}

class ProductNameController @Inject() (
override val messagesApi: MessagesApi,
cacheConnector: CacheConnector,
navigator: Navigator,
identify: IdentifierAction,
getData: DataRetrievalAction,
formProvider: ProductNameFormProvider,
val controllerComponents: MessagesControllerComponents,
view: ProductNameView
)(implicit ec: ExecutionContext)
extends FrontendBaseController
with I18nSupport {

val form = formProvider()

def onPageLoad(mode: Mode): Action[AnyContent] = (identify andThen getData) { implicit request =>
val preparedForm = request.userAnswers.flatMap(_.get(ProductNamePage)) match {
case None => form
case Some(value) => form.fill(value)
}

Ok(view(preparedForm, mode))
}

def onSubmit(mode: Mode): Action[AnyContent] = (identify andThen getData).async { implicit request =>
form
.bindFromRequest()
.fold(
formWithErrors => Future.successful(BadRequest(view(formWithErrors, mode))),
value =>
for {
updatedAnswers <-
Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.userId)).set(ProductNamePage, value))
_ <- cacheConnector.set(updatedAnswers)
} yield Redirect(navigator.nextPage(ProductNamePage, mode, updatedAnswers))
)
}
}
31 changes: 31 additions & 0 deletions app/forms/ProductNameFormProvider.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2023 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 forms

import javax.inject.Inject

import forms.mappings.Mappings
import play.api.data.Form

class ProductNameFormProvider @Inject() extends Mappings {

def apply(): Form[String] =
Form(
"value" -> text("productName.error.required")
.verifying(maxLength(50, "productName.error.length"))
)
}
26 changes: 26 additions & 0 deletions app/pages/ProductNamePage.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2023 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 pages

import play.api.libs.json.JsPath

case object ProductNamePage extends QuestionPage[String] {

override def path: JsPath = JsPath \ toString

override def toString: String = "productName"
}
41 changes: 41 additions & 0 deletions app/viewmodels/checkAnswers/ProductNameSummary.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2023 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 viewmodels.checkAnswers

import controllers.routes
import models.{CheckMode, UserAnswers}
import pages.ProductNamePage
import play.api.i18n.Messages
import play.twirl.api.HtmlFormat
import uk.gov.hmrc.govukfrontend.views.viewmodels.summarylist.SummaryListRow
import viewmodels.govuk.summarylist._
import viewmodels.implicits._

object ProductNameSummary {

def row(answers: UserAnswers)(implicit messages: Messages): Option[SummaryListRow] =
answers.get(ProductNamePage).map { answer =>
SummaryListRowViewModel(
key = "productName.checkYourAnswersLabel",
value = ValueViewModel(HtmlFormat.escape(answer).toString),
actions = Seq(
ActionItemViewModel("site.change", routes.ProductNameController.onPageLoad(CheckMode).url)
.withVisuallyHiddenText(messages("productName.change.hidden"))
)
)
}
}
3 changes: 2 additions & 1 deletion app/viewmodels/govuk/ButtonFluency.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ trait ButtonFluency {

object ButtonViewModel {

def apply(content: Content): Button =
def apply(id: String, content: Content): Button =
Button(
id = Some(id),
element = Some("button"),
content = content
)
Expand Down
3 changes: 3 additions & 0 deletions app/viewmodels/govuk/LabelFluency.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@ trait LabelFluency {

def forAttr(attr: String): Label =
label.copy(forAttr = Some(attr))

def asVisuallyHidden(): Label =
withCssClass("govuk-visually-hidden")
}
}
2 changes: 1 addition & 1 deletion app/views/DraughtReliefQuestionView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
)

@govukButton(
ButtonViewModel(messages("site.saveAndContinue"))
ButtonViewModel("saveAndContinueButton", messages("site.saveAndContinue"))
)
}
}
2 changes: 1 addition & 1 deletion app/views/JourneyRecoveryContinueView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ <h1 class="govuk-heading-xl">@messages("journeyRecovery.continue.heading")</h1>

<p class="govuk-body">
@govukButton(
ButtonViewModel(messages("site.continue"))
ButtonViewModel("continueButton", messages("site.continue"))
.asLink(continueUrl)
)
</p>
Expand Down
2 changes: 1 addition & 1 deletion app/views/JourneyRecoveryStartAgainView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ <h1 class="govuk-heading-xl">@messages("journeyRecovery.startAgain.heading")</h1

<p class="govuk-body">
@govukButton(
ButtonViewModel(messages("site.startAgain"))
ButtonViewModel("startAgainButton", messages("site.startAgain"))
.asLink(routes.IndexController.onPageLoad.url)
)
</p>
Expand Down
63 changes: 63 additions & 0 deletions app/views/ProductNameView.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
@*
* Copyright 2023 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 viewmodels.InputWidth._
@import components.{SectionHeading, PageHeading}

@this(
layout: templates.Layout,
formHelper: FormWithCSRF,
govukErrorSummary: GovukErrorSummary,
govukInput: GovukInput,
govukButton: GovukButton,
sectionHeading: SectionHeading,
pageHeading: PageHeading
)

@(form: Form[_], mode: Mode)(implicit request: Request[_], messages: Messages)

@layout(pageTitle = title(form, messages("productName.title"))) {

@if(form.errors.nonEmpty) {
@govukErrorSummary(ErrorSummaryViewModel(form))
}

@sectionHeading(
id = "product-name-section",
text = messages("section.alcoholDutyReturn"),
)

@pageHeading(messages("productName.heading"))

<p class="govuk-body">@messages("productName.p1")</p>

<p class="govuk-body">@messages("productName.p2")</p>

@formHelper(action = routes.ProductNameController.onSubmit(mode)) {

@govukInput(
InputViewModel(
field = form("value"),
label = LabelViewModel(messages("productName.heading")).asVisuallyHidden()
)
.withWidth(Fixed30)
)

@govukButton(
ButtonViewModel("saveAndContinueButton", messages("site.saveAndContinue"))
)
}
}
2 changes: 1 addition & 1 deletion app/views/SmallProducerReliefQuestionView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
)

@govukButton(
ButtonViewModel(messages("site.saveAndContinue"))
ButtonViewModel("saveAndContinueButton", messages("site.saveAndContinue"))
)
}
}
2 changes: 1 addition & 1 deletion app/views/auth/SignedOutView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h1 class="govuk-heading-xl">@messages("signedOut.heading")</h1>

<p class="govuk-body">
@govukButton(
ButtonViewModel(messages("site.signIn"))
ButtonViewModel("signInButton", messages("site.signIn"))
.asLink(routes.IndexController.onPageLoad.url)
)
</p>
Expand Down
7 changes: 7 additions & 0 deletions conf/app.routes
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ POST /draughtReliefQuestion controllers.DraughtReli
GET /changeDraughtReliefQuestion controllers.DraughtReliefQuestionController.onPageLoad(mode: Mode = CheckMode)
POST /changeDraughtReliefQuestion controllers.DraughtReliefQuestionController.onSubmit(mode: Mode = CheckMode)


GET /productName controllers.ProductNameController.onPageLoad(mode: Mode = NormalMode)
POST /productName controllers.ProductNameController.onSubmit(mode: Mode = NormalMode)
GET /changeProductName controllers.ProductNameController.onPageLoad(mode: Mode = CheckMode)
POST /changeProductName controllers.ProductNameController.onSubmit(mode: Mode = CheckMode)

GET /smallProducerReliefQuestion controllers.SmallProducerReliefQuestionController.onPageLoad(mode: Mode = NormalMode)
POST /smallProducerReliefQuestion controllers.SmallProducerReliefQuestionController.onSubmit(mode: Mode = NormalMode)
GET /changeSmallProducerReliefQuestion controllers.SmallProducerReliefQuestionController.onPageLoad(mode: Mode = CheckMode)
POST /changeSmallProducerReliefQuestion controllers.SmallProducerReliefQuestionController.onSubmit(mode: Mode = CheckMode)

9 changes: 9 additions & 0 deletions conf/messages.en
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ draughtReliefQuestion.error.required = Select yes if this product is eligible fo
draughtReliefQuestion.guidance.link.url = https://www.gov.uk/guidance/check-if-you-can-pay-less-alcohol-duty-on-draught-products
draughtReliefQuestion.guidance.link.text = You can get a reduced rate of duty on some draught products (opens in a new tab)

productName.title = What name do you want to give this product?
productName.heading = What name do you want to give this product?
productName.p1 = Give your product a name so you can identify it on your return.
productName.p2 = You may want to use an internal reference number or a description of the product's alcohol type and ABV strength. For example, ‘Beer, 5.3%’
productName.checkYourAnswersLabel = Name
productName.error.required = Enter the name you want to give this product
productName.error.length = Product name must be 50 characters or less
productName.change.hidden = name

smallProducerReliefQuestion.title = Is this product eligible for Small Producer Relief?
smallProducerReliefQuestion.heading = Is this product eligible for Small Producer Relief?
smallProducerReliefQuestion.error.required = Select yes if this product is eligible for Small Producer Relief
Expand Down
Loading

0 comments on commit 4ef63a2

Please sign in to comment.