diff --git a/app/controllers/checkAndSubmit/DutyDueForThisReturnController.scala b/app/controllers/checkAndSubmit/DutyDueForThisReturnController.scala index 10981c99..e3fb69d0 100644 --- a/app/controllers/checkAndSubmit/DutyDueForThisReturnController.scala +++ b/app/controllers/checkAndSubmit/DutyDueForThisReturnController.scala @@ -58,7 +58,7 @@ class DutyDueForThisReturnController @Inject() ( def onPageLoad(): Action[AnyContent] = (identify andThen getData andThen requireData).async { implicit request => dutyDueForThisReturnHelper - .getDutyDueViewModel(request.userAnswers) + .getDutyDueViewModel(request.userAnswers, request.returnPeriod) .foldF( error => { logger.warn(error) diff --git a/app/services/checkAndSubmit/AdrReturnSubmissionService.scala b/app/services/checkAndSubmit/AdrReturnSubmissionService.scala index 552ef148..4f50d0b3 100644 --- a/app/services/checkAndSubmit/AdrReturnSubmissionService.scala +++ b/app/services/checkAndSubmit/AdrReturnSubmissionService.scala @@ -53,17 +53,13 @@ class AdrReturnSubmissionServiceImpl @Inject() ( dutyDeclared <- getDutyDeclared(userAnswers) adjustments <- getAdjustments(userAnswers) dutySuspended <- getDutySuspended(userAnswers) - spirits <- - if ( - userAnswers.regimes.hasSpirits() && returnPeriod.hasQuarterlySpirits && appConfig.spiritsAndIngredientsEnabled - ) getSpirits(userAnswers) - else EitherT.rightT[Future, String](None) + maybeSpirits <- getSpirits(userAnswers, returnPeriod) totals <- getTotals(userAnswers) } yield AdrReturnSubmission( dutyDeclared = dutyDeclared, adjustments = adjustments, dutySuspended = dutySuspended, - spirits = spirits, + spirits = maybeSpirits, totals = totals ) @@ -330,16 +326,22 @@ class AdrReturnSubmissionServiceImpl @Inject() ( otherFermentedDutySuspended ).flatten - def getSpirits(userAnswers: UserAnswers): EitherT[Future, String, Option[AdrSpirits]] = - for { - declared <- getValue(userAnswers, DeclareQuarterlySpiritsPage) - spiritsProduced <- if (declared) getSpiritProduced(userAnswers) else EitherT.rightT[Future, String](None) - } yield Some( - AdrSpirits( - declared, - spiritsProduced + def getSpirits(userAnswers: UserAnswers, returnPeriod: ReturnPeriod): EitherT[Future, String, Option[AdrSpirits]] = + if ( + userAnswers.regimes.hasSpirits() && returnPeriod.hasQuarterlySpirits && appConfig.spiritsAndIngredientsEnabled + ) { + for { + declared <- getValue(userAnswers, DeclareQuarterlySpiritsPage) + spiritsProduced <- if (declared) getSpiritProduced(userAnswers) else EitherT.rightT[Future, String](None) + } yield Some( + AdrSpirits( + declared, + spiritsProduced + ) ) - ) + } else { + EitherT.rightT[Future, String](None) + } private def getSpiritProduced(userAnswers: UserAnswers): EitherT[Future, String, Option[AdrSpiritsProduced]] = for { @@ -506,7 +508,7 @@ trait AdrReturnSubmissionService { def getDutyDeclared(userAnswers: UserAnswers): EitherT[Future, String, AdrDutyDeclared] def getAdjustments(userAnswers: UserAnswers): EitherT[Future, String, AdrAdjustments] - def getSpirits(userAnswers: UserAnswers): EitherT[Future, String, Option[AdrSpirits]] def getDutySuspended(userAnswers: UserAnswers): EitherT[Future, String, AdrDutySuspended] + def getSpirits(userAnswers: UserAnswers, returnPeriod: ReturnPeriod): EitherT[Future, String, Option[AdrSpirits]] def getTotals(userAnswers: UserAnswers)(implicit hc: HeaderCarrier): EitherT[Future, String, AdrTotals] } diff --git a/app/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelper.scala b/app/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelper.scala index f010e9a3..aeea1f37 100644 --- a/app/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelper.scala +++ b/app/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelper.scala @@ -20,9 +20,9 @@ import cats.data.EitherT import config.Constants.Css import connectors.AlcoholDutyCalculatorConnector import models.AlcoholRegime.{Beer, Cider, OtherFermentedProduct, Spirits, Wine} -import models.checkAndSubmit.AdrDutySuspended +import models.checkAndSubmit.{AdrDutySuspended, AdrSpirits} import models.declareDuty.AlcoholDuty -import models.{AlcoholRegime, NormalMode, UserAnswers} +import models.{AlcoholRegime, NormalMode, ReturnPeriod, UserAnswers} import pages.adjustment.{AdjustmentTotalPage, DeclareAdjustmentQuestionPage} import pages.declareDuty.{AlcoholDutyPage, DeclareAlcoholDutyQuestionPage} import play.api.Logging @@ -51,7 +51,8 @@ class DutyDueForThisReturnHelper @Inject() ( private val dutyDueOrder = Seq(Beer, Cider, Wine, Spirits, OtherFermentedProduct) def getDutyDueViewModel( - userAnswers: UserAnswers + userAnswers: UserAnswers, + returnPeriod: ReturnPeriod )(implicit hc: HeaderCarrier, messages: Messages): EitherT[Future, String, DutyDueForThisReturnViewModel] = for { dutiesByRegime <- getDutiesByAlcoholRegime(userAnswers) @@ -59,7 +60,8 @@ class DutyDueForThisReturnHelper @Inject() ( total <- calculateTotal(dutiesByRegime, totalAdjustment) dutiesBreakdownViewModel <- createTableViewModel(dutiesByRegime, totalAdjustment) dutySuspended <- adrReturnSubmissionService.getDutySuspended(userAnswers) - youveAlsoAnsweredViewModel <- createYouveAlsoAnsweredTableViewModel(dutySuspended) + maybeSpirits <- adrReturnSubmissionService.getSpirits(userAnswers, returnPeriod) + youveAlsoAnsweredViewModel <- createYouveAlsoAnsweredTableViewModel(dutySuspended, maybeSpirits) } yield DutyDueForThisReturnViewModel( dutiesBreakdownViewModel, youveAlsoAnsweredViewModel, @@ -106,14 +108,15 @@ class DutyDueForThisReturnHelper @Inject() ( ) } - private def createYouveAlsoAnsweredTableViewModel(dutySuspended: AdrDutySuspended)(implicit - messages: Messages + private def createYouveAlsoAnsweredTableViewModel(dutySuspended: AdrDutySuspended, maybeSpirits: Option[AdrSpirits])( + implicit messages: Messages ): EitherT[Future, String, TableViewModel] = { val returnDutiesRow = createDutySuspendedRow(dutySuspended.declared) + val maybeSpiritsRow = maybeSpirits.map(spirits => createSpiritsRow(spirits.spiritsDeclared)) EitherT.rightT[Future, String]( TableViewModel( head = Seq.empty, - rows = returnDutiesRow + rows = maybeSpiritsRow.fold(returnDutiesRow)(returnDutiesRow ++ _) ) ) } @@ -177,7 +180,7 @@ class DutyDueForThisReturnHelper @Inject() ( ), actions = Seq( TableRowActionViewModel( - label = "Change", + label = messages("site.change"), href = controllers.dutySuspended.routes.CheckYourAnswersDutySuspendedDeliveriesController .onPageLoad() ) @@ -199,7 +202,7 @@ class DutyDueForThisReturnHelper @Inject() ( ), actions = Seq( TableRowActionViewModel( - label = "Change", + label = messages("site.change"), href = controllers.dutySuspended.routes.DeclareDutySuspendedDeliveriesQuestionController.onPageLoad(NormalMode) ) @@ -208,6 +211,54 @@ class DutyDueForThisReturnHelper @Inject() ( ) } + private def createSpiritsRow( + hasSpirits: Boolean + )(implicit messages: Messages): Seq[TableRowViewModel] = + if (hasSpirits) { + Seq( + TableRowViewModel( + cells = Seq( + TableRow( + content = Text(messages("dutyDueForThisReturn.spirits.production")), + classes = s"${Css.boldFontCssClass} ${Css.summaryListKeyCssClass}" + ), + TableRow( + Text(messages("dutyDueForThisReturn.spirits.declared")), + classes = Css.summaryListValueCssClass + ) + ), + actions = Seq( + TableRowActionViewModel( + label = messages("site.change"), + href = controllers.spiritsQuestions.routes.CheckYourAnswersController + .onPageLoad() + ) + ) + ) + ) + } else { + Seq( + TableRowViewModel( + cells = Seq( + TableRow( + content = Text(messages("dutyDueForThisReturn.spirits.production")), + classes = s"${Css.boldFontCssClass} ${Css.summaryListKeyCssClass}" + ), + TableRow( + Text(messages("dutyDueForThisReturn.spirits.nothingToDeclare")), + classes = Css.summaryListValueCssClass + ) + ), + actions = Seq( + TableRowActionViewModel( + label = messages("site.change"), + href = controllers.spiritsQuestions.routes.DeclareQuarterlySpiritsController.onPageLoad(NormalMode) + ) + ) + ) + ) + } + private def createAdjustmentRow(totalAdjustment: BigDecimal)(implicit messages: Messages): TableRowViewModel = if (totalAdjustment == 0) { TableRowViewModel( diff --git a/conf/messages.en b/conf/messages.en index b25664f0..f338655b 100644 --- a/conf/messages.en +++ b/conf/messages.en @@ -1074,6 +1074,9 @@ dutyDueForThisReturn.youveAlsoAnswered.p = The below answers will not affect how dutyDueForThisReturn.dutySuspended.alcohol = Duty suspended alcohol dutyDueForThisReturn.dutySuspended.declared = Declared dutyDueForThisReturn.dutySuspended.nothingToDeclare = Nothing to declare +dutyDueForThisReturn.spirits.production = Spirits production +dutyDueForThisReturn.spirits.declared = Declared +dutyDueForThisReturn.spirits.nothingToDeclare = Nothing to declare returnSubmitted.title = Return sent returnSubmitted.heading = Return sent diff --git a/test/controllers/checkAndSubmit/DutyDueForThisReturnControllerSpec.scala b/test/controllers/checkAndSubmit/DutyDueForThisReturnControllerSpec.scala index d3fdea7d..6c9d6f12 100644 --- a/test/controllers/checkAndSubmit/DutyDueForThisReturnControllerSpec.scala +++ b/test/controllers/checkAndSubmit/DutyDueForThisReturnControllerSpec.scala @@ -56,7 +56,7 @@ class DutyDueForThisReturnControllerSpec extends SpecBase { "DutyDueForThisReturn Controller" - { "must return OK and the correct view for a GET if Yes is selected and there is alcohol to declare" in { - when(dutyDueForThisReturnHelper.getDutyDueViewModel(any())(any(), any())).thenReturn( + when(dutyDueForThisReturnHelper.getDutyDueViewModel(any(), any())(any(), any())).thenReturn( EitherT.rightT(viewModel) ) @@ -78,7 +78,7 @@ class DutyDueForThisReturnControllerSpec extends SpecBase { } "must redirect in the Journey Recovery screen if the dutyDueForThisReturnHelper return an error" in { - when(dutyDueForThisReturnHelper.getDutyDueViewModel(any())(any(), any())).thenReturn( + when(dutyDueForThisReturnHelper.getDutyDueViewModel(any(), any())(any(), any())).thenReturn( EitherT.leftT("Error message") ) @@ -145,7 +145,7 @@ class DutyDueForThisReturnControllerSpec extends SpecBase { } } - "must redirect to the Journey Recover page if mapping from UserAnswer to AdrReturnSubmission return an error" in { + "must redirect to the Journey Recovery page if mapping from UserAnswer to AdrReturnSubmission return an error" in { val adrReturnSubmissionService = mock[AdrReturnSubmissionService] val alcoholDutyReturnsConnector = mock[AlcoholDutyReturnsConnector] val auditService = mock[AuditService] @@ -173,7 +173,7 @@ class DutyDueForThisReturnControllerSpec extends SpecBase { } } - "must redirect to the Journey Recover page if the submission is not successful" in { + "must redirect to the Journey Recovery page if the submission is not successful" in { val adrReturnSubmission = mock[AdrReturnSubmission] val adrReturnSubmissionService = mock[AdrReturnSubmissionService] val alcoholDutyReturnsConnector = mock[AlcoholDutyReturnsConnector] @@ -205,6 +205,5 @@ class DutyDueForThisReturnControllerSpec extends SpecBase { verify(auditService, times(0)).audit(any())(any(), any()) } } - } } diff --git a/test/services/checkAndSubmit/AdrReturnSubmissionServiceSpec.scala b/test/services/checkAndSubmit/AdrReturnSubmissionServiceSpec.scala index ed4f7318..c9939471 100644 --- a/test/services/checkAndSubmit/AdrReturnSubmissionServiceSpec.scala +++ b/test/services/checkAndSubmit/AdrReturnSubmissionServiceSpec.scala @@ -83,34 +83,6 @@ class AdrReturnSubmissionServiceSpec extends SpecBase with TestData { } "Full return" - { - "must return the valid return submission when for a return is passed" in new SetUp { - whenReady( - adrReturnSubmissionService.getAdrReturnSubmission(fullUserAnswers, quarterlySpiritsReturnPeriod).value - ) { result => - result mustBe Right(fullReturn) - } - } - - "must return the valid return submission without Spirits if the return period is not a quarter return" in new SetUp { - val expectedReturn = fullReturn.copy(spirits = None) - - whenReady( - adrReturnSubmissionService.getAdrReturnSubmission(fullUserAnswers, notQuarterlySpiritsReturnPeriod).value - ) { result => - result mustBe Right(expectedReturn) - } - } - - "must return the valid return submission without Spirits if the feature toggle is off" in new SetUp(false) { - val expectedReturn = fullReturn.copy(spirits = None) - - whenReady( - adrReturnSubmissionService.getAdrReturnSubmission(fullUserAnswers, quarterlySpiritsReturnPeriod).value - ) { result => - result mustBe Right(expectedReturn) - } - } - "must return the valid return submission if one adjustment type is not filled" in new SetUp { val drawbackAdjustmentIndex = 5 val userAnswers = @@ -397,16 +369,51 @@ class AdrReturnSubmissionServiceSpec extends SpecBase with TestData { } "Spirits section" - { - Seq( - DeclareQuarterlySpiritsPage - ).foreach { page => - s"must return Left if $page is not present" in new SetUp { - val userAnswers = fullUserAnswers.remove(page).success.value - whenReady( - adrReturnSubmissionService.getAdrReturnSubmission(userAnswers, quarterlySpiritsReturnPeriod).value - ) { result => - result mustBe Left(s"Value not found for page: $page") - } + "must return no spirits if the user doesn't have the spirits regime" in new SetUp { + whenReady( + adrReturnSubmissionService + .getAdrReturnSubmission( + fullUserAnswers.copy(regimes = AlcoholRegimes(Set(Beer, Cider, Wine, OtherFermentedProduct))), + quarterlySpiritsReturnPeriod + ) + .value + ) { result => + result.toOption.get.spirits mustBe None + } + } + + "must return no spirits if not a spirits quarter" in new SetUp { + whenReady( + adrReturnSubmissionService.getAdrReturnSubmission(fullUserAnswers, notQuarterlySpiritsReturnPeriod).value + ) { result => + result.toOption.get.spirits mustBe None + } + } + + "must return no spirits if the feature toggle is off" in new SetUp(false) { + whenReady( + adrReturnSubmissionService.getAdrReturnSubmission(fullUserAnswers, quarterlySpiritsReturnPeriod).value + ) { result => + result.toOption.get.spirits mustBe None + } + } + + "must return an error if DeclareQuarterlySpiritsPage is not present" in new SetUp { + val userAnswers = fullUserAnswers.remove(DeclareQuarterlySpiritsPage).success.value + whenReady( + adrReturnSubmissionService.getAdrReturnSubmission(userAnswers, quarterlySpiritsReturnPeriod).value + ) { result => + result mustBe Left(s"Value not found for page: $DeclareQuarterlySpiritsPage") + } + } + + "must return spirits otherwise" in new SetUp { + whenReady( + adrReturnSubmissionService.getAdrReturnSubmission(fullUserAnswers, quarterlySpiritsReturnPeriod).value + ) { result => + result.toOption.get.spirits.nonEmpty mustBe true + result.toOption.get.spirits.get.spiritsDeclared mustBe true + result.toOption.get.spirits.get.spiritsProduced.nonEmpty mustBe true } } } diff --git a/test/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelperSpec.scala b/test/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelperSpec.scala index 8cfe0607..dd2dd891 100644 --- a/test/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelperSpec.scala +++ b/test/viewmodels/checkAnswers/checkAndSubmit/DutyDueForThisReturnHelperSpec.scala @@ -21,7 +21,7 @@ import cats.data.EitherT import connectors.AlcoholDutyCalculatorConnector import models.{NormalMode, UserAnswers} import models.adjustment.AdjustmentDuty -import models.checkAndSubmit.{AdrDutySuspended, AdrDutySuspendedProduct} +import models.checkAndSubmit.{AdrDutySuspended, AdrDutySuspendedProduct, AdrSpirits} import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchersSugar.eqTo import play.api.i18n.Messages @@ -46,8 +46,9 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { .thenReturn(Future.successful(totalDuty)) when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(emptyDutySuspendedSuccessModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(emptySpiritsModel) - whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers).value) { result => + whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers, returnPeriod).value) { result => result.toOption.get.totalDue mustBe totalDuty.duty result.toOption.get.dutiesBreakdownTable.rows.map( _.cells(1).content.toString.filter(c => c.isDigit || c == '.') @@ -66,8 +67,9 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { .thenReturn(Future.successful(totalDutyWithoutAdjustments)) when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(emptyDutySuspendedSuccessModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(emptySpiritsModel) - whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers).value) { result => + whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers, returnPeriod).value) { result => result.toOption.get.totalDue mustBe totalDutyWithoutAdjustments.duty result.toOption.get.dutiesBreakdownTable.rows.map( _.cells(1).content.toString.filter(c => c.isDigit || c == '.') @@ -88,8 +90,9 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { .thenReturn(Future.successful(totalAdjustments)) when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(emptyDutySuspendedSuccessModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(emptySpiritsModel) - whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers).value) { result => + whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers, returnPeriod).value) { result => result.toOption.get.totalDue mustBe totalAdjustments.duty result.toOption.get.dutiesBreakdownTable.rows.map( _.cells(1).content.toString.filter(c => c.isDigit || c == '.') @@ -98,62 +101,212 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { } "should return a You've Also Answered Table View Model" - { - "with the correct label, declared content and redirect to the 'Duty suspended deliveries check answers' page" in new SetUp { - val userAnswers: UserAnswers = declareAdjustmentTotalPage( - declareAdjustmentQuestionPage( - declareAlcoholDutyQuestionPage(emptyUserAnswers, false), - true - ), - adjustmentTotal - ) - - val expectedRedirectUrl: Call = - controllers.dutySuspended.routes.CheckYourAnswersDutySuspendedDeliveriesController.onPageLoad() - - when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) - .thenReturn(Future.successful(totalAdjustments)) - - when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedDeclaredModel) - - val result = dutyDueForThisReturnHelper - .getDutyDueViewModel(userAnswers) - .value - .futureValue - .toOption - .get - .youveAlsoDeclaredTable - - result.rows.head.actions.head.href mustBe expectedRedirectUrl - result.rows.head.cells(1).content mustBe Text("Declared") + "when no spirits" - { + "and declared, with the correct label, declared content, and redirect to the appropriate check your answers page" in new SetUp { + val userAnswers: UserAnswers = declareAdjustmentTotalPage( + declareAdjustmentQuestionPage( + declareAlcoholDutyQuestionPage(emptyUserAnswers, false), + true + ), + adjustmentTotal + ) + + val expectedDutySuspendedDeliveriesRedirectUrl: Call = + controllers.dutySuspended.routes.CheckYourAnswersDutySuspendedDeliveriesController.onPageLoad() + + when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) + .thenReturn(Future.successful(totalAdjustments)) + + when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedDeclaredModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(emptySpiritsModel) + + val result = dutyDueForThisReturnHelper + .getDutyDueViewModel(userAnswers, returnPeriod) + .value + .futureValue + .toOption + .get + .youveAlsoDeclaredTable + + result.rows.size mustBe 1 + result.rows.head.actions.head.href mustBe expectedDutySuspendedDeliveriesRedirectUrl + result.rows.head.cells(1).content mustBe Text(messages("dutyDueForThisReturn.dutySuspended.declared")) + } + + "and DSD not declared, with the correct label, nothing to declare content, and redirect to the appropriate declaration page" in new SetUp { + val userAnswers: UserAnswers = declareAdjustmentTotalPage( + declareAdjustmentQuestionPage( + declareAlcoholDutyQuestionPage(emptyUserAnswers, false), + true + ), + adjustmentTotal + ) + + val expectedDutySuspendedDeliveriesRedirectUrl: Call = + controllers.dutySuspended.routes.DeclareDutySuspendedDeliveriesQuestionController.onPageLoad(NormalMode) + + when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) + .thenReturn(Future.successful(totalAdjustments)) + + when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedNotDeclaredModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(emptySpiritsModel) + + val result = dutyDueForThisReturnHelper + .getDutyDueViewModel(userAnswers, returnPeriod) + .value + .futureValue + .toOption + .get + .youveAlsoDeclaredTable + + result.rows.size mustBe 1 + result.rows.head.actions.head.href mustBe expectedDutySuspendedDeliveriesRedirectUrl + result.rows.head.cells(1).content mustBe Text(messages("dutyDueForThisReturn.dutySuspended.nothingToDeclare")) + } } - "with the correct label, nothing to declare content, and redirect to the 'Do you have any duty suspended deliveries to declare?' page" in new SetUp { - val userAnswers: UserAnswers = declareAdjustmentTotalPage( - declareAdjustmentQuestionPage( - declareAlcoholDutyQuestionPage(emptyUserAnswers, false), - true - ), - adjustmentTotal - ) - - val expectedRedirectUrl: Call = - controllers.dutySuspended.routes.DeclareDutySuspendedDeliveriesQuestionController.onPageLoad(NormalMode) - - when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) - .thenReturn(Future.successful(totalAdjustments)) - - when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedNotDeclaredModel) - - val result = dutyDueForThisReturnHelper - .getDutyDueViewModel(userAnswers) - .value - .futureValue - .toOption - .get - .youveAlsoDeclaredTable + "when spirits declared" - { + "and DSD declared, with the correct labels, declared content, and redirect to the appropriate check your answers pages" in new SetUp { + val userAnswers: UserAnswers = declareAdjustmentTotalPage( + declareAdjustmentQuestionPage( + declareAlcoholDutyQuestionPage(emptyUserAnswers, false), + true + ), + adjustmentTotal + ) + + val expectedDutySuspendedDeliveriesRedirectUrl: Call = + controllers.dutySuspended.routes.CheckYourAnswersDutySuspendedDeliveriesController.onPageLoad() + val expectedSpiritsRedirectUrl: Call = + controllers.spiritsQuestions.routes.CheckYourAnswersController.onPageLoad() + + when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) + .thenReturn(Future.successful(totalAdjustments)) + + when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedDeclaredModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(spiritsDeclaredModel) + + val result = dutyDueForThisReturnHelper + .getDutyDueViewModel(userAnswers, returnPeriod) + .value + .futureValue + .toOption + .get + .youveAlsoDeclaredTable + + result.rows.size mustBe 2 + result.rows(0).actions.head.href mustBe expectedDutySuspendedDeliveriesRedirectUrl + result.rows(0).cells(1).content mustBe Text(messages("dutyDueForThisReturn.dutySuspended.declared")) + result.rows(1).actions.head.href mustBe expectedSpiritsRedirectUrl + result.rows(1).cells(1).content mustBe Text(messages("dutyDueForThisReturn.spirits.declared")) + } + + "and DSD not declared, with the correct labels, nothing to declare content, and redirect to the appropriate pages" in new SetUp { + val userAnswers: UserAnswers = declareAdjustmentTotalPage( + declareAdjustmentQuestionPage( + declareAlcoholDutyQuestionPage(emptyUserAnswers, false), + true + ), + adjustmentTotal + ) + + val expectedDutySuspendedDeliveriesRedirectUrl: Call = + controllers.dutySuspended.routes.DeclareDutySuspendedDeliveriesQuestionController.onPageLoad(NormalMode) + val expectedSpiritsRedirectUrl: Call = + controllers.spiritsQuestions.routes.CheckYourAnswersController.onPageLoad() + + when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) + .thenReturn(Future.successful(totalAdjustments)) + + when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedNotDeclaredModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(spiritsDeclaredModel) + + val result = dutyDueForThisReturnHelper + .getDutyDueViewModel(userAnswers, returnPeriod) + .value + .futureValue + .toOption + .get + .youveAlsoDeclaredTable + + result.rows.size mustBe 2 + result.rows(0).actions.head.href mustBe expectedDutySuspendedDeliveriesRedirectUrl + result.rows(0).cells(1).content mustBe Text(messages("dutyDueForThisReturn.dutySuspended.nothingToDeclare")) + result.rows(1).actions.head.href mustBe expectedSpiritsRedirectUrl + result.rows(1).cells(1).content mustBe Text(messages("dutyDueForThisReturn.spirits.declared")) + } + } - result.rows.head.actions.head.href mustBe expectedRedirectUrl - result.rows.head.cells(1).content mustBe Text("Nothing to declare") + "when spirits not declared" - { + "and DSD declared, with the correct labels, declared content, and redirect to the appropriate pages" in new SetUp { + val userAnswers: UserAnswers = declareAdjustmentTotalPage( + declareAdjustmentQuestionPage( + declareAlcoholDutyQuestionPage(emptyUserAnswers, false), + true + ), + adjustmentTotal + ) + + val expectedDutySuspendedDeliveriesRedirectUrl: Call = + controllers.dutySuspended.routes.CheckYourAnswersDutySuspendedDeliveriesController.onPageLoad() + val expectedSpiritsRedirectUrl: Call = + controllers.spiritsQuestions.routes.DeclareQuarterlySpiritsController.onPageLoad(NormalMode) + + when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) + .thenReturn(Future.successful(totalAdjustments)) + + when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedDeclaredModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(spiritsNotDeclaredModel) + + val result = dutyDueForThisReturnHelper + .getDutyDueViewModel(userAnswers, returnPeriod) + .value + .futureValue + .toOption + .get + .youveAlsoDeclaredTable + + result.rows.size mustBe 2 + result.rows(0).actions.head.href mustBe expectedDutySuspendedDeliveriesRedirectUrl + result.rows(0).cells(1).content mustBe Text(messages("dutyDueForThisReturn.dutySuspended.declared")) + result.rows(1).actions.head.href mustBe expectedSpiritsRedirectUrl + result.rows(1).cells(1).content mustBe Text(messages("dutyDueForThisReturn.spirits.nothingToDeclare")) + } + + "and DSD not declared, with the correct labels, nothing to declare content, and redirect to the appropriate declarations pages" in new SetUp { + val userAnswers: UserAnswers = declareAdjustmentTotalPage( + declareAdjustmentQuestionPage( + declareAlcoholDutyQuestionPage(emptyUserAnswers, false), + true + ), + adjustmentTotal + ) + + val expectedDutySuspendedDeliveriesRedirectUrl: Call = + controllers.dutySuspended.routes.DeclareDutySuspendedDeliveriesQuestionController.onPageLoad(NormalMode) + val expectedSpiritsRedirectUrl: Call = + controllers.spiritsQuestions.routes.DeclareQuarterlySpiritsController.onPageLoad(NormalMode) + + when(mockCalculatorConnector.calculateTotalAdjustment(eqTo(adjustmentsNoDuties))(any)) + .thenReturn(Future.successful(totalAdjustments)) + + when(mockAdrReturnSubmissionService.getDutySuspended(any())).thenReturn(dutySuspendedNotDeclaredModel) + when(mockAdrReturnSubmissionService.getSpirits(any(), any())).thenReturn(spiritsNotDeclaredModel) + + val result = dutyDueForThisReturnHelper + .getDutyDueViewModel(userAnswers, returnPeriod) + .value + .futureValue + .toOption + .get + .youveAlsoDeclaredTable + + result.rows.size mustBe 2 + result.rows(0).actions.head.href mustBe expectedDutySuspendedDeliveriesRedirectUrl + result.rows(0).cells(1).content mustBe Text(messages("dutyDueForThisReturn.dutySuspended.nothingToDeclare")) + result.rows(1).actions.head.href mustBe expectedSpiritsRedirectUrl + result.rows(1).cells(1).content mustBe Text(messages("dutyDueForThisReturn.spirits.nothingToDeclare")) + } } } @@ -166,7 +319,7 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { adjustmentTotal ) - whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers).value) { result => + whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers, returnPeriod).value) { result => result.swap.toOption.get mustBe "Unable to get duties due when calculating duty due" } } @@ -178,7 +331,7 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { true ) - whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers).value) { result => + whenReady(dutyDueForThisReturnHelper.getDutyDueViewModel(userAnswers, returnPeriod).value) { result => result.swap.toOption.get mustBe "Unable to get adjustment totals when calculating duty due" } } @@ -189,7 +342,10 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { Future.failed(new Exception(errorMessage)) ) val result = - dutyDueForThisReturnHelper.getDutyDueViewModel(fullUserAnswers)(hc, getMessages(app)).value.futureValue + dutyDueForThisReturnHelper + .getDutyDueViewModel(fullUserAnswers, returnPeriod)(hc, getMessages(app)) + .value + .futureValue result mustBe Left(s"Failed to calculate total duty due: $errorMessage") } } @@ -215,9 +371,18 @@ class DutyDueForThisReturnHelperSpec extends SpecBase { val dutySuspendedNotDeclaredModel: EitherT[Future, String, AdrDutySuspended] = EitherT.rightT[Future, String]( AdrDutySuspended(declared = false, dutySuspendedProducts = Seq.empty[AdrDutySuspendedProduct]) ) - val totalDutyWithoutAdjustments = AdjustmentDuty(totalDuties.sum) - val totalAdjustments = AdjustmentDuty(adjustmentsNoDuties.sum) - val totalDuty = AdjustmentDuty(totalDutiesAndAdjustments.sum) + + val emptySpiritsModel: EitherT[Future, String, Option[AdrSpirits]] = EitherT.rightT[Future, String](None) + val spiritsDeclaredModel: EitherT[Future, String, Option[AdrSpirits]] = EitherT.rightT[Future, String]( + Some(AdrSpirits(spiritsDeclared = true, spiritsProduced = None)) + ) + val spiritsNotDeclaredModel: EitherT[Future, String, Option[AdrSpirits]] = EitherT.rightT[Future, String]( + Some(AdrSpirits(spiritsDeclared = false, spiritsProduced = None)) + ) + + val totalDutyWithoutAdjustments = AdjustmentDuty(totalDuties.sum) + val totalAdjustments = AdjustmentDuty(adjustmentsNoDuties.sum) + val totalDuty = AdjustmentDuty(totalDutiesAndAdjustments.sum) val mockCalculatorConnector = mock[AlcoholDutyCalculatorConnector] val mockAdrReturnSubmissionService = mock[AdrReturnSubmissionService]