Skip to content

Commit

Permalink
PIL-937 - Add btn confirmation page (#23)
Browse files Browse the repository at this point in the history
* PIL-937 - Add btn confirmation page

* PIL-937 - Navigate to confirmation page

* PIL-937 - Update css
  • Loading branch information
TevynAllen authored Nov 11, 2024
1 parent 734caaa commit e546b44
Show file tree
Hide file tree
Showing 17 changed files with 646 additions and 9 deletions.
20 changes: 20 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,23 @@
.js-enabled .js-visible {
display: inline-block !important;
}

@media print {

.govuk-link {
pointer-events: none !important;
cursor: default !important;
text-decoration: none !important;
color: black !important;
}

#print-this-page, .hmrc-sign-out-nav, .govuk-footer, #back-link {
display: none !important;
}
.govuk-grid-column-two-thirds {
width:100%;
}
a[href]:after {
content: none !important;
}
}
31 changes: 31 additions & 0 deletions app/config/FopFactoryProvider.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 config

import org.apache.fop.apps.{FopFactory, FopFactoryBuilder}
import play.api.Environment

import javax.inject.{Inject, Provider, Singleton}

@Singleton
class FopFactoryProvider @Inject() (
environment: Environment
) extends Provider[FopFactory] {
override def get(): FopFactory =
new FopFactoryBuilder(environment.rootPath.toURI)
.build()
}
3 changes: 2 additions & 1 deletion app/config/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package config
import com.google.inject.name.{Named, Names}
import com.google.inject.{AbstractModule, Provides}
import controllers.actions._
import org.apache.fop.apps.FopFactory
import play.api.{Configuration, Environment}
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig

Expand All @@ -36,7 +37,7 @@ class Module(environment: Environment, configuration: Configuration) extends Abs
// For session based storage instead of cred based, change to SessionIdentifierAction
bind(classOf[IdentifierAction]).to(classOf[AuthenticatedIdentifierAction]).asEagerSingleton()
bind(classOf[IdentifierAction]).annotatedWith(Names.named("EnrolmentIdentifier")).to(classOf[EnrolmentIdentifierAction]).asEagerSingleton()

bind(classOf[FopFactory]).toProvider(classOf[FopFactoryProvider])
bind(classOf[Clock]).toInstance(Clock.systemDefaultZone.withZone(ZoneOffset.UTC))
}

Expand Down
64 changes: 64 additions & 0 deletions app/controllers/btn/BtnConfirmationController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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 controllers.btn

import config.FrontendAppConfig
import controllers.actions.{IdentifierAction, SubscriptionDataRequiredAction, SubscriptionDataRetrievalAction}
import play.api.i18n.I18nSupport
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import services.FopService
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import utils.ViewHelpers
import views.html.btn.BtnConfirmationView
import views.xml.pdf.BtnConfirmationPdf

import java.time.LocalDate
import javax.inject.{Inject, Named}
import scala.concurrent.ExecutionContext

class BtnConfirmationController @Inject() (
val controllerComponents: MessagesControllerComponents,
getData: SubscriptionDataRetrievalAction,
requireData: SubscriptionDataRequiredAction,
dateHelper: ViewHelpers,
fopService: FopService,
@Named("EnrolmentIdentifier") identify: IdentifierAction,
view: BtnConfirmationView,
confirmationPdf: BtnConfirmationPdf
)(implicit ec: ExecutionContext, appConfig: FrontendAppConfig)
extends FrontendBaseController
with I18nSupport {

def onPageLoad: Action[AnyContent] = (identify andThen getData andThen requireData) { implicit request =>
val currentDate = dateHelper.formatDateGDS(LocalDate.now())
val startDate = dateHelper.formatDateGDS(request.subscriptionLocalData.subAccountingPeriod.startDate)

Ok(view(currentDate, startDate))
}

def onDownloadConfirmation: Action[AnyContent] = (identify andThen getData andThen requireData).async { implicit request =>
val currentDate = dateHelper.formatDateGDS(LocalDate.now())
val startDate = dateHelper.formatDateGDS(request.subscriptionLocalData.subAccountingPeriod.startDate)

for {
pdf <- fopService.render(confirmationPdf.render(currentDate, startDate, implicitly, implicitly).body)
} yield Ok(pdf)
.as("application/octet-stream")
.withHeaders(CONTENT_DISPOSITION -> "attachment; filename=below-threshold-notification-confirmation.pdf")
}

}
2 changes: 1 addition & 1 deletion app/controllers/btn/CheckYourAnswersController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@ class CheckYourAnswersController @Inject() (
}

