Skip to content

Commit

Permalink
Merge pull request #105 from hmrc/VEIOSS-396
Browse files Browse the repository at this point in the history
VEIOSS-396 | Add completion checks for Returns journey
  • Loading branch information
Lee-Powell authored Apr 10, 2024
2 parents bed4eee + 96064fc commit ed102c6
Show file tree
Hide file tree
Showing 30 changed files with 1,256 additions and 184 deletions.
69 changes: 53 additions & 16 deletions app/controllers/CheckSalesController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ package controllers
import controllers.actions._
import forms.CheckSalesFormProvider
import models.Index
import pages.{CheckSalesPage, Waypoints}
import pages.{CheckSalesPage, SalesToCountryPage, Waypoints}
import play.api.data.Form
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import queries.RemainingVatRatesFromCountryQuery
import queries.{RemainingVatRatesFromCountryQuery, VatRateWithOptionalSalesFromCountry}
import services.VatRateService
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import utils.CompletionChecks
import utils.FutureSyntax.FutureOps
import viewmodels.checkAnswers.CheckSalesSummary
import views.html.CheckSalesView
Expand All @@ -39,7 +40,8 @@ class CheckSalesController @Inject()(
formProvider: CheckSalesFormProvider,
vatRateService: VatRateService,
view: CheckSalesView
)(implicit ec: ExecutionContext) extends FrontendBaseController with I18nSupport with GetCountry with GetVatRates {
)(implicit ec: ExecutionContext)
extends FrontendBaseController with CompletionChecks with I18nSupport with GetCountry with GetVatRates {

protected val controllerComponents: MessagesControllerComponents = cc

Expand All @@ -61,35 +63,70 @@ class CheckSalesController @Inject()(
case Some(value) => form.fill(value)
}

Ok(view(preparedForm, waypoints, period, checkSalesSummary, countryIndex, country, canAddAnotherVatRate)).toFuture
withCompleteDataAsync[VatRateWithOptionalSalesFromCountry](
countryIndex,
data = getIncompleteVatRateAndSales _,
onFailure = (incomplete: Seq[VatRateWithOptionalSalesFromCountry]) => {
Ok(view(
preparedForm,
waypoints,
period,
checkSalesSummary,
countryIndex,
country,
canAddAnotherVatRate,
incomplete)).toFuture
}) {
Ok(view(preparedForm, waypoints, period, checkSalesSummary, countryIndex, country, canAddAnotherVatRate)).toFuture
}
}
}
}

