Skip to content

Commit

Permalink
Merge pull request #117 from hmrc/DAC6-3293
Browse files Browse the repository at this point in the history
DAC6-3293 | First Draft PR - Controller, view, model etc
  • Loading branch information
Vishakha1903 authored Oct 21, 2024
2 parents 3abcce2 + 9d6ad7e commit dfbb4a5
Show file tree
Hide file tree
Showing 12 changed files with 548 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* 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.changeFinancialInstitution

import com.google.inject.Inject
import controllers.actions._
import models.UserAnswers
import models.requests.DataRequest
import pages.changeFinancialInstitution.ChangeFiDetailsInProgressId
import play.api.Logging
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents, Result}
import services.{FinancialInstitutionUpdateService, FinancialInstitutionsService}
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import utils.ContactHelper
import viewmodels.changeFinancialInstitution.ChangeRegisteredFinancialInstitutionViewModel.getChangeRegisteredFinancialInstitutionSummaries
import viewmodels.govuk.summarylist._
import views.html.ThereIsAProblemView
import views.html.changeFinancialInstitution.ChangeRegisteredFinancialInstitutionView

import scala.concurrent.{ExecutionContext, Future}

class ChangeRegisteredFinancialInstitutionController @Inject() (
override val messagesApi: MessagesApi,
identify: IdentifierAction,
getData: DataRetrievalAction,
requireData: DataRequiredAction,
financialInstitutionsService: FinancialInstitutionsService,
financialInstitutionUpdateService: FinancialInstitutionUpdateService,
val controllerComponents: MessagesControllerComponents,
view: ChangeRegisteredFinancialInstitutionView,
errorView: ThereIsAProblemView
)(implicit ec: ExecutionContext)
extends FrontendBaseController
with ContactHelper
with I18nSupport
with Logging {

def onPageLoad(fiid: String): Action[AnyContent] = (identify andThen getData andThen requireData).async {
implicit request =>
val userAnswers = request.userAnswers
financialInstitutionsService
.getFinancialInstitution(request.fatcaId, fiid)
.flatMap {
case Some(fiDetails) =>
userAnswers.get(ChangeFiDetailsInProgressId) match {
case Some(id) if id.equalsIgnoreCase(fiid) =>
val hasChanges = financialInstitutionUpdateService.registeredFiDetailsHasChanged(userAnswers, fiDetails)
Future.successful(createPage(fiid, userAnswers, hasChanges))
case _ =>
financialInstitutionUpdateService
.populateAndSaveRegisteredFiDetails(userAnswers, fiDetails)
.map(createPage(fiid, _, hasChanges = false))
.recoverWith {
exception =>
logger.error(s"Failed to populate and save FI details to user answers for subscription Id: [${request.fatcaId}] and FI Id [$fiid]",
exception
)
Future.successful(InternalServerError(errorView()))
}
}
case _ =>
logger.error(s"Failed to retrieve FI details from backend for subscription Id: [${request.fatcaId}] and FI Id [$fiid]")
Future.successful(InternalServerError(errorView()))
}
.recoverWith {
exception =>
logger.error(s"Failed to get FI details for subscription Id: [${request.fatcaId}] and FI Id [$fiid]", exception)
Future.successful(InternalServerError(errorView()))
}
}

def confirmAndAdd(): Action[AnyContent] = (identify andThen getData andThen requireData).async {
implicit request =>
financialInstitutionUpdateService
.clearUserAnswers(request.userAnswers)
.map(
_ => // TODO: User answers to be submitted and redirected to /details-updated as part of DAC6-3186
Redirect(controllers.routes.JourneyRecoveryController.onPageLoad())
)
.recoverWith {
exception =>
logger.error(s"Failed to clear user answers for subscription Id: [${request.fatcaId}]", exception)
Future.successful(InternalServerError(errorView()))
}
}

private def createPage(fiId: String, updatedUserAnswers: UserAnswers, hasChanges: Boolean)(implicit request: DataRequest[AnyContent]): Result = {
val fiName = getFinancialInstitutionName(updatedUserAnswers)
val financialInstitutionSummary = SummaryListViewModel(getChangeRegisteredFinancialInstitutionSummaries(fiId, updatedUserAnswers))
Ok(view(hasChanges, fiName, financialInstitutionSummary))
}

}
23 changes: 13 additions & 10 deletions app/navigation/Navigator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,7 @@ class Navigator @Inject() () {
case _ => redirectToCheckYouAnswers
}