def onSubmit: Action[AnyContent] = (identify andThen getData andThen requireData) {
Redirect(UnderConstructionController.onPageLoad)
Redirect(controllers.btn.routes.BtnConfirmationController.onPageLoad)
}
}
64 changes: 64 additions & 0 deletions app/services/FopService.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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 services

import org.apache.commons.io.output.ByteArrayOutputStream
import org.apache.fop.apps.{FOUserAgent, FopFactory}
import org.apache.xmlgraphics.util.MimeConstants

import java.io.StringReader
import javax.inject.{Inject, Singleton}
import javax.xml.transform.TransformerFactory
import javax.xml.transform.sax.SAXResult
import javax.xml.transform.stream.StreamSource
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class FopService @Inject() (
fopFactory: FopFactory
)(implicit ec: ExecutionContext) {

private val userAgentBlock: FOUserAgent => Unit = { foUserAgent =>
foUserAgent.setAccessibility(true)
foUserAgent.setPdfUAEnabled(true)
foUserAgent.setAuthor("HMRC forms service")
foUserAgent.setProducer("HMRC forms services")
foUserAgent.setCreator("HMRC forms services")
foUserAgent.setSubject("Report Pillar 2 top-up taxes")
foUserAgent.setTitle("Report Pillar 2 top-up taxes")
}

def render(input: String): Future[Array[Byte]] = Future {

val out = new ByteArrayOutputStream()

val userAgent = fopFactory.newFOUserAgent()
userAgentBlock(userAgent)

val fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out)

val transformerFactory = TransformerFactory.newInstance()
val transformer = transformerFactory.newTransformer()

val source = new StreamSource(new StringReader(input))
val result = new SAXResult(fop.getDefaultHandler)

transformer.transform(source, result)

out.toByteArray
}
}
54 changes: 54 additions & 0 deletions app/views/btn/BtnConfirmationView.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
@*
* 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 config.FrontendAppConfig
@import views.html.components.gds._

@this(
layout: templates.Layout,
formHelper: FormWithCSRF,
p: ParagraphBody,
paragraphMessageWithLink: ParagraphMessageWithLink,
link: Link,
printLink: PrintLink,
pdfLink: PDFLink,
govukButton: GovukButton,
govukPanel: GovukPanel,
h2: HeadingH2
)


@(submissionDate: String, accountingPeriodStartDate: String)(implicit request: Request[_], appConfig: FrontendAppConfig, messages: Messages)

@layout(pageTitle = titleNoForm(messages("btn.confirmation.title")), showBackLink = false) {

@govukPanel(Panel(
title = Text(messages("btn.confirmation.heading")),
content = HtmlContent(""),
attributes = Map("id" -> "plr2-banner")
))

@p(messages("btn.confirmation.p1", submissionDate, accountingPeriodStartDate))

@printLink(messages("site.print"))
@pdfLink(messages("site.pdf"), controllers.btn.routes.BtnConfirmationController.onDownloadConfirmation.url)

@h2(messages("btn.confirmation.subheading"))
@p(messages("btn.confirmation.p2"))
@paragraphMessageWithLink(message1 = Some(messages("btn.confirmation.p3")), linkMessage = messages("btn.confirmation.p3.link"), linkUrl = controllers.uktr.routes.UkTaxReturnStartController.onPageLoad.url, linkFullStop = true, classes = "govuk-body hmrc-!-js-visible")
@paragraphMessageWithLink(linkMessage = messages("btn.confirmation.p4.link"), linkUrl = appConfig.pillar2FrontendUrl, classes = "govuk-body govuk-!-display-none-print")

}
25 changes: 25 additions & 0 deletions app/views/components/gds/PDFLink.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@*
* 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.
*@