def onSubmit(waypoints: Waypoints, countryIndex: Index): Action[AnyContent] = cc.authAndRequireData().async {
def onSubmit(waypoints: Waypoints, countryIndex: Index, incompletePromptShown: Boolean): Action[AnyContent] = cc.authAndRequireData().async {
implicit request =>
getCountry(waypoints, countryIndex) { country =>
getAllVatRatesFromCountry(waypoints, countryIndex) { vatRates =>

val period = request.userAnswers.period

val vatRateIndex = Index(vatRates.vatRatesFromCountry.map(_.size).getOrElse(0) - 1)

val remainingVatRates = vatRateService.getRemainingVatRatesForCountry(period, country, vatRates)

val canAddAnotherVatRate = remainingVatRates.nonEmpty

val checkSalesSummary = CheckSalesSummary.rows(request.userAnswers, waypoints, countryIndex)

form.bindFromRequest().fold(
formWithErrors =>
BadRequest(view(formWithErrors, waypoints, period, checkSalesSummary, countryIndex, country, canAddAnotherVatRate)).toFuture,

value =>
for {
updatedAnswers <- Future.fromTry(request.userAnswers.set(CheckSalesPage(countryIndex), value))
updatedAnswersWithRemainingVatRates <- Future.fromTry(updatedAnswers.set(RemainingVatRatesFromCountryQuery(countryIndex), remainingVatRates))
_ <- cc.sessionRepository.set(updatedAnswersWithRemainingVatRates)
} yield Redirect(CheckSalesPage(countryIndex).navigate(waypoints, request.userAnswers, updatedAnswersWithRemainingVatRates).route)
)
val salesToCountry = request.userAnswers.get(SalesToCountryPage(countryIndex, vatRateIndex))

withCompleteDataAsync[VatRateWithOptionalSalesFromCountry](
countryIndex,
data = getIncompleteVatRateAndSales _,
onFailure = (_: Seq[VatRateWithOptionalSalesFromCountry]) => {
if(incompletePromptShown) {
salesToCountry match {
case Some(_) =>
Redirect(routes.VatOnSalesController.onPageLoad(waypoints, countryIndex, vatRateIndex)).toFuture
case None =>
Redirect(routes.SalesToCountryController.onPageLoad(waypoints, countryIndex, vatRateIndex)).toFuture
}
} else {
Redirect(routes.CheckSalesController.onPageLoad(waypoints, countryIndex)).toFuture
}
}) {
form.bindFromRequest().fold(
formWithErrors =>
BadRequest(view(formWithErrors, waypoints, period, checkSalesSummary, countryIndex, country, canAddAnotherVatRate, Seq.empty)).toFuture,

value =>
for {
updatedAnswers <- Future.fromTry(request.userAnswers.set(CheckSalesPage(countryIndex), value))
updatedAnswersWithRemainingVatRates <- Future.fromTry(updatedAnswers.set(RemainingVatRatesFromCountryQuery(countryIndex), remainingVatRates))
_ <- cc.sessionRepository.set(updatedAnswersWithRemainingVatRates)
} yield Redirect(CheckSalesPage(countryIndex).navigate(waypoints, request.userAnswers, updatedAnswersWithRemainingVatRates).route)
)
}
}
}
}
Expand Down
52 changes: 32 additions & 20 deletions app/controllers/CheckYourAnswersController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import uk.gov.hmrc.govukfrontend.views.Aliases.Card
import uk.gov.hmrc.govukfrontend.views.viewmodels.content.HtmlContent
import uk.gov.hmrc.govukfrontend.views.viewmodels.summarylist.{CardTitle, SummaryList}
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import utils.FutureSyntax.FutureOps
import viewmodels.checkAnswers._
import viewmodels.checkAnswers.corrections.{CorrectPreviousReturnSummary, CorrectionNoPaymentDueSummary, CorrectionReturnPeriodSummary}
import viewmodels.govuk.summarylist._
Expand All @@ -51,15 +52,18 @@ class CheckYourAnswersController @Inject()(
auditService: AuditService,
periodService: PeriodService,
view: CheckYourAnswersView,
saveForLaterConnector: SaveForLaterConnector
saveForLaterConnector: SaveForLaterConnector,
redirectService: RedirectService
)(implicit ec: ExecutionContext) extends FrontendBaseController with I18nSupport with Logging {

protected val controllerComponents: MessagesControllerComponents = cc

def onPageLoad(waypoints: Waypoints): Action[AnyContent] = cc.authAndRequireData() {
implicit request =>

val errors: List[ValidationError] = Nil // TODO
val period = request.userAnswers.period

val errors: List[ValidationError] = redirectService.validate(period)

val businessSummaryList = getBusinessSummaryList(request, waypoints)

Expand All @@ -75,8 +79,6 @@ class CheckYourAnswersController @Inject()(

val maybeExclusion: Option[EtmpExclusion] = request.registrationWrapper.registration.exclusions.lastOption

val period = request.userAnswers.period

val nextPeriodString = periodService.getNextPeriod(period).displayYearMonth

val nextPeriod: LocalDate = LocalDate.parse(nextPeriodString, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
Expand All @@ -102,22 +104,32 @@ class CheckYourAnswersController @Inject()(
def onSubmit(waypoints: Waypoints, incompletePromptShown: Boolean): Action[AnyContent] = cc.authAndRequireData().async {
implicit request =>
val userAnswers = request.userAnswers
coreVatReturnService.submitCoreVatReturn(userAnswers).flatMap { remainingTotalAmountVatDueGBP =>
auditService.audit(ReturnsAuditModel.build(userAnswers, SubmissionResult.Success))
userAnswers.set(TotalAmountVatDueGBPQuery, remainingTotalAmountVatDueGBP) match {
case Failure(exception) =>
logger.error(s"Couldn't update users answers with remaining owed vat ${exception.getMessage}", exception)
Future.successful(Redirect(controllers.submissionResults.routes.ReturnSubmissionFailureController.onPageLoad().url))
case Success(updatedAnswers) =>
cc.sessionRepository.set(updatedAnswers).map(_ =>
Redirect(controllers.submissionResults.routes.SuccessfullySubmittedController.onPageLoad().url)
)
}
}.recoverWith {
case e: Exception =>
logger.error(s"Error while submitting VAT return ${e.getMessage}", e)
auditService.audit(ReturnsAuditModel.build(userAnswers, SubmissionResult.Failure))
saveUserAnswersOnCoreError(controllers.submissionResults.routes.ReturnSubmissionFailureController.onPageLoad)

val preferredPeriod = userAnswers.period

val redirectToFirstError = redirectService.getRedirect(waypoints, redirectService.validate(preferredPeriod)).headOption

(redirectToFirstError, incompletePromptShown) match {
case (Some(redirect), true) => Redirect(redirect).toFuture
case (Some(_), false) => Redirect(routes.CheckYourAnswersController.onPageLoad(waypoints)).toFuture
case _ =>
coreVatReturnService.submitCoreVatReturn(userAnswers).flatMap { remainingTotalAmountVatDueGBP =>
auditService.audit(ReturnsAuditModel.build(userAnswers, SubmissionResult.Success))
userAnswers.set(TotalAmountVatDueGBPQuery, remainingTotalAmountVatDueGBP) match {
case Failure(exception) =>
logger.error(s"Couldn't update users answers with remaining owed vat ${exception.getMessage}", exception)
Future.successful(Redirect(controllers.submissionResults.routes.ReturnSubmissionFailureController.onPageLoad().url))
case Success(updatedAnswers) =>
cc.sessionRepository.set(updatedAnswers).map(_ =>
Redirect(controllers.submissionResults.routes.SuccessfullySubmittedController.onPageLoad().url)
)
}
}.recoverWith {
case e: Exception =>
logger.error(s"Error while submitting VAT return ${e.getMessage}", e)
auditService.audit(ReturnsAuditModel.build(userAnswers, SubmissionResult.Failure))
saveUserAnswersOnCoreError(controllers.submissionResults.routes.ReturnSubmissionFailureController.onPageLoad)
}
}
}

Expand Down
37 changes: 31 additions & 6 deletions app/controllers/SoldToCountryListController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ package controllers

import controllers.actions._
import forms.SoldToCountryListFormProvider
import models.Country
import models.{Country, Index}
import pages.{SoldToCountryListPage, Waypoints}
import play.api.data.Form
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import queries.DeriveNumberOfSales
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import utils.CompletionChecks
import utils.FutureSyntax.FutureOps
import utils.ItemsHelper.getDerivedItems
import viewmodels.checkAnswers.SoldToCountryListSummary
Expand All @@ -38,7 +39,7 @@ class SoldToCountryListController @Inject()(
cc: AuthenticatedControllerComponents,
formProvider: SoldToCountryListFormProvider,
view: SoldToCountryListView
)(implicit ec: ExecutionContext) extends FrontendBaseController with I18nSupport {
)(implicit ec: ExecutionContext) extends FrontendBaseController with CompletionChecks with I18nSupport {

protected val controllerComponents: MessagesControllerComponents = cc

Expand All @@ -56,16 +57,40 @@ class SoldToCountryListController @Inject()(
val salesSummary = SoldToCountryListSummary
.addToListRows(request.userAnswers, waypoints, SoldToCountryListPage())

Ok(view(form, waypoints, period, salesSummary, canAddSales)).toFuture
withCompleteDataAsync[Country](
data = getCountriesWithIncompleteSales _,
onFailure = (incomplete: Seq[Country]) => {
Ok(view(form, waypoints, period, salesSummary, canAddSales, incomplete)).toFuture
}) {
Ok(view(form, waypoints, period, salesSummary, canAddSales)).toFuture
}

}
}

def onSubmit(waypoints: Waypoints): Action[AnyContent] = cc.authAndRequireData().async {
def onSubmit(waypoints: Waypoints, incompletePromptShown: Boolean): Action[AnyContent] = cc.authAndRequireData().async {
implicit request =>

val period = request.userAnswers.period

getDerivedItems(waypoints, DeriveNumberOfSales) {
withCompleteDataAsync[Country](
data = getCountriesWithIncompleteSales _,
onFailure = (incompleteCountries: Seq[Country]) => {
if (incompletePromptShown) {
firstIndexedIncompleteCountrySales(incompleteCountries) match {
case Some(incompleteCountry) =>
if (incompleteCountry._1.vatRatesFromCountry.isEmpty) {
Redirect(routes.VatRatesFromCountryController.onPageLoad(waypoints, Index(incompleteCountry._2))).toFuture
} else {
Redirect(routes.CheckSalesController.onPageLoad(waypoints, Index(incompleteCountry._2))).toFuture
}
case None =>
Redirect(routes.JourneyRecoveryController.onPageLoad()).toFuture
}
} else {
Redirect(routes.SoldToCountryListController.onPageLoad(waypoints)).toFuture
}
})(getDerivedItems(waypoints, DeriveNumberOfSales) {
number =>

val canAddSales = number < Country.euCountriesWithNI.size
Expand All @@ -82,6 +107,6 @@ class SoldToCountryListController @Inject()(
_ <- cc.sessionRepository.set(updatedAnswers)
} yield Redirect(SoldToCountryListPage().navigate(waypoints, request.userAnswers, updatedAnswers).route)
)
}
})
}
}
3 changes: 1 addition & 2 deletions app/controllers/StartReturnController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import pages.{StartReturnPage, Waypoints}
import play.api.data.Form
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import services.{PartialReturnPeriodService, PeriodService}
import services.PartialReturnPeriodService
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import utils.FutureSyntax.FutureOps
import views.html.StartReturnView
Expand All @@ -37,7 +37,6 @@ class StartReturnController @Inject()(
override val messagesApi: MessagesApi,
cc: AuthenticatedControllerComponents,
formProvider: StartReturnFormProvider,
periodService: PeriodService,
partialReturnPeriodService: PartialReturnPeriodService,
view: StartReturnView,
clock: Clock
Expand Down
Loading

0 comments on commit ed102c6

Please sign in to comment.