Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 25 additions & 8 deletions app/controllers/TaxCodeChangeController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@

package controllers

import controllers.auth.{AuthJourney, AuthedUser}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import controllers.auth.{AuthJourney, AuthedUser, AuthenticatedRequest}
import play.api.Logging
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents, Result}
import uk.gov.hmrc.domain.Nino
import uk.gov.hmrc.http.UpstreamErrorResponse
import uk.gov.hmrc.tai.config.ApplicationConfig
import uk.gov.hmrc.tai.model.TaxYear
import uk.gov.hmrc.tai.service._
import uk.gov.hmrc.tai.service.*
import uk.gov.hmrc.tai.service.yourTaxFreeAmount.{DescribedYourTaxFreeAmountService, TaxCodeChangeReasonsService}
import uk.gov.hmrc.tai.util.yourTaxFreeAmount.{IabdTaxCodeChangeReasons, YourTaxFreeAmount}
import uk.gov.hmrc.tai.viewModels.taxCodeChange.TaxCodeChangeViewModel
Expand All @@ -42,19 +44,34 @@ class TaxCodeChangeController @Inject() (
mcc: MessagesControllerComponents,
taxCodeComparisonView: TaxCodeComparisonView,
yourTaxFreeAmountView: YourTaxFreeAmountView,
whatHappensNextView: WhatHappensNextView
whatHappensNextView: WhatHappensNextView,
errorPagesHandler: ErrorPagesHandler
)(implicit val ec: ExecutionContext)
extends TaiBaseController(mcc)
with YourTaxFreeAmount {
with YourTaxFreeAmount
with Logging {

def taxCodeComparison: Action[AnyContent] = authenticate.authWithValidatePerson.async { implicit request =>
val nino: Nino = request.taiUser.nino
val nino = request.taiUser.nino

val yourTaxFreeAmountComparisonFuture = yourTaxFreeAmountService.taxFreeAmountComparison(nino)
taxCodeChangeService
.hasTaxCodeChanged(nino)
.value
.flatMap {
case Right(false) => Future.successful(Redirect(controllers.routes.TaxAccountSummaryController.onPageLoad()))
case Right(true) => buildTaxCodeComparisonResult
case Left(error) => Future.successful(errorPagesHandler.internalServerError(error.message, Some(error)))
}
.recover { case exception =>
errorPagesHandler.internalServerError("Failed to build tax code comparison result", Some(exception))
}
}

private def buildTaxCodeComparisonResult(implicit request: AuthenticatedRequest[_]): Future[Result] = {
val nino: Nino = request.taiUser.nino
for {
yourTaxFreeAmountComparison <- yourTaxFreeAmountComparisonFuture
taxCodeChange <- taxCodeChangeService.taxCodeChange(nino).toFutureOrThrow
yourTaxFreeAmountComparison <- yourTaxFreeAmountService.taxFreeAmountComparison(nino, taxCodeChange)
scottishTaxRateBands <- taxAccountService.scottishBandRates(nino, TaxYear(), taxCodeChange.uniqueTaxCodes)
} yield {
val iabdTaxCodeChangeReasons: IabdTaxCodeChangeReasons = new IabdTaxCodeChangeReasons
Expand Down
8 changes: 3 additions & 5 deletions app/uk/gov/hmrc/tai/model/domain/TaxCodeChange.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@ case class TaxCodeChange(previous: List[TaxCodeRecord], current: List[TaxCodeRec

require(current.nonEmpty, "No current records for Tax Code Change. Current date cannot be determined.")

val currentPensionCount: Int = current.count(_.pensionIndicator)
val currentEmploymentCount: Int = current.count(!_.pensionIndicator)
val mostRecentTaxCodeChangeDate: LocalDate = DateHelper.mostRecentDate(current.map(_.startDate))
val mostRecentPreviousTaxCodeChangeDate: LocalDate =
DateHelper.mostRecentDate(previous.map(_.startDate))
val currentPensionCount: Int = current.count(_.pensionIndicator)
val currentEmploymentCount: Int = current.count(!_.pensionIndicator)
val mostRecentTaxCodeChangeDate: LocalDate = DateHelper.mostRecentDate(current.map(_.startDate))

lazy val uniqueTaxCodes: Seq[String] = (previous ++ current).map(_.taxCode).distinct
}
Expand Down
29 changes: 19 additions & 10 deletions app/uk/gov/hmrc/tai/service/YourTaxFreeAmountService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@

package uk.gov.hmrc.tai.service

import cats.implicits._
import cats.implicits.*
import play.api.i18n.Messages
import uk.gov.hmrc.domain.Nino
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.tai.model.domain.TaxCodeChange
import uk.gov.hmrc.tai.util.EitherTExtensions.EitherTThrowableOps
import uk.gov.hmrc.tai.util.yourTaxFreeAmount._
import uk.gov.hmrc.tai.util.yourTaxFreeAmount.*

import javax.inject.Inject
import scala.concurrent.{ExecutionContext, Future}
Expand All @@ -42,12 +43,20 @@ class YourTaxFreeAmountService @Inject() (
messages: Messages,
executionContext: ExecutionContext
): Future[YourTaxFreeAmountComparison] =
(taxCodeChangeService.taxCodeChange(nino).toFutureOrThrow, codingComponentService.taxFreeAmountComparison(nino))
.mapN { case (taxCodeChange, taxFreeAmountComparison) =>
buildTaxFreeAmount(
taxCodeChange.mostRecentTaxCodeChangeDate,
Some(taxFreeAmountComparison.previous),
taxFreeAmountComparison.current
)
}
taxCodeChangeService.taxCodeChange(nino).toFutureOrThrow.flatMap { taxCodeChange =>
taxFreeAmountComparison(nino, taxCodeChange)
}

def taxFreeAmountComparison(nino: Nino, taxCodeChange: TaxCodeChange)(implicit
hc: HeaderCarrier,
messages: Messages,
executionContext: ExecutionContext
): Future[YourTaxFreeAmountComparison] =
codingComponentService.taxFreeAmountComparison(nino).map { taxFreeAmountComparison =>
buildTaxFreeAmount(
taxCodeChange.mostRecentTaxCodeChangeDate,
Some(taxFreeAmountComparison.previous),
taxFreeAmountComparison.current
)
}
}
3 changes: 1 addition & 2 deletions app/uk/gov/hmrc/tai/util/DateHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ object DateHelper {

implicit val dateTimeOrdering: Ordering[LocalDate] = Ordering.fromLessThan(_ isAfter _)

def mostRecentDate(dates: Seq[LocalDate]): LocalDate =
dates.min
def mostRecentDate(dates: Seq[LocalDate]): LocalDate = dates.minOption.getOrElse(LocalDate.now)

def monthOfYear(date: String): String = {
val monthRegex = "[A-Za-z]+".r
Expand Down
2 changes: 1 addition & 1 deletion it/test/controllers/ContentsCheckSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ class ContentsCheckSpec extends IntegrationSpec with MockitoSugar with Matchers

server.stubFor(
get(urlEqualTo(s"/tai/$generatedNino/tax-account/tax-code-change/exists"))
.willReturn(ok("false"))
.willReturn(ok("true"))
)

server.stubFor(
Expand Down
41 changes: 36 additions & 5 deletions test/controllers/TaxCodeChangeControllerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ import builders.RequestBuilder
import cats.data.EitherT
import cats.instances.future.*
import controllers.auth.AuthenticatedRequest
import org.mockito.ArgumentMatchers.{any, eq => meq}
import org.mockito.ArgumentMatchers.{any, eq as meq}
import org.mockito.Mockito.when
import play.api.mvc.AnyContentAsFormUrlEncoded
import play.api.test.FakeRequest
import play.api.test.Helpers.{status, _}
import play.api.test.Helpers.{status, *}
import uk.gov.hmrc.http.UpstreamErrorResponse
import uk.gov.hmrc.tai.model.TaxYear
import uk.gov.hmrc.tai.model.domain.income.OtherBasisOfOperation
import uk.gov.hmrc.tai.model.domain.tax.TotalTax
import uk.gov.hmrc.tai.model.domain.{TaxCodeChange, TaxCodeRecord}
import uk.gov.hmrc.tai.service._
import uk.gov.hmrc.tai.service.*
import uk.gov.hmrc.tai.service.yourTaxFreeAmount.{DescribedYourTaxFreeAmountService, TaxCodeChangeReasonsService}
import uk.gov.hmrc.tai.util.yourTaxFreeAmount.TaxFreeInfo
import uk.gov.hmrc.tai.viewModels.taxCodeChange.{TaxCodeChangeViewModel, YourTaxFreeAmountViewModel}
Expand Down Expand Up @@ -97,12 +98,13 @@ class TaxCodeChangeControllerSpec extends BaseSpec with ControllerViewTestHelper
val taxCodeChange = TaxCodeChange(List(taxCodeRecord1), List(taxCodeRecord2))
val scottishRates = Map.empty[String, BigDecimal]

when(taxCodeChangeService.hasTaxCodeChanged(any())(any())).thenReturn(EitherT.rightT(true))
when(taxAccountService.scottishBandRates(any(), any(), any())(any()))
.thenReturn(Future.successful(Map[String, BigDecimal]()))
when(taxAccountService.totalTax(meq(FakeAuthRetrievals.nino), any())(any()))
.thenReturn(Future.successful(TotalTax(0, Seq.empty, None, None, None)))
when(taxCodeChangeService.taxCodeChange(any())(any())).thenReturn(EitherT.rightT(taxCodeChange))
when(yourTaxFreeAmountService.taxFreeAmountComparison(any())(any(), any(), any()))
when(yourTaxFreeAmountService.taxFreeAmountComparison(any(), any())(any(), any(), any()))
.thenReturn(Future.successful(mock[YourTaxFreeAmountComparison]))

val reasons = Seq("a reason")
Expand All @@ -124,6 +126,32 @@ class TaxCodeChangeControllerSpec extends BaseSpec with ControllerViewTestHelper
status(result) mustBe OK
result rendersTheSameViewAs taxCodeComparisonView(expectedViewModel, appConfig)
}

"show an error page when there is any issue in upstream, though hasTaxCodeChanged is true" in {
implicit val request: FakeRequest[AnyContentAsFormUrlEncoded] = RequestBuilder.buildFakeRequestWithAuth("GET")

val taxCodeChange = TaxCodeChange(List(taxCodeRecord1), List(taxCodeRecord2))

when(taxCodeChangeService.hasTaxCodeChanged(any())(any())).thenReturn(EitherT.rightT(true))
when(taxCodeChangeService.taxCodeChange(any())(any())).thenReturn(EitherT.rightT(taxCodeChange))
when(yourTaxFreeAmountService.taxFreeAmountComparison(any(), any())(any(), any(), any()))
.thenReturn(Future.failed(UpstreamErrorResponse("Error from upstream", INTERNAL_SERVER_ERROR)))

val result = createController().taxCodeComparison()(request)

status(result) mustBe INTERNAL_SERVER_ERROR
}

"show the tax account summary when hasTaxCodeChanged is false" in {
implicit val request: FakeRequest[AnyContentAsFormUrlEncoded] = RequestBuilder.buildFakeRequestWithAuth("GET")

when(taxCodeChangeService.hasTaxCodeChanged(any())(any())).thenReturn(EitherT.rightT(false))

val result = createController().taxCodeComparison()(request)

status(result) mustBe SEE_OTHER
redirectLocation(result) mustBe Some(controllers.routes.TaxAccountSummaryController.onPageLoad().url)
}
}

val giftAmount = 1000
Expand Down Expand Up @@ -157,6 +185,8 @@ class TaxCodeChangeControllerSpec extends BaseSpec with ControllerViewTestHelper

private val taxCodeComparisonView = inject[TaxCodeComparisonView]

private val errorPagesHandler = inject[ErrorPagesHandler]

private class TaxCodeChangeTestController
extends TaxCodeChangeController(
taxCodeChangeService,
Expand All @@ -169,7 +199,8 @@ class TaxCodeChangeControllerSpec extends BaseSpec with ControllerViewTestHelper
mcc,
taxCodeComparisonView,
yourTaxFreeAmountView,
whatHappensNextView
whatHappensNextView,
errorPagesHandler
) {}

}
9 changes: 0 additions & 9 deletions test/uk/gov/hmrc/tai/model/domain/TaxCodeChangeSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,6 @@ class TaxCodeChangeSpec extends PlaySpec {
}
}

"mostRecentPreviousTaxCodeChangeDate" should {
"return the latest tax code change date from a List of tax code records" in {
val model =
TaxCodeChange(List(previousTaxCodeRecord1, fullYearTaxCode), List(currentTaxCodeRecord1, fullYearTaxCode))

model.mostRecentPreviousTaxCodeChangeDate mustEqual startDate
}
}

"uniqueTaxCodes" should {
"return a List of unique tax codes found in the previous and current lists" in {
val model =
Expand Down