@this()

@(message: String, url: String)

<p id="download" class="govuk-list govuk-link print-link hmrc-!-js-visible govuk-!-display-none-print">
<a href="@url" role="button" class="govuk-link govuk-link--no-visited-state hmrc-!-js-visible" data-module="print-link">
@message
</a>
</p>
76 changes: 76 additions & 0 deletions app/views/pdf/BtnConfirmationPdf.scala.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
@*
* Copyright 2022 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.
*@

@this()

@(currentDate: String, startDate: String)(implicit request: RequestHeader, messages: Messages)

<fo:root xml:lang="@messages.lang.locale.getLanguage" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" font-family="sans-serif">

<fo:layout-master-set>
<fo:simple-page-master master-name="main" page-height="297mm" page-width="210mm" margin="2cm">
<fo:region-body region-name="xsl-region-body" margin-top="3cm"/>
<fo:region-before region-name="xsl-region-before"/>
<fo:region-after region-name="xsl-region-after"/>
</fo:simple-page-master>
</fo:layout-master-set>

<fo:declarations>
<pdf:catalog xmlns:pdf="http://xmlgraphics.apache.org/fop/extensions/pdf">
<pdf:dictionary type="normal" key="ViewerPreferences">
<pdf:boolean key="DisplayDocTitle">true</pdf:boolean>
</pdf:dictionary>
</pdf:catalog>
</fo:declarations>

<fo:page-sequence master-reference="main">

<!-- Header -->
<fo:static-content flow-name="xsl-region-before">
<fo:block border-color="#1d70b8" border-after-style="solid" border-after-width="5pt">
<fo:external-graphic content-width="148px" content-height="20px"
src="url(conf/resources/gov-uk-logo.png)" padding-right="1cm"
fox:alt-text="GOV.UK"/>
<fo:block role="H1" font-size="16pt" font-weight="bold" margin-bottom="1mm">@messages("service.name")
</fo:block>
</fo:block>
</fo:static-content>

<!-- Body -->
<fo:flow flow-name="xsl-region-body">
<fo:block-container margin-bottom="10mm">

<!-- Confirmation Banner -->
<fo:block-container border-color="#000000" border-style="solid" border-width="4pt" margin-bottom="10mm" text-align="center">
<fo:block role="H1" id="repayment-submission-title" font-size="24pt" font-weight="bold" margin-bottom="5mm" margin-top="5mm">@messages("btn.confirmation.heading")</fo:block>
</fo:block-container>

<!-- First paragraph -->
<fo:block id="more-info-date" margin-bottom="5mm">@messages("btn.confirmation.p1", currentDate, startDate)</fo:block>
<!-- What happens next -->
<fo:block role="H2" id="what-happens-next" font-size="14pt" font-weight="bold" margin-bottom="5mm">@messages("btn.confirmation.subheading")</fo:block>

<!-- Second paragraph -->
<fo:block id="removed-group-info" margin-bottom="5mm">@messages("btn.confirmation.p2")</fo:block>
<!-- Third paragraph -->
<fo:block id="submit-additional-info" margin-bottom="5mm">@messages("btn.confirmation.p3") @messages("btn.confirmation.p3.link").</fo:block>

</fo:block-container>
</fo:flow>

</fo:page-sequence>

</fo:root>
5 changes: 4 additions & 1 deletion conf/app.routes
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,7 @@ POST /below-threshold-notification/change-future-annual-revenues
GET /below-threshold-notification/nil-return controllers.btn.BtnSubmitUKTRController.onPageLoad

GET /below-threshold-notification/submit controllers.btn.CheckYourAnswersController.onPageLoad
POST /below-threshold-notification/submit controllers.btn.CheckYourAnswersController.onSubmit
POST /below-threshold-notification/submit controllers.btn.CheckYourAnswersController.onSubmit

GET /below-threshold-notification/confirmation controllers.btn.BtnConfirmationController.onPageLoad
GET /below-threshold-notification/confirmation/download-pdf controllers.btn.BtnConfirmationController.onDownloadConfirmation
Loading

0 comments on commit e546b44

Please sign in to comment.