private def redirectToCheckYouAnswers(ua: UserAnswers): Call =
ua.get(ReportForRegisteredBusinessPage) match {
case Some(value) if value => controllers.addFinancialInstitution.registeredBusiness.routes.RegisteredBusinessCheckYourAnswersController.onPageLoad()
case _ => resolveAnswersVerificationRoute(ua)
}
private def redirectToCheckYouAnswers(ua: UserAnswers): Call = resolveAnswersVerificationRoute(ua)

private def isFiUser(ua: UserAnswers, yesCall: => Call, noCall: => Call): Call =
ua.get(ReportForRegisteredBusinessPage) match {
Expand Down Expand Up @@ -298,14 +294,21 @@ class Navigator @Inject() () {
def checkNextPageForValueThenRoute[A](mode: Mode, userAnswers: UserAnswers, page: QuestionPage[A], call: Call)(implicit rds: Reads[A]): Call =
if (mode.equals(CheckMode) && userAnswers.get(page).isDefined) resolveAnswersVerificationRoute(userAnswers) else call

private def resolveAnswersVerificationRoute(userAnswers: UserAnswers): Call =
resolveNextRoute(userAnswers, routes.CheckYourAnswersController.onPageLoad())
private def resolveAnswersVerificationRoute(userAnswers: UserAnswers): Call = {
val route = userAnswers.get(ReportForRegisteredBusinessPage) match {
case Some(value) if value => controllers.addFinancialInstitution.registeredBusiness.routes.RegisteredBusinessCheckYourAnswersController.onPageLoad()
case _ => routes.CheckYourAnswersController.onPageLoad()
}
resolveNextRoute(userAnswers, route)
}

private def resolveNextRoute(userAnswers: UserAnswers, checkAnswersOnwardRoute: Call): Call =
userAnswers.get(ChangeFiDetailsInProgressId) match {
case Some(id) =>
(userAnswers.get(ChangeFiDetailsInProgressId), userAnswers.get(ReportForRegisteredBusinessPage)) match {
case (Some(id), Some(true)) =>
controllers.changeFinancialInstitution.routes.ChangeRegisteredFinancialInstitutionController.onPageLoad(id)
case (Some(id), _) =>
controllers.changeFinancialInstitution.routes.ChangeFinancialInstitutionController.onPageLoad(id)
case None => checkAnswersOnwardRoute
case _ => checkAnswersOnwardRoute
}

}
32 changes: 32 additions & 0 deletions app/services/FinancialInstitutionUpdateService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import models.FinancialInstitutions.TINType.{GIIN, UTR}
import models.FinancialInstitutions._
import models.{GIINumber, TaxIdentificationNumber, UniqueTaxpayerReference, UserAnswers}
import pages.QuestionPage
import pages.addFinancialInstitution.IsRegisteredBusiness.{IsTheAddressCorrectPage, IsThisYourBusinessNamePage, ReportForRegisteredBusinessPage}
import pages.addFinancialInstitution._
import pages.changeFinancialInstitution.ChangeFiDetailsInProgressId
import play.api.libs.json.{Json, Reads}
Expand All @@ -41,6 +42,13 @@ class FinancialInstitutionUpdateService @Inject() (
_ <- sessionRepository.set(updatedUserAnswers)
} yield updatedUserAnswers

def populateAndSaveRegisteredFiDetails(userAnswers: UserAnswers, fiDetails: FIDetail): Future[UserAnswers] =
for {
userAnswersWithProgressFlag <- Future.fromTry(userAnswers.set(ChangeFiDetailsInProgressId, fiDetails.FIID))
updatedUserAnswers <- populateUserAnswersWithRegisteredFiDetail(fiDetails, userAnswersWithProgressFlag)
_ <- sessionRepository.set(updatedUserAnswers)
} yield updatedUserAnswers

def fiDetailsHasChanged(userAnswers: UserAnswers, fiDetails: FIDetail): Boolean =
userAnswers.get(NameOfFinancialInstitutionPage).exists(_ != fiDetails.FIName) ||
checkTaxIdentifierForChanges(userAnswers, fiDetails.TINDetails, UTR, HaveUniqueTaxpayerReferencePage, WhatIsUniqueTaxpayerReferencePage) ||
Expand All @@ -49,6 +57,11 @@ class FinancialInstitutionUpdateService @Inject() (
checkPrimaryContactForChanges(userAnswers, fiDetails) ||
checkSecondaryContactForChanges(userAnswers, fiDetails)

def registeredFiDetailsHasChanged(userAnswers: UserAnswers, fiDetails: FIDetail): Boolean =
userAnswers.get(NameOfFinancialInstitutionPage).exists(_ != fiDetails.FIName) ||
checkTaxIdentifierForChanges(userAnswers, fiDetails.TINDetails, GIIN, HaveGIINPage, WhatIsGIINPage) ||
checkAddressForChanges(userAnswers, fiDetails.AddressDetails)

def clearUserAnswers(userAnswers: UserAnswers): Future[Boolean] =
sessionRepository.set(userAnswers.copy(data = Json.obj()))

Expand All @@ -65,6 +78,18 @@ class FinancialInstitutionUpdateService @Inject() (
f <- setSecondaryContactDetails(e, fiDetails)
} yield f

private def populateUserAnswersWithRegisteredFiDetail(
fiDetails: FIDetail,
userAnswers: UserAnswers
)(implicit ec: ExecutionContext): Future[UserAnswers] =
for {
a <- Future.fromTry(userAnswers.set(ReportForRegisteredBusinessPage, fiDetails.IsFIUser))
b <- Future.fromTry(a.set(NameOfFinancialInstitutionPage, fiDetails.FIName))
c <- setGIIN(b, fiDetails.TINDetails)
d <- setAddress(c, fiDetails.AddressDetails)
e <- setFiUserDetails(d)
} yield e

private def setUTR(userAnswers: UserAnswers, tinDetails: Seq[TINDetails])(implicit ec: ExecutionContext): Future[UserAnswers] =
tinDetails.find(_.TINType == UTR) match {
case Some(details) =>
Expand Down Expand Up @@ -137,6 +162,13 @@ class FinancialInstitutionUpdateService @Inject() (
} yield b
}

private def setFiUserDetails(userAnswers: UserAnswers): Future[UserAnswers] = for {
a <- Future.fromTry(userAnswers.set(ReportForRegisteredBusinessPage, true))
b <- Future.fromTry(a.set(IsThisYourBusinessNamePage, true))
c <- Future.fromTry(b.set(IsThisAddressPage, true))
d <- Future.fromTry(c.set(IsTheAddressCorrectPage, true))
} yield d

private def setSecondaryContactDetails(userAnswers: UserAnswers, fiDetails: FIDetail)(implicit ec: ExecutionContext): Future[UserAnswers] =
for {
a <- Future.fromTry(userAnswers.set(SecondContactExistsPage, fiDetails.SecondaryContactDetails.isDefined))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 viewmodels.changeFinancialInstitution

import models.{ChangeAnswers, UserAnswers}
import play.api.i18n.Messages
import uk.gov.hmrc.govukfrontend.views.viewmodels.summarylist.SummaryListRow
import viewmodels.common._

object ChangeRegisteredFinancialInstitutionViewModel {

def getChangeRegisteredFinancialInstitutionSummaries(fiId: String, userAnswers: UserAnswers)(implicit messages: Messages): Seq[SummaryListRow] =
Seq(
Option(FinancialInstitutionIdSummary.row(fiId)),
IsThisYourBusinessNameSummary.row(userAnswers, ChangeAnswers),
getGIINRows(userAnswers, ChangeAnswers),
getAddressRow(userAnswers, ChangeAnswers)
).flatten

}
4 changes: 2 additions & 2 deletions app/viewmodels/checkAnswers/CheckYourAnswersViewModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ object CheckYourAnswersViewModel {

def getFinancialInstitutionSummaries(ua: UserAnswers)(implicit messages: Messages): Seq[SummaryListRow] =
Seq(
ReportForRegisteredBusinessSummary.row(ua),
ReportForRegisteredBusinessSummary.row(ua, CheckAnswers),
IsThisYourBusinessNameSummary.row(ua, CheckAnswers),
HaveUniqueTaxpayerReferenceSummary.row(ua, CheckAnswers),
WhatIsUniqueTaxpayerReferenceSummary.row(ua, CheckAnswers),
Expand All @@ -35,7 +35,7 @@ object CheckYourAnswersViewModel {

def getRegisteredBusinessSummaries(ua: UserAnswers)(implicit messages: Messages): Seq[SummaryListRow] =
Seq(
ReportForRegisteredBusinessSummary.row(ua),
ReportForRegisteredBusinessSummary.row(ua, CheckAnswers),
IsThisYourBusinessNameSummary.row(ua, CheckAnswers),
getGIINRows(ua, CheckAnswers),
getAddressRow(ua, CheckAnswers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package viewmodels.checkAnswers

import models.{CheckMode, UserAnswers}
import models.{AnswersReviewPageType, CheckMode, UserAnswers}
import pages.addFinancialInstitution.IsRegisteredBusiness.ReportForRegisteredBusinessPage
import play.api.i18n.Messages
import uk.gov.hmrc.govukfrontend.views.viewmodels.summarylist.SummaryListRow
Expand All @@ -26,13 +26,13 @@ import viewmodels.implicits._

object ReportForRegisteredBusinessSummary {

def row(answers: UserAnswers)(implicit messages: Messages): Option[SummaryListRow] =
def row(answers: UserAnswers, pageType: AnswersReviewPageType)(implicit messages: Messages): Option[SummaryListRow] =
answers.get(ReportForRegisteredBusinessPage).map {
answer =>
val value = if (answer) "site.yes" else "site.no"

SummaryListRowViewModel(
key = "reportForRegisteredBusiness.checkYourAnswersLabel",
key = s"reportForRegisteredBusiness.${pageType.labelPrefix}YourAnswersLabel",
value = ValueViewModel(value),
actions = Seq(
accessibleActionItem("site.change",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ object YourFinancialInstitutionsViewModel {
key = Key("", "govuk-!-display-none"),
value = ValueViewModel(institution.FIName),
actions = Seq(
accessibleActionItem("site.change",
controllers.changeFinancialInstitution.routes.ChangeFinancialInstitutionController.onPageLoad(institution.FIID).url
accessibleActionItem(
"site.change",
if (institution.IsFIUser) {
controllers.changeFinancialInstitution.routes.ChangeRegisteredFinancialInstitutionController.onPageLoad(institution.FIID).url
} else {
controllers.changeFinancialInstitution.routes.ChangeFinancialInstitutionController.onPageLoad(institution.FIID).url
}
)
.withVisuallyHiddenText(messages("yourFinancialInstitutions.change.hidden", institution.FIName)),
accessibleActionItem("site.remove", controllers.routes.RemoveAreYouSureController.onPageLoad(institution.FIID).url)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@*
* 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 components._

@this(
layout: templates.Layout,
govukSummaryList: GovukSummaryList,
heading: Heading,
para: Paragraph,
formHelper: FormWithCSRF,
govukButton: GovukButton,
link: components.Link,
)

@(hasChanges: Boolean, fiName: String, financialInstitutionList: SummaryList)(implicit request: Request[_], messages: Messages)

@layout(pageTitle = titleNoForm(if (hasChanges) messages("changeYourRegisteredAnswers.title") else messages("changeYourRegisteredAnswers.title"))) {

@heading(if (hasChanges) messages("changedYourRegisteredAnswers.heading", fiName) else messages("changeYourRegisteredAnswers.heading", fiName))

@govukSummaryList(financialInstitutionList)
<p class="govuk-!-margin-bottom-9"></p>

@if(hasChanges){
@heading(messages("changeYourAnswers.changed.subheading"), "m")
@para(Html(messages("changeYourAnswers.changed.p2")))

@formHelper(action = controllers.changeFinancialInstitution.routes.ChangeRegisteredFinancialInstitutionController.confirmAndAdd()) {
@govukButton(
ButtonViewModel(messages("changeYourAnswers.submit.button")).withAttribute("id" -> "submit").preventingDoubleClick())
}
}

<p class="govuk-body govuk-!-margin-bottom-2">@link(controllers.routes.YourFinancialInstitutionsController.onPageLoad().url, "changeYourAnswers.p1")</p>

}
5 changes: 4 additions & 1 deletion conf/app.routes
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,7 @@ POST /remove-fi/:fiid contro
GET /change-answers/:fiid controllers.changeFinancialInstitution.ChangeFinancialInstitutionController.onPageLoad(fiid: String)
POST /change-answers controllers.changeFinancialInstitution.ChangeFinancialInstitutionController.confirmAndAdd()

GET /details-updated controllers.DetailsUpdatedController.onPageLoad()
GET /registered-business/change-answers/:fiid controllers.changeFinancialInstitution.ChangeRegisteredFinancialInstitutionController.onPageLoad(fiid: String)
POST /registered-business/change-answers controllers.changeFinancialInstitution.ChangeRegisteredFinancialInstitutionController.confirmAndAdd()

GET /details-updated controllers.DetailsUpdatedController.onPageLoad()
Loading

0 comments on commit dfbb4a5

Please sign in to comment.