diff --git a/app/controllers/returns/ViewReturnController.scala b/app/controllers/returns/ViewReturnController.scala
index 429fff2a..29de50bf 100644
--- a/app/controllers/returns/ViewReturnController.scala
+++ b/app/controllers/returns/ViewReturnController.scala
@@ -58,6 +58,7 @@ class ViewReturnController @Inject() (
val dutyToDeclareViewModel = viewModel.createAlcoholDeclaredViewModel(returnDetails)
val adjustmentsViewModel = viewModel.createAdjustmentsViewModel(returnDetails)
val totalDueViewModel = viewModel.createTotalDueViewModel(returnDetails)
+ val netDutySuspension = viewModel.createNetDutySuspensionViewModel(returnDetails)
val returnPeriodStr = dateTimeHelper.formatMonthYear(returnPeriod.period)
val submittedDate = dateTimeHelper.instantToLocalDate(returnDetails.identification.submittedTime)
val submittedDateStr = dateTimeHelper.formatDateMonthYear(submittedDate)
@@ -71,7 +72,8 @@ class ViewReturnController @Inject() (
submittedTimeStr,
dutyToDeclareViewModel,
adjustmentsViewModel,
- totalDueViewModel
+ totalDueViewModel,
+ netDutySuspension
)
)
}
diff --git a/app/models/returns/ReturnDetails.scala b/app/models/returns/ReturnDetails.scala
index 635f9b64..e04f2252 100644
--- a/app/models/returns/ReturnDetails.scala
+++ b/app/models/returns/ReturnDetails.scala
@@ -24,7 +24,8 @@ case class ReturnDetails(
identification: ReturnDetailsIdentification,
alcoholDeclared: ReturnAlcoholDeclared,
adjustments: ReturnAdjustments,
- totalDutyDue: ReturnTotalDutyDue
+ totalDutyDue: ReturnTotalDutyDue,
+ netDutySuspension: Option[ReturnNetDutySuspension]
)
object ReturnDetails {
@@ -109,3 +110,20 @@ case class ReturnTotalDutyDue(totalDue: BigDecimal)
object ReturnTotalDutyDue {
implicit val returnTotalDutyDueFormat: OFormat[ReturnTotalDutyDue] = Json.format[ReturnTotalDutyDue]
}
+
+case class ReturnNetDutySuspension(
+ totalLtsBeer: Option[BigDecimal],
+ totalLtsWine: Option[BigDecimal],
+ totalLtsCider: Option[BigDecimal],
+ totalLtsSpirit: Option[BigDecimal],
+ totalLtsOtherFermented: Option[BigDecimal],
+ totalLtsPureAlcoholBeer: Option[BigDecimal],
+ totalLtsPureAlcoholWine: Option[BigDecimal],
+ totalLtsPureAlcoholCider: Option[BigDecimal],
+ totalLtsPureAlcoholSpirit: Option[BigDecimal],
+ totalLtsPureAlcoholOtherFermented: Option[BigDecimal]
+)
+
+object ReturnNetDutySuspension {
+ implicit val returnTotalDutyDueFormat: OFormat[ReturnNetDutySuspension] = Json.format[ReturnNetDutySuspension]
+}
diff --git a/app/viewmodels/returns/ViewReturnViewModel.scala b/app/viewmodels/returns/ViewReturnViewModel.scala
index c532aa54..e39fbd00 100644
--- a/app/viewmodels/returns/ViewReturnViewModel.scala
+++ b/app/viewmodels/returns/ViewReturnViewModel.scala
@@ -219,4 +219,106 @@ class ViewReturnViewModel @Inject() () {
HeadCell(content = content, classes = s"${Constants.oneQuarterCssClass} ${Constants.textAlignRightCssClass}")
)
}
+
+ def createNetDutySuspensionViewModel(
+ returnDetails: ReturnDetails
+ )(implicit messages: Messages): TableViewModel =
+ returnDetails.netDutySuspension match {
+ case Some(netDutySuspension) =>
+ TableViewModel(
+ head = netDutySuspensionTableHeader(),
+ rows = netDutySuspensionRows(netDutySuspension)
+ )
+ case None =>
+ TableViewModel(
+ head = noneDeclareDutySuspensionHeader(),
+ rows = noneDeclaredDutySuspension()
+ )
+ }
+
+ private def netDutySuspensionTableHeader()(implicit messages: Messages): Seq[HeadCell] =
+ Seq(
+ HeadCell(
+ content = Text(messages("viewReturn.table.description.legend")),
+ classes = Constants.oneHalfCssClass
+ ),
+ HeadCell(
+ content = Text(messages("viewReturn.table.totalVolume.legend")),
+ classes = s"${Constants.oneQuarterCssClass} ${Constants.textAlignRightCssClass}"
+ ),
+ HeadCell(
+ content = Text(messages("viewReturn.table.lpa.legend")),
+ classes = s"${Constants.oneQuarterCssClass} ${Constants.textAlignRightCssClass}"
+ )
+ )
+
+ private def netDutySuspensionRows(netDutySuspension: ReturnNetDutySuspension)(implicit
+ messages: Messages
+ ): Seq[TableRowViewModel] =
+ Seq(
+ netDutySuspensionCell(
+ "return.regime.Beer",
+ netDutySuspension.totalLtsBeer,
+ netDutySuspension.totalLtsPureAlcoholBeer
+ ),
+ netDutySuspensionCell(
+ "return.regime.Cider",
+ netDutySuspension.totalLtsCider,
+ netDutySuspension.totalLtsPureAlcoholCider
+ ),
+ netDutySuspensionCell(
+ "return.regime.Spirits",
+ netDutySuspension.totalLtsSpirit,
+ netDutySuspension.totalLtsPureAlcoholSpirit
+ ),
+ netDutySuspensionCell(
+ "return.regime.Wine",
+ netDutySuspension.totalLtsWine,
+ netDutySuspension.totalLtsPureAlcoholWine
+ ),
+ netDutySuspensionCell(
+ "return.regime.OtherFermentedProduct",
+ netDutySuspension.totalLtsOtherFermented,
+ netDutySuspension.totalLtsPureAlcoholOtherFermented
+ )
+ ).flatten
+
+ private def netDutySuspensionCell(
+ messageKey: String,
+ totalLitres: Option[BigDecimal],
+ litresOfPureAlcohol: Option[BigDecimal]
+ )(implicit messages: Messages): Option[TableRowViewModel] =
+ for {
+ total <- totalLitres
+ lpa <- litresOfPureAlcohol
+ } yield TableRowViewModel(
+ cells = Seq(
+ TableRow(
+ content = Text(messages(messageKey).capitalize),
+ classes = Constants.oneHalfCssClass
+ ),
+ TableRow(
+ content = Text(messages("site.2DP", total)),
+ classes = s"${Constants.oneQuarterCssClass} ${Constants.textAlignRightCssClass}"
+ ),
+ TableRow(
+ content = Text(messages("site.4DP", lpa)),
+ classes = s"${Constants.oneQuarterCssClass} ${Constants.textAlignRightCssClass}"
+ )
+ )
+ )
+
+ private def noneDeclaredDutySuspension()(implicit messages: Messages) = Seq(
+ TableRowViewModel(
+ cells = Seq(
+ TableRow(content = Text(messages("viewReturn.netDutySuspension.noneDeclared")))
+ )
+ )
+ )
+
+ private def noneDeclareDutySuspensionHeader()(implicit messages: Messages): Seq[HeadCell] = Seq(
+ HeadCell(
+ content = Text(messages("viewReturn.table.description.legend"))
+ )
+ )
}
diff --git a/app/views/returns/ViewReturnView.scala.html b/app/views/returns/ViewReturnView.scala.html
index 338d3fe7..8acd5769 100644
--- a/app/views/returns/ViewReturnView.scala.html
+++ b/app/views/returns/ViewReturnView.scala.html
@@ -14,7 +14,7 @@
* limitations under the License.
*@
-@import components.{PageHeading, Paragraph, PrintPage, SectionHeading}
+@import components.{PageHeading, Paragraph, PrintPage}
@import config.Constants
@import viewmodels.{TableTotalViewModel, TableViewModel}
@@ -22,14 +22,13 @@
layout: templates.Layout,
formHelper: FormWithCSRF,
govukErrorSummary: GovukErrorSummary,
- sectionHeading: SectionHeading,
pageHeading: PageHeading,
paragraph: Paragraph,
govukTable: GovukTable,
printPage: PrintPage
)
-@(period: String, submittedAtDate: String, submittedAtTime: String, dutyToDeclare: TableViewModel, adjustments: TableViewModel, totalDue: TableTotalViewModel)(implicit request: Request[_], messages: Messages)
+@(period: String, submittedAtDate: String, submittedAtTime: String, dutyToDeclare: TableViewModel, adjustments: TableViewModel, totalDue: TableTotalViewModel, netDutySuspension: TableViewModel)(implicit request: Request[_], messages: Messages)
@layout(pageTitle = titleNoForm(messages(s"viewReturn.title", period)), fullWidth = true, withPrintCss = true) {
@@ -75,5 +74,16 @@
head = Some(totalDue.toHeadCells())
))
+
+
+ @govukTable(Table(
+ caption = Some(messages("viewReturn.netDutySuspension.caption")),
+ captionClasses = Constants.tableCaptionMCssClass,
+ head = Some(netDutySuspension.head),
+ rows = netDutySuspension.rows.map(_.cells)
+ ))
+
+
+
@printPage("print-past-payments-link", messages("viewReturn.printYourReturn"))
}
\ No newline at end of file
diff --git a/conf/messages.en b/conf/messages.en
index cc6fbf47..fc29d55f 100644
--- a/conf/messages.en
+++ b/conf/messages.en
@@ -156,11 +156,14 @@ viewReturn.dutyDue.caption = Total
viewReturn.dutyDue.total.legend = Total duty value
viewReturn.table.adjustmentType.legend = Adjustment
viewReturn.table.description.legend = Description
+viewReturn.table.totalVolume.legend = Total volume (litres)
viewReturn.table.lpa.legend = Litres of pure alcohol (LPA)
viewReturn.table.dutyRate.legend = Duty rate (per litre)
viewReturn.table.dutyValue.legend = Duty value
viewReturn.table.dutyDue.legend = Duty value
viewReturn.printYourReturn = Print your return
+viewReturn.netDutySuspension.caption = Duty suspended deliveries
+viewReturn.netDutySuspension.noneDeclared = Nothing declared
viewPastPayments.heading = Alcohol Duty payments
viewPastPayments.title = Alcohol Duty payments
diff --git a/test-utils/common/TestData.scala b/test-utils/common/TestData.scala
index 76732cfe..c873c4f7 100644
--- a/test-utils/common/TestData.scala
+++ b/test-utils/common/TestData.scala
@@ -234,7 +234,21 @@ trait TestData extends ModelGenerators {
),
total = BigDecimal("-19434")
),
- totalDutyDue = ReturnTotalDutyDue(totalDue = BigDecimal("55815"))
+ totalDutyDue = ReturnTotalDutyDue(totalDue = BigDecimal("55815")),
+ netDutySuspension = Some(
+ ReturnNetDutySuspension(
+ totalLtsBeer = Some(BigDecimal("0.15")),
+ totalLtsCider = Some(BigDecimal("0.38")),
+ totalLtsSpirit = Some(BigDecimal("0.02")),
+ totalLtsWine = Some(BigDecimal("0.44")),
+ totalLtsOtherFermented = Some(BigDecimal("0.02")),
+ totalLtsPureAlcoholBeer = Some(BigDecimal("0.4248")),
+ totalLtsPureAlcoholCider = Some(BigDecimal("0.0379")),
+ totalLtsPureAlcoholSpirit = Some(BigDecimal("0.2492")),
+ totalLtsPureAlcoholWine = Some(BigDecimal("0.5965")),
+ totalLtsPureAlcoholOtherFermented = Some(BigDecimal("0.1894"))
+ )
+ )
)
def nilReturnDetails(periodKey: String, now: Instant): ReturnDetails =
@@ -248,7 +262,8 @@ trait TestData extends ModelGenerators {
adjustmentDetails = None,
total = BigDecimal("0")
),
- totalDutyDue = ReturnTotalDutyDue(totalDue = BigDecimal("0"))
+ totalDutyDue = ReturnTotalDutyDue(totalDue = BigDecimal("0")),
+ netDutySuspension = None
)
def nilReturnDetailsWithEmptySections(periodKey: String, now: Instant): ReturnDetails =
@@ -262,7 +277,8 @@ trait TestData extends ModelGenerators {
adjustmentDetails = Some(Seq.empty),
total = BigDecimal("0")
),
- totalDutyDue = ReturnTotalDutyDue(totalDue = BigDecimal("0"))
+ totalDutyDue = ReturnTotalDutyDue(totalDue = BigDecimal("0")),
+ netDutySuspension = None
)
val obligationDataSingleOpen = ObligationData(
diff --git a/test/controllers/returns/ViewReturnControllerSpec.scala b/test/controllers/returns/ViewReturnControllerSpec.scala
index 6e5bd856..5cc6c54e 100644
--- a/test/controllers/returns/ViewReturnControllerSpec.scala
+++ b/test/controllers/returns/ViewReturnControllerSpec.scala
@@ -46,6 +46,7 @@ class ViewReturnControllerSpec extends SpecBase {
when(mockViewModel.createAlcoholDeclaredViewModel(returnDetails)).thenReturn(tableModel)
when(mockViewModel.createAdjustmentsViewModel(returnDetails)).thenReturn(tableModel)
when(mockViewModel.createTotalDueViewModel(returnDetails)).thenReturn(totalTableModel)
+ when(mockViewModel.createNetDutySuspensionViewModel(returnDetails)).thenReturn(tableModel)
val request = FakeRequest(GET, controllers.returns.routes.ViewReturnController.onPageLoad(periodKey).url)
val result = route(application, request).value
@@ -59,7 +60,8 @@ class ViewReturnControllerSpec extends SpecBase {
submittedAtTimeStr,
tableModel,
tableModel,
- totalTableModel
+ totalTableModel,
+ tableModel
)(
request,
messages
diff --git a/test/viewmodels/returns/ViewReturnViewModelSpec.scala b/test/viewmodels/returns/ViewReturnViewModelSpec.scala
index b99dcdee..d1deaf99 100644
--- a/test/viewmodels/returns/ViewReturnViewModelSpec.scala
+++ b/test/viewmodels/returns/ViewReturnViewModelSpec.scala
@@ -17,7 +17,7 @@
package viewmodels.returns
import base.SpecBase
-import models.returns.{ReturnAdjustments, ReturnAlcoholDeclared, ReturnTotalDutyDue}
+import models.returns.{ReturnAdjustments, ReturnAlcoholDeclared, ReturnDetails, ReturnTotalDutyDue}
import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper
import play.api.Application
import play.api.i18n.Messages
@@ -135,6 +135,45 @@ class ViewReturnViewModelSpec extends SpecBase {
adjustmentsViewModel.rows.head.cells(1).content shouldBe Text(messages("site.nil"))
}
}
+
+ "createNetDutySuspensionViewModel" - {
+ "should return a model with data when duty suspension is declared" in new SetUp {
+ val netDutySuspensionViewModel = viewModel.createNetDutySuspensionViewModel(returnDetails)
+
+ netDutySuspensionViewModel.head.size shouldBe 3
+ netDutySuspensionViewModel.rows.size shouldBe 5
+ netDutySuspensionViewModel.rows.foreach { row =>
+ row.cells.size shouldBe 3
+ }
+ }
+
+ "should return a model excluding the alcohol types not declared in the return" in new SetUp {
+ val returnDetailsWithoutCider: ReturnDetails = returnDetails
+ .copy(netDutySuspension =
+ Some(
+ returnDetails.netDutySuspension.get.copy(
+ totalLtsCider = None,
+ totalLtsPureAlcoholCider = None
+ )
+ )
+ )
+
+ val netDutySuspensionViewModel = viewModel.createNetDutySuspensionViewModel(returnDetailsWithoutCider)
+
+ netDutySuspensionViewModel.head.size shouldBe 3
+ netDutySuspensionViewModel.rows.size shouldBe 4
+
+ }
+
+ "should return a model with the right label when nothing declared" in new SetUp {
+ val netDutySuspensionViewModel = viewModel.createNetDutySuspensionViewModel(nilReturn)
+
+ netDutySuspensionViewModel.rows.size shouldBe 1
+ netDutySuspensionViewModel.rows.head.cells.head.content shouldBe Text(
+ messages("viewReturn.netDutySuspension.noneDeclared")
+ )
+ }
+ }
}
class SetUp {