diff --git a/app/controllers/PSRController.scala b/app/controllers/PSRController.scala index d97752691..dbff671dd 100644 --- a/app/controllers/PSRController.scala +++ b/app/controllers/PSRController.scala @@ -120,6 +120,10 @@ abstract class PSRController extends FrontendBaseController with I18nSupport wit } } + implicit class FutureEitherOps[A](f: Future[Either[A, A]])(implicit ec: ExecutionContext) { + def merge: Future[A] = f.map(_.merge) + } + implicit class EitherOps[A](maybe: Either[String, A]) { def getOrRecoverJourney(implicit logger: Logger): Either[Result, A] = maybe.leftMap { errMsg => diff --git a/app/controllers/nonsipp/shares/SharesListController.scala b/app/controllers/nonsipp/shares/SharesListController.scala index 5233d2fb2..595caf447 100644 --- a/app/controllers/nonsipp/shares/SharesListController.scala +++ b/app/controllers/nonsipp/shares/SharesListController.scala @@ -21,7 +21,6 @@ import viewmodels.implicits._ import com.google.inject.Inject import utils.ListUtils._ import utils.nonsipp.TaskListStatusUtils.getCompletedOrUpdatedTaskListStatus -import _root_.config.Constants import controllers.actions.IdentifyAndRequireData import forms.YesNoPageFormProvider import viewmodels.models.TaskListStatus.Updated @@ -33,15 +32,20 @@ import views.html.ListView import models.SchemeId.Srn import cats.implicits.{catsSyntaxApplicativeId, toShow, toTraverseOps} import controllers.nonsipp.shares.SharesListController._ +import _root_.config.Constants +import config.Constants.maxSharesTransactions import pages.nonsipp.CompilationOrSubmissionDatePage +import play.api.Logger import navigation.Navigator import utils.DateTimeUtils.{localDateShow, localDateTimeShow} import models._ +import utils.nonsipp.check.SharesCheckStatusUtils import play.api.i18n.MessagesApi import viewmodels.DisplayMessage import viewmodels.DisplayMessage.{LinkMessage, Message, ParagraphMessage} import viewmodels.models._ import models.requests.DataRequest +import utils.MapUtils.UserAnswersMapOps import play.api.data.Form import scala.concurrent.{ExecutionContext, Future} @@ -60,6 +64,8 @@ class SharesListController @Inject()( )(implicit ec: ExecutionContext) extends PSRController { + private implicit val logger = Logger(getClass) + val form: Form[Boolean] = SharesListController.form(formProvider) def onPageLoad(srn: Srn, page: Int, mode: Mode): Action[AnyContent] = identifyAndRequireData(srn) { @@ -105,23 +111,26 @@ class SharesListController @Inject()( val indexes: List[Max5000] = request.userAnswers.map(SharesCompleted.all(srn)).keys.toList.refine[Max5000.Refined] if (indexes.nonEmpty || mode.isViewOnlyMode) { - sharesData(srn, indexes).map { data => - val filledForm = - request.userAnswers.get(SharesListPage(srn)).fold(form)(form.fill) - Ok( - view( - filledForm, - SharesListController.viewModel( - srn, - page, - mode, - data, - request.schemeDetails.schemeName, - viewOnlyViewModel, - showBackLink = showBackLink + shares(srn).map { + case (sharesToCheck, shares) => + val filledForm = + request.userAnswers.get(SharesListPage(srn)).fold(form)(form.fill) + Ok( + view( + filledForm, + viewModel( + srn, + page, + mode, + shares, + sharesToCheck, + request.schemeDetails.schemeName, + viewOnlyViewModel, + showBackLink = showBackLink, + isPrePopulation + ) ) ) - ) }.merge } else { Redirect(controllers.nonsipp.routes.TaskListController.onPageLoad(srn)) @@ -130,35 +139,36 @@ class SharesListController @Inject()( def onSubmit(srn: Srn, page: Int, mode: Mode): Action[AnyContent] = identifyAndRequireData(srn).async { implicit request => - val indexes: List[Max5000] = request.userAnswers.map(SharesCompleted.all(srn)).keys.toList.refine[Max5000.Refined] - - if (indexes.size >= Constants.maxSharesTransactions) { - Future.successful( - Redirect( - navigator.nextPage(SharesListPage(srn), mode, request.userAnswers) - ) - ) - } else { - form - .bindFromRequest() - .fold( - errors => { - sharesData(srn, indexes) - .map { data => - BadRequest(view(errors, viewModel(srn, page, mode, data, "", showBackLink = true))) - } - .merge - .pure[Future] - }, - addAnother => - for { - updatedUserAnswers <- Future.fromTry(request.userAnswers.set(SharesListPage(srn), addAnother)) - _ <- saveService.save(updatedUserAnswers) - } yield Redirect( - navigator.nextPage(SharesListPage(srn), mode, updatedUserAnswers) + shares(srn).traverse { + case (sharesToCheck, shares) => + if (sharesToCheck.size + shares.size >= Constants.maxSharesTransactions) { + Future.successful( + Redirect( + navigator.nextPage(SharesListPage(srn), mode, request.userAnswers) ) - ) - } + ) + } else { + form + .bindFromRequest() + .fold( + errors => { + BadRequest( + view( + errors, + viewModel(srn, page, mode, shares, sharesToCheck, "", None, showBackLink = true, isPrePopulation) + ) + ).pure[Future] + }, + addAnother => + for { + updatedUserAnswers <- Future.fromTry(request.userAnswers.set(SharesListPage(srn), addAnother)) + _ <- saveService.save(updatedUserAnswers) + } yield Redirect( + navigator.nextPage(SharesListPage(srn), mode, updatedUserAnswers) + ) + ) + } + }.merge } def onSubmitViewOnly(srn: Srn, year: String, current: Int, previous: Int): Action[AnyContent] = @@ -195,20 +205,42 @@ class SharesListController @Inject()( onPageLoadCommon(srn, page, ViewOnlyMode, Some(viewOnlyViewModel), showBackLink) } - private def sharesData(srn: Srn, indexes: List[Max5000])( - implicit req: DataRequest[_] - ): Either[Result, List[SharesData]] = - indexes - .sortBy(listRow => listRow.value) - .map { index => - for { - typeOfSharesHeld <- requiredPage(TypeOfSharesHeldPage(srn, index)) - companyName <- requiredPage(CompanyNameRelatedSharesPage(srn, index)) - acquisitionType <- requiredPage(WhyDoesSchemeHoldSharesPage(srn, index)) - acquisitionDate = req.userAnswers.get(WhenDidSchemeAcquireSharesPage(srn, index)) - } yield SharesData(index, typeOfSharesHeld, companyName, acquisitionType, acquisitionDate) - } - .sequence + private def shares(srn: Srn)( + implicit request: DataRequest[_], + logger: Logger + ): Either[Result, (List[SharesData], List[SharesData])] = { + // if return has been pre-populated, partition shares by those that need to be checked + def buildShares(index: Max5000): Either[Result, SharesData] = + for { + typeOfSharesHeld <- requiredPage(TypeOfSharesHeldPage(srn, index)) + companyName <- requiredPage(CompanyNameRelatedSharesPage(srn, index)) + acquisitionType <- requiredPage(WhyDoesSchemeHoldSharesPage(srn, index)) + acquisitionDate = request.userAnswers.get(WhenDidSchemeAcquireSharesPage(srn, index)) + } yield SharesData(index, typeOfSharesHeld, companyName, acquisitionType, acquisitionDate) + + if (isPrePopulation) { + for { + indexes <- request.userAnswers + .map(TypeOfSharesHeldPages(srn)) + .refine[Max5000.Refined] + .map(_.keys.toList) + .getOrRecoverJourney + shares <- indexes.traverse(buildShares) + } yield shares.partition( + shares => SharesCheckStatusUtils.checkSharesRecord(request.userAnswers, srn, shares.index) + ) + } else { + val noSharesToCheck = List.empty[SharesData] + for { + indexes <- request.userAnswers + .map(TypeOfSharesHeldPages(srn)) + .refine[Max5000.Refined] + .map(_.keys.toList) + .getOrRecoverJourney + shares <- indexes.traverse(buildShares) + } yield (noSharesToCheck, shares) + } + } } object SharesListController { @@ -222,7 +254,8 @@ object SharesListController { mode: Mode, memberList: List[SharesData], viewOnlyViewModel: Option[ViewOnlyViewModel], - schemeName: String + schemeName: String, + check: Boolean = false ): List[ListRow] = (memberList, mode) match { case (Nil, mode) if mode.isViewOnlyMode => @@ -261,6 +294,12 @@ object SharesListController { .url, Message("site.view.param", sharesMessage) ) + case _ if check => + ListRow.check( + sharesMessage, + controllers.routes.UnauthorisedController.onPageLoad().url, + Message("site.check.param", sharesMessage) + ) case _ => ListRow( sharesMessage, @@ -278,34 +317,45 @@ object SharesListController { srn: Srn, page: Int, mode: Mode, - data: List[SharesData], + shares: List[SharesData], + sharesToCheck: List[SharesData], schemeName: String, viewOnlyViewModel: Option[ViewOnlyViewModel] = None, - showBackLink: Boolean + showBackLink: Boolean, + isPrePop: Boolean ): FormPageViewModel[ListViewModel] = { - val lengthOfData = data.length + val sharesSize = if (isPrePop) shares.length + sharesToCheck.size else shares.length - val (title, heading) = ((mode, lengthOfData) match { - case (ViewOnlyMode, lengthOfData) if lengthOfData == 0 => + val (title, heading) = ((mode, sharesSize) match { + // View only + case (ViewOnlyMode, 0) => ("sharesList.view.title.none", "sharesList.view.heading.none") case (ViewOnlyMode, lengthOfData) if lengthOfData > 1 => ("sharesList.view.title.plural", "sharesList.view.heading.plural") case (ViewOnlyMode, _) => ("sharesList.view.title", "sharesList.view.heading") + // Pre-pop + case (_, _) if isPrePop && shares.nonEmpty => + ("sharesList.title.prepop.check", "sharesList.heading.prepop.check") + case (_, sharesSize) if isPrePop && sharesSize > 1 => + ("sharesList.title.prepop.plural", "sharesList.heading.prepop.plural") + case (_, _) if isPrePop => + ("sharesList.title.prepop", "sharesList.heading.prepop") + // Normal case (_, lengthOfData) if lengthOfData > 1 => ("sharesList.title.plural", "sharesList.heading.plural") case _ => ("sharesList.title", "sharesList.heading") }) match { case (title, heading) => - (Message(title, lengthOfData), Message(heading, lengthOfData)) + (Message(title, sharesSize), Message(heading, sharesSize)) } val pagination = Pagination( currentPage = page, pageSize = Constants.pageSize, - totalSize = data.size, + totalSize = shares.size, call = viewOnlyViewModel match { case Some(ViewOnlyViewModel(_, year, currentVersion, previousVersion, _)) => routes.SharesListController @@ -315,25 +365,60 @@ object SharesListController { } ) + val paragraph = Option.when(sharesSize < maxSharesTransactions) { + if (sharesToCheck.nonEmpty) { + ParagraphMessage("sharesList.description.prepop") ++ + ParagraphMessage("sharesList.description.disposal") + } else { + ParagraphMessage("sharesList.description") ++ + ParagraphMessage("sharesList.description.disposal") + } + } + val conditionalInsetText: DisplayMessage = { - if (data.size >= Constants.maxSharesTransactions) { + if (shares.size >= Constants.maxSharesTransactions) { ParagraphMessage("sharesList.inset") } else { Message("") } } + val sections = { + if (isPrePop) { + Option + .when(sharesToCheck.nonEmpty)( + ListSection( + heading = Some("sharesList.section.check"), + rows(srn, mode, sharesToCheck, viewOnlyViewModel, schemeName, check = true) + ) + ) + .toList ++ + Option + .when(shares.nonEmpty)( + ListSection( + heading = Some("sharesList.section.added"), + rows(srn, mode, shares, viewOnlyViewModel, schemeName) + ) + ) + .toList + } else { + List( + ListSection(rows(srn, mode, shares, viewOnlyViewModel, schemeName)) + ) + } + } + FormPageViewModel( mode = mode, title = title, heading = heading, - description = Some(ParagraphMessage("sharesList.description")), + description = paragraph, page = ListViewModel( inset = conditionalInsetText, - sections = List(ListSection(rows(srn, mode, data, viewOnlyViewModel, schemeName))), + sections = sections, radioText = Message("sharesList.radios"), - showRadios = data.size < Constants.maxSharesTransactions, - showInsetWithRadios = !(data.length < Constants.maxSharesTransactions), + showRadios = shares.size < Constants.maxSharesTransactions, + showInsetWithRadios = !(shares.length < Constants.maxSharesTransactions), paginatedViewModel = Some( PaginatedViewModel( Message( diff --git a/app/utils/nonsipp/MemberCountUtils.scala b/app/utils/nonsipp/MemberCountUtils.scala index e07cb20c3..45902defc 100644 --- a/app/utils/nonsipp/MemberCountUtils.scala +++ b/app/utils/nonsipp/MemberCountUtils.scala @@ -55,7 +55,7 @@ object MemberCountUtils { userAnswers.get(FeesCommissionsWagesSalariesPage(srn, NormalMode)) ) ) - lazy val sharesExist = !noDataStatuses.contains(getSharesTaskListStatusAndLink(userAnswers, srn)._1) + lazy val sharesExist = !noDataStatuses.contains(getSharesTaskListStatusAndLink(userAnswers, srn, isPrePop)._1) lazy val landOrPropertyExist = !noDataStatuses.contains(getLandOrPropertyTaskListStatusAndLink(userAnswers, srn, isPrePop)._1) lazy val bondsExist = !noDataStatuses.contains(getBondsTaskListStatusAndLink(userAnswers, srn)._1) diff --git a/app/utils/nonsipp/TaskListStatusUtils.scala b/app/utils/nonsipp/TaskListStatusUtils.scala index 0a9e5f6f1..735541244 100644 --- a/app/utils/nonsipp/TaskListStatusUtils.scala +++ b/app/utils/nonsipp/TaskListStatusUtils.scala @@ -42,7 +42,7 @@ import eu.timepit.refined.refineV import viewmodels.models.TaskListStatus._ import pages.nonsipp.schemedesignatory.Paths.schemeDesignatory import pages.nonsipp.common.IdentityTypes -import utils.nonsipp.check.LandOrPropertyCheckStatusUtils +import utils.nonsipp.check.{LandOrPropertyCheckStatusUtils, SharesCheckStatusUtils} import pages.nonsipp.membertransferout.{SchemeTransferOutPage, TransfersOutSectionCompleted} import pages.nonsipp.moneyborrowed.{LenderNamePages, MoneyBorrowedPage, WhySchemeBorrowedMoneyPages} import pages.nonsipp.bondsdisposal.{BondsDisposalPage, BondsDisposalProgress} @@ -377,36 +377,48 @@ object TaskListStatusUtils { } } - def getSharesTaskListStatusAndLink(userAnswers: UserAnswers, srn: Srn): (TaskListStatus, String) = { - val wereShares = userAnswers.get(DidSchemeHoldAnySharesPage(srn)) - val numRecorded = userAnswers.get(SharesCompleted.all(srn)).getOrElse(Map.empty).size + def getSharesTaskListStatusAndLink( + userAnswers: UserAnswers, + srn: Srn, + isPrePop: Boolean + ): (TaskListStatus, String) = + if (isPrePop && SharesCheckStatusUtils.checkSharesSection(userAnswers, srn)) { + ( + Check, + controllers.nonsipp.shares.routes.SharesListController + .onPageLoad(srn, 1, NormalMode) + .url + ) + } else { + val wereShares = userAnswers.get(DidSchemeHoldAnySharesPage(srn)) + val numRecorded = userAnswers.get(SharesCompleted.all(srn)).getOrElse(Map.empty).size - val firstQuestionPageUrl = - controllers.nonsipp.shares.routes.DidSchemeHoldAnySharesController - .onPageLoad(srn, NormalMode) - .url + val firstQuestionPageUrl = + controllers.nonsipp.shares.routes.DidSchemeHoldAnySharesController + .onPageLoad(srn, NormalMode) + .url - val listPageUrl = - controllers.nonsipp.shares.routes.SharesListController - .onPageLoad(srn, 1, NormalMode) - .url + val listPageUrl = + controllers.nonsipp.shares.routes.SharesListController + .onPageLoad(srn, 1, NormalMode) + .url - val firstPages = userAnswers.get(TypeOfSharesHeldPages(srn)) - val lastPages = userAnswers.map(SharesCompleted.all(srn)) - val incompleteIndex: Int = getIncompleteIndex(firstPages, Some(lastPages)) + val firstPages = userAnswers.get(TypeOfSharesHeldPages(srn)) + val lastPages = userAnswers.map(SharesCompleted.all(srn)) + val incompleteIndex: Int = getIncompleteIndex(firstPages, Some(lastPages)) - val inProgressCalculatedUrl = refineV[OneTo5000](incompleteIndex).fold( - _ => firstQuestionPageUrl, - index => controllers.nonsipp.shares.routes.TypeOfSharesHeldController.onPageLoad(srn, index, NormalMode).url - ) + val inProgressCalculatedUrl = refineV[OneTo5000](incompleteIndex).fold( + _ => firstQuestionPageUrl, + index => controllers.nonsipp.shares.routes.TypeOfSharesHeldController.onPageLoad(srn, index, NormalMode).url + ) - (wereShares, numRecorded) match { - case (None, _) => (NotStarted, firstQuestionPageUrl) - case (Some(false), _) => (Recorded(0, ""), firstQuestionPageUrl) - case (Some(true), 0) => (InProgress, inProgressCalculatedUrl) - case (Some(true), _) => (Recorded(numRecorded, "shares"), listPageUrl) + (wereShares, numRecorded) match { + case (None, _) => (NotStarted, firstQuestionPageUrl) + case (Some(false), _) => (Recorded(0, ""), firstQuestionPageUrl) + case (Some(true), 0) => (InProgress, inProgressCalculatedUrl) + case (Some(true), _) => (Recorded(numRecorded, "shares"), listPageUrl) + } } - } def getSharesDisposalsTaskListStatusWithLink(userAnswers: UserAnswers, srn: Srn): (TaskListStatus, String) = { val sharesDisposalsMade = userAnswers.get(SharesDisposalPage(srn)) @@ -428,8 +440,6 @@ object TaskListStatusUtils { } } - // if pre pop - check if any are in check state - if not resume regular status - // if any need checked - if some are done it's recorded if none then it's something else, stick to recorded for now def getLandOrPropertyTaskListStatusAndLink( userAnswers: UserAnswers, srn: Srn, diff --git a/app/utils/nonsipp/TaskListUtils.scala b/app/utils/nonsipp/TaskListUtils.scala index 18b088da8..0975abc31 100644 --- a/app/utils/nonsipp/TaskListUtils.scala +++ b/app/utils/nonsipp/TaskListUtils.scala @@ -49,7 +49,7 @@ object TaskListUtils { membersSection(srn, schemeName, userAnswers), memberPaymentsSection(srn, userAnswers), loansSection(srn, schemeName, userAnswers), - sharesSection(srn, userAnswers), + sharesSection(srn, userAnswers, isPrePop), landOrPropertySection(srn, userAnswers, isPrePop), bondsSection(srn, userAnswers), otherAssetsSection(srn, userAnswers) @@ -392,9 +392,9 @@ object TaskListUtils { ) } - private def sharesSection(srn: Srn, userAnswers: UserAnswers): TaskListSectionViewModel = { + private def sharesSection(srn: Srn, userAnswers: UserAnswers, isPrePop: Boolean): TaskListSectionViewModel = { val prefix = "nonsipp.tasklist.shares" - val (sharesStatus, sharesLink) = getSharesTaskListStatusAndLink(userAnswers, srn) + val (sharesStatus, sharesLink) = getSharesTaskListStatusAndLink(userAnswers, srn, isPrePop) val (sharesDisposalsStatus, sharesDisposalsLinkUrl) = TaskListStatusUtils.getSharesDisposalsTaskListStatusWithLink(userAnswers, srn) diff --git a/conf/messages.en b/conf/messages.en index 9b148c5cc..8a0c8b88f 100755 --- a/conf/messages.en +++ b/conf/messages.en @@ -13,6 +13,7 @@ site.previous = Previous site.view = View site.view.param = View {0} site.change.param = Change {0} +site.check.param = Check {0} site.remove.param = Remove {0} site.viewOrChange = View or change site.start = Start @@ -2933,10 +2934,18 @@ sharesTotalIncome.error.tooLarge = Total income from these shares in the period sharesList.title = You have added {0} share transaction sharesList.title.plural = You have added {0} share transactions +sharesList.title.prepop.check = Total of {0} shares in a sponsoring employer, acquired from a connected party, or unquoted shares +sharesList.title.prepop = {0} share in a sponsoring employer, acquired from a connected party, or unquoted shares +sharesList.title.prepop.plural = {0} shares in a sponsoring employer, acquired from a connected party, or unquoted shares sharesList.heading = You have added {0} share transaction sharesList.heading.plural = You have added {0} share transactions +sharesList.heading.prepop.check = Total of {0} shares in a sponsoring employer, acquired from a connected party, or unquoted shares +sharesList.heading.prepop = {0} share in a sponsoring employer, acquired from a connected party, or unquoted shares +sharesList.heading.prepop.plural = {0} shares in a sponsoring employer, acquired from a connected party, or unquoted shares sharesList.row.withDate = {0} in {1} {2} on {3} sharesList.row = {0} in {1} {2} +sharesList.section.check = Check details added in a previous return +sharesList.section.added = Updated in this return sharesList.view.title = View share transactions sharesList.view.title.plural = View share transactions @@ -2955,11 +2964,14 @@ sharesList.acquisition.acquired = acquired sharesList.acquisition.contributed = contributed sharesList.acquisition.transferred = transferred in sharesList.description = You must tell us about all shares in a sponsoring employer, unquoted shares, or any other shares acquired from a connected party held by the pension scheme at any point during the period of this return. -sharesList.radios = Do you need to add another share transaction? +sharesList.description.prepop = You must check all shares previously added. You must tell us about all shares in a sponsoring employer, acquired from a connected party, or unquoted shares the scheme held at any point during the period of this return. +sharesList.description.disposal = You can report any disposals in the ‘Disposal of shares in a sponsoring employer, acquired from a connected party, or unquoted shares’ section. +sharesList.radios = Do you need to add another share? sharesList.inset = You cannot add another share transaction as you have entered the maximum of 5,000. -sharesList.error.required = Select yes if you need to add another share transaction +sharesList.error.required = Select yes to add another share, or no to return to task list sharesList.pagination.label = Showing {0} - {1} of {2} shares + companyNameOfSharesBuyer.title = What is the buyer’s company name? companyNameOfSharesBuyer.heading = What is the buyer’s company name? companyNameOfSharesBuyer.error.required = Enter the buyer’s company name diff --git a/test/controllers/ControllerBehaviours.scala b/test/controllers/ControllerBehaviours.scala index 536798327..9ab5a2f3f 100644 --- a/test/controllers/ControllerBehaviours.scala +++ b/test/controllers/ControllerBehaviours.scala @@ -73,7 +73,7 @@ trait ControllerBehaviours { )( view: Application => Request[_] => Html ): BehaviourTest = - "return OK and the correct view".hasBehaviour { + "return OK and the correct view with PrePop session".hasBehaviour { val appBuilder = applicationBuilder( userAnswers = Some(userAnswers), pureUserAnswers = Some(pureUserAnswers), diff --git a/test/controllers/nonsipp/shares/SharesListControllerSpec.scala b/test/controllers/nonsipp/shares/SharesListControllerSpec.scala index 12f23a520..402006b07 100644 --- a/test/controllers/nonsipp/shares/SharesListControllerSpec.scala +++ b/test/controllers/nonsipp/shares/SharesListControllerSpec.scala @@ -34,7 +34,9 @@ import play.api.inject class SharesListControllerSpec extends ControllerBaseSpec { - private val index = refineMV[Max5000.Refined](1) + private val indexOne = refineMV[Max5000.Refined](1) + private val indexTwo = refineMV[Max5000.Refined](2) + private val page = 1 private implicit val mockPsrSubmissionService: PsrSubmissionService = mock[PsrSubmissionService] @@ -71,11 +73,26 @@ class SharesListControllerSpec extends ControllerBaseSpec { private val userAnswers = defaultUserAnswers .unsafeSet(DidSchemeHoldAnySharesPage(srn), true) - .unsafeSet(SharesCompleted(srn, index), SectionCompleted) - .unsafeSet(TypeOfSharesHeldPage(srn, index), TypeOfShares.Unquoted) - .unsafeSet(CompanyNameRelatedSharesPage(srn, index), companyName) - .unsafeSet(WhyDoesSchemeHoldSharesPage(srn, index), SchemeHoldShare.Acquisition) - .unsafeSet(WhenDidSchemeAcquireSharesPage(srn, index), localDate) + .unsafeSet(SharesCompleted(srn, indexOne), SectionCompleted) + .unsafeSet(WhyDoesSchemeHoldSharesPage(srn, indexOne), SchemeHoldShare.Transfer) + .unsafeSet(TypeOfSharesHeldPage(srn, indexOne), TypeOfShares.ConnectedParty) + .unsafeSet(CompanyNameRelatedSharesPage(srn, indexOne), companyName) + .unsafeSet(SharesCompanyCrnPage(srn, indexOne), ConditionalYesNo.yes[String, Crn](crn)) + .unsafeSet(ClassOfSharesPage(srn, indexOne), classOfShares) + .unsafeSet(HowManySharesPage(srn, indexOne), totalShares) + .unsafeSet(CostOfSharesPage(srn, indexOne), money) + .unsafeSet(SharesIndependentValuationPage(srn, indexOne), true) + .unsafeSet(SharesTotalIncomePage(srn, indexOne), money) + + private val userAnswersToCheck = userAnswers + .unsafeSet(WhyDoesSchemeHoldSharesPage(srn, indexTwo), SchemeHoldShare.Transfer) + .unsafeSet(TypeOfSharesHeldPage(srn, indexTwo), TypeOfShares.ConnectedParty) + .unsafeSet(CompanyNameRelatedSharesPage(srn, indexTwo), companyName) + .unsafeSet(SharesCompanyCrnPage(srn, indexTwo), ConditionalYesNo.yes[String, Crn](crn)) + .unsafeSet(ClassOfSharesPage(srn, indexTwo), classOfShares) + .unsafeSet(HowManySharesPage(srn, indexTwo), totalShares) + .unsafeSet(CostOfSharesPage(srn, indexTwo), money) + .unsafeSet(SharesIndependentValuationPage(srn, indexTwo), true) private val noUserAnswers = defaultUserAnswers @@ -83,14 +100,33 @@ class SharesListControllerSpec extends ControllerBaseSpec { .unsafeSet(FbVersionPage(srn), "002") .unsafeSet(CompilationOrSubmissionDatePage(srn), submissionDateTwo) - private val shareData = SharesData( - index, - typeOfShares = TypeOfShares.Unquoted, - companyName = companyName, - acquisitionType = SchemeHoldShare.Acquisition, - acquisitionDate = Some(localDate) + private val sharesData = List( + SharesData( + indexOne, + typeOfShares = TypeOfShares.ConnectedParty, + companyName = companyName, + acquisitionType = SchemeHoldShare.Transfer, + acquisitionDate = None + ) + ) + private val changedSharesData = List( + SharesData( + indexOne, + typeOfShares = TypeOfShares.ConnectedParty, + companyName = "changed", + acquisitionType = SchemeHoldShare.Transfer, + acquisitionDate = None + ) + ) + private val shareToCheckData = List( + SharesData( + indexTwo, + typeOfShares = TypeOfShares.ConnectedParty, + companyName = companyName, + acquisitionType = SchemeHoldShare.Transfer, + acquisitionDate = None + ) ) - private val sharesData = List(shareData) override protected val additionalBindings: List[GuiceableModule] = List( inject.bind[PsrSubmissionService].toInstance(mockPsrSubmissionService) @@ -102,7 +138,33 @@ class SharesListControllerSpec extends ControllerBaseSpec { injected[ListView] .apply( form(injected[YesNoPageFormProvider]), - viewModel(srn, page, NormalMode, sharesData, schemeName, showBackLink = true) + viewModel( + srn, + page, + NormalMode, + sharesData, + sharesToCheck = Nil, + schemeName, + showBackLink = true, + isPrePop = false + ) + ) + }) + + act.like(renderViewWithPrePopSession(onPageLoad, userAnswersToCheck) { implicit app => implicit request => + injected[ListView] + .apply( + form(injected[YesNoPageFormProvider]), + viewModel( + srn, + page, + NormalMode, + sharesData, + shareToCheckData, + schemeName, + showBackLink = true, + isPrePop = true + ) ) }) @@ -111,7 +173,16 @@ class SharesListControllerSpec extends ControllerBaseSpec { injected[ListView] .apply( form(injected[YesNoPageFormProvider]).fill(true), - viewModel(srn, page, NormalMode, sharesData, schemeName, showBackLink = true) + viewModel( + srn, + page, + NormalMode, + sharesData, + sharesToCheck = Nil, + schemeName, + showBackLink = true, + isPrePop = false + ) ) } ) @@ -166,16 +237,18 @@ class SharesListControllerSpec extends ControllerBaseSpec { page, mode = ViewOnlyMode, sharesData, + sharesToCheck = Nil, schemeName, Some(viewOnlyViewModel), - showBackLink = true + showBackLink = true, + isPrePop = false ) ) }.withName("OnPageLoadViewOnly renders ok with no changed flag") ) val updatedUserAnswers = currentUserAnswers - .unsafeSet(CompanyNameRelatedSharesPage(srn, index), "changed") + .unsafeSet(CompanyNameRelatedSharesPage(srn, indexOne), "changed") act.like( renderView(onPageLoadViewOnly, userAnswers = updatedUserAnswers, optPreviousAnswers = Some(previousUserAnswers)) { @@ -187,10 +260,12 @@ class SharesListControllerSpec extends ControllerBaseSpec { srn, page, mode = ViewOnlyMode, - List(shareData.copy(companyName = "changed")), + changedSharesData, + sharesToCheck = Nil, schemeName, viewOnlyViewModel = Some(viewOnlyViewModel.copy(viewOnlyUpdated = true)), - showBackLink = true + showBackLink = true, + isPrePop = false ) ) }.withName("OnPageLoadViewOnly renders ok with changed flag") @@ -206,10 +281,12 @@ class SharesListControllerSpec extends ControllerBaseSpec { srn, page, mode = ViewOnlyMode, - List(), + shares = Nil, + sharesToCheck = Nil, schemeName, viewOnlyViewModel = Some(viewOnlyViewModel.copy(viewOnlyUpdated = true)), - showBackLink = true + showBackLink = true, + isPrePop = false ) ) }.withName("OnPageLoadViewOnly renders ok with no shares") @@ -240,6 +317,7 @@ class SharesListControllerSpec extends ControllerBaseSpec { page, mode = ViewOnlyMode, sharesData, + sharesToCheck = Nil, schemeName, viewOnlyViewModel = Some( viewOnlyViewModel.copy( @@ -247,7 +325,8 @@ class SharesListControllerSpec extends ControllerBaseSpec { previousVersion = (submissionNumberOne - 1).max(0) ) ), - showBackLink = false + showBackLink = false, + isPrePop = false ) ) }.withName("OnPreviousViewOnly renders the view correctly") diff --git a/test/utils/nonsipp/TaskListStatusUtilsSpec.scala b/test/utils/nonsipp/TaskListStatusUtilsSpec.scala index 16d21b857..b672209d3 100644 --- a/test/utils/nonsipp/TaskListStatusUtilsSpec.scala +++ b/test/utils/nonsipp/TaskListStatusUtilsSpec.scala @@ -525,7 +525,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue "should be Not Started" - { "when default data" in { - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(defaultUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(defaultUserAnswers, srn, isPrePop = false) result mustBe (NotStarted, firstQuestionPageUrl) } } @@ -534,7 +534,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue "when only DidSchemeHoldAnyShares false is present" in { val customUserAnswers = defaultUserAnswers .unsafeSet(DidSchemeHoldAnySharesPage(srn), false) - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn, isPrePop = false) result mustBe (Recorded(0, ""), firstQuestionPageUrl) } @@ -543,7 +543,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue .unsafeSet(DidSchemeHoldAnySharesPage(srn), true) .unsafeSet(TypeOfSharesHeldPage(srn, index1of5000), TypeOfShares.ConnectedParty) .unsafeSet(SharesCompleted(srn, index1of5000), SectionCompleted) - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn, isPrePop = false) result mustBe (Recorded(1, "shares"), listPageUrl) } @@ -556,7 +556,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue .unsafeSet(TypeOfSharesHeldPage(srn, refineMV(2)), TypeOfShares.Unquoted) .unsafeSet(SharesCompleted(srn, refineMV(2)), SectionCompleted) - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn, isPrePop = false) result mustBe (Recorded(1, "shares"), listPageUrl) } @@ -569,7 +569,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue // second share: .unsafeSet(TypeOfSharesHeldPage(srn, refineMV(2)), TypeOfShares.Unquoted) - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn, isPrePop = false) result mustBe (Recorded(1, "shares"), listPageUrl) } } @@ -578,7 +578,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue "when only DidSchemeHoldAnyShares true is present" in { val customUserAnswers = defaultUserAnswers .unsafeSet(DidSchemeHoldAnySharesPage(srn), true) - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn, isPrePop = false) result mustBe (InProgress, firstQuestionPageUrl) } @@ -586,7 +586,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue val customUserAnswers = defaultUserAnswers .unsafeSet(DidSchemeHoldAnySharesPage(srn), true) .unsafeSet(TypeOfSharesHeldPage(srn, refineMV(1)), TypeOfShares.Unquoted) - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn, isPrePop = false) result mustBe (InProgress, secondQuestionPageUrl(index1of5000)) } @@ -597,7 +597,7 @@ class TaskListStatusUtilsSpec extends AnyFreeSpec with Matchers with OptionValue // second share: .unsafeSet(TypeOfSharesHeldPage(srn, refineMV(2)), TypeOfShares.Unquoted) - val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn) + val result = TaskListStatusUtils.getSharesTaskListStatusAndLink(customUserAnswers, srn, isPrePop = false) result mustBe (InProgress, secondQuestionPageUrl(index2of5000)) } }