Skip to content

Commit

Permalink
ADR-1362: duty suspended deliveries added to view specific return (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
msatta authored Oct 25, 2024
1 parent a1adab5 commit 594f036
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 10 deletions.
4 changes: 3 additions & 1 deletion app/controllers/returns/ViewReturnController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -71,7 +72,8 @@ class ViewReturnController @Inject() (
submittedTimeStr,
dutyToDeclareViewModel,
adjustmentsViewModel,
totalDueViewModel
totalDueViewModel,
netDutySuspension
)
)
}
Expand Down
20 changes: 19 additions & 1 deletion app/models/returns/ReturnDetails.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ case class ReturnDetails(
identification: ReturnDetailsIdentification,
alcoholDeclared: ReturnAlcoholDeclared,
adjustments: ReturnAdjustments,
totalDutyDue: ReturnTotalDutyDue
totalDutyDue: ReturnTotalDutyDue,
netDutySuspension: Option[ReturnNetDutySuspension]
)

object ReturnDetails {
Expand Down Expand Up @@ -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]
}
102 changes: 102 additions & 0 deletions app/viewmodels/returns/ViewReturnViewModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
)
)
}
16 changes: 13 additions & 3 deletions app/views/returns/ViewReturnView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,21 @@
* limitations under the License.
*@

@import components.{PageHeading, Paragraph, PrintPage, SectionHeading}
@import components.{PageHeading, Paragraph, PrintPage}
@import config.Constants
@import viewmodels.{TableTotalViewModel, TableViewModel}

@this(
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) {

Expand Down Expand Up @@ -75,5 +74,16 @@
head = Some(totalDue.toHeadCells())
))

<br>

@govukTable(Table(
caption = Some(messages("viewReturn.netDutySuspension.caption")),
captionClasses = Constants.tableCaptionMCssClass,
head = Some(netDutySuspension.head),
rows = netDutySuspension.rows.map(_.cells)
))

<br>

@printPage("print-past-payments-link", messages("viewReturn.printYourReturn"))
}
3 changes: 3 additions & 0 deletions conf/messages.en
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 19 additions & 3 deletions test-utils/common/TestData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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 =
Expand All @@ -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(
Expand Down
4 changes: 3 additions & 1 deletion test/controllers/returns/ViewReturnControllerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -59,7 +60,8 @@ class ViewReturnControllerSpec extends SpecBase {
submittedAtTimeStr,
tableModel,
tableModel,
totalTableModel
totalTableModel,
tableModel
)(
request,
messages
Expand Down
41 changes: 40 additions & 1 deletion test/viewmodels/returns/ViewReturnViewModelSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 594f036

Please sign in to comment.