Skip to content

Commit

Permalink
DL-14586 - Duplicate payments removal (#1023)
Browse files Browse the repository at this point in the history
* DL-14586 - Duplicate payments removal

* Dl-14586

* Fixed build errors

* Removed Unwanted Spaces
  • Loading branch information
Prem-Dasari authored Oct 31, 2024
1 parent 915e674 commit 66aca40
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 61 deletions.
1 change: 1 addition & 0 deletions app/v1/controllers/PaymentsController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ extends AuthorisedController(cc) with BaseController with Logging {

private def errorResult(errorWrapper: ErrorWrapper): Result = {
(errorWrapper.error: @unchecked) match {
case RuleDuplicatePaymentError => Conflict(Json.toJson(errorWrapper)) // Error case to Handle duplicate payments
case VrnFormatError | VrnFormatErrorDes |
FinancialDataInvalidDateFromError | InvalidDateFromErrorDes |
FinancialDataInvalidDateToError | InvalidDateToErrorDes |
Expand Down
5 changes: 4 additions & 1 deletion app/v1/models/errors/mtdErrors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,7 @@ object DuplicateVatSubmission extends MtdError(
)
))

object RuleIncorrectGovTestScenarioError extends MtdError(code = "RULE_INCORRECT_GOV_TEST_SCENARIO", message = "The Gov-Test-Scenario was not found")
object RuleIncorrectGovTestScenarioError extends MtdError(code = "RULE_INCORRECT_GOV_TEST_SCENARIO", message = "The Gov-Test-Scenario was not found")
object RuleDuplicatePaymentError extends MtdError(
"RULE_DUPLICATE_PAYMENT",
"Duplicate payment found: paymentLot, and paymentLotItem must be unique")
22 changes: 14 additions & 8 deletions app/v1/models/response/payments/PaymentItem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@
package v1.models.response.payments

import play.api.libs.functional.syntax._
import play.api.libs.json.{JsPath, Json, OWrites, Reads}
import play.api.libs.json.{JsNull, JsPath, Json, OWrites, Reads, __}

case class PaymentItem(amount: Option[BigDecimal],
received: Option[String])
received: Option[String],
paymentLot: Option[String],
paymentLotItem: Option[String])

object PaymentItem {

val empty: PaymentItem = PaymentItem(None, None)

implicit val writes: OWrites[PaymentItem] = Json.writes[PaymentItem]

val empty: PaymentItem = PaymentItem(None, None, None, None)
implicit val writes: OWrites[PaymentItem] = OWrites[PaymentItem] { paymentItem =>
Json.obj(
"amount" -> paymentItem.amount,
"received" -> paymentItem.received
).fields.filterNot(_._2 == JsNull).foldLeft(Json.obj())(_ + _)
}
implicit val reads: Reads[PaymentItem] = (
(JsPath \ "paymentAmount").readNullable[BigDecimal] and
(JsPath \ "clearingDate").readNullable[String]
(JsPath \ "clearingDate").readNullable[String] and
(JsPath \ "paymentLot").readNullable[String] and
(JsPath \ "paymentLotItem").readNullable[String]
) (PaymentItem.apply _)
}
26 changes: 23 additions & 3 deletions app/v1/services/PaymentsService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,31 @@ class PaymentsService @Inject()(connector: PaymentsConnector) extends DesRespons
val result = for {
desResponseWrapper <- EitherT(connector.retrievePayments(request)).leftMap(mapDesErrors(desErrorMap))
mtdResponseWrapper <- EitherT.fromEither[Future](validatePaymentsSuccessResponse(desResponseWrapper))
} yield mtdResponseWrapper

} yield {
val deduplicatedPayments = ensureUniquePayments(mtdResponseWrapper.responseData)
mtdResponseWrapper.copy(responseData = deduplicatedPayments)
}
result.value
}

private def ensureUniquePayments(paymentsResponse: PaymentsResponse): PaymentsResponse = {
val seen = scala.collection.mutable.Set[(BigDecimal, String, String)]()
val uniquePayments = paymentsResponse.payments.map { payment =>
payment.paymentItems match {
case Some(items) =>
val uniqueItems = items.filter { item =>
val key = (
item.amount.getOrElse(BigDecimal(0)),
item.paymentLot.getOrElse("").trim,
item.paymentLotItem.getOrElse("").trim
)
!seen.contains(key) && seen.add(key)
}
payment.copy(paymentItems = Some(uniqueItems))
case None => payment
}
}
paymentsResponse.copy(payments = uniquePayments)
}
private val desErrorMap: Map[String, MtdError] =
Map(
"INVALID_IDTYPE" -> DownstreamError,
Expand Down
12 changes: 6 additions & 6 deletions func/test/v1/fixtures/PaymentsFixture.scala
Original file line number Diff line number Diff line change
Expand Up @@ -266,24 +266,24 @@ trait PaymentsFixture {
taxPeriod = Some(TaxPeriod(from = "2017-02-01", to = "2017-02-28")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(15.0), received = Some("2017-02-11"))
PaymentItem(amount = Some(15.0), received = Some("2017-02-11"), paymentLot = Some("081203010024"), paymentLotItem = Some ("000001"))
))
),
Payment(
taxPeriod = Some(TaxPeriod(from = "2017-03-01", to = "2017-03-25")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(40.00), received = Some("2017-03-11")),
PaymentItem(amount = Some(1001.00), received = Some("2017-03-12"))
PaymentItem(amount = Some(40.00), received = Some("2017-03-11"), paymentLot = Some("081203010024"), paymentLotItem = Some ("000001")),
PaymentItem(amount = Some(1001.00), received = Some("2017-03-12"), paymentLot = Some("081203010024"), paymentLotItem = Some ("000001"))
))
),
Payment(
taxPeriod = Some(TaxPeriod(from = "2017-08-01", to = "2017-12-20")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(Some(322.00), Some("2017-08-05")),
PaymentItem(Some(90.00), None),
PaymentItem(Some(6.00), Some("2017-09-12"))
PaymentItem(Some(322.00), Some("2017-08-05"), paymentLot = Some("081203010024"), paymentLotItem = Some ("000001")),
PaymentItem(Some(90.00), None, paymentLot = Some("081203010024"), paymentLotItem = Some ("000002")),
PaymentItem(Some(6.00), Some("2017-09-12"), paymentLot = Some("081203010024"), paymentLotItem = Some ("000003"))
))
)
)
Expand Down
6 changes: 3 additions & 3 deletions test/v1/connectors/PaymentsConnectorSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class PaymentsConnectorSpec extends ConnectorSpec {
taxPeriod = Some(TaxPeriod(from = "2017-1-1", to = "2017-12-31")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(200.00), received = Some("2017-03-12"))
PaymentItem(amount = Some(200.00), received = Some("2017-03-12"), paymentLot = Some("01234"), paymentLotItem = Some("0001"))
))
)
)
Expand All @@ -55,14 +55,14 @@ class PaymentsConnectorSpec extends ConnectorSpec {
taxPeriod = Some(TaxPeriod(from = "2017-1-1", to = "2017-12-31")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(200.00), received = Some("2017-03-12"))
PaymentItem(amount = Some(200.00), received = Some("2017-03-12"), paymentLot = Some("01234"), paymentLotItem = Some("0001"))
))
),
Payment(
taxPeriod = Some(TaxPeriod(from = "2018-1-1", to = "2018-12-31")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(2375.23), received = Some("2018-03-12"))
PaymentItem(amount = Some(2375.23), received = Some("2018-03-12"), paymentLot = Some("56789"), paymentLotItem = Some("0002"))
))
)
)
Expand Down
12 changes: 6 additions & 6 deletions test/v1/controllers/PaymentsControllerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,24 @@ class PaymentsControllerSpec
taxPeriod = Some(TaxPeriod(from = "2017-02-01", to = "2017-02-28")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(15.0), received = Some("2017-02-11"))
PaymentItem(amount = Some(15.0), received = Some("2017-02-11"), paymentLot = Some("01234"), paymentLotItem = Some("0001"))
))
),
Payment(
taxPeriod = Some(TaxPeriod(from = "2017-03-01", to = "2017-03-25")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(40.00), received = Some("2017-03-11")),
PaymentItem(amount = Some(1001.00), received = Some("2017-03-12"))
PaymentItem(amount = Some(40.00), received = Some("2017-03-11"), paymentLot = Some("01234"), paymentLotItem = Some("0001")),
PaymentItem(amount = Some(1001.00), received = Some("2017-03-12"), paymentLot = Some("56789"), paymentLotItem = Some("0002"))
))
),
Payment(
taxPeriod = Some(TaxPeriod(from = "2017-08-01", to = "2017-12-20")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(Some(322.00), Some("2017-08-05")),
PaymentItem(Some(90.00), None),
PaymentItem(Some(6.00), Some("2017-09-12"))
PaymentItem(Some(322.00), Some("2017-08-05"), paymentLot = Some("01234"), paymentLotItem = Some("0001")),
PaymentItem(Some(90.00), None, paymentLot = Some("56789"), paymentLotItem = Some("0002")),
PaymentItem(Some(6.00), Some("2017-09-12"), paymentLot = Some("12345"), paymentLotItem = Some("0003"))
))
)
)
Expand Down
13 changes: 8 additions & 5 deletions test/v1/models/response/payments/PaymentItemSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class PaymentItemSpec extends UnitSpec {
"""
|{
| "paymentAmount" : 100.2,
| "clearingDate" : "2017-01-01"
| "clearingDate" : "2017-01-01",
| "paymentLot":"01234",
| "paymentLotItem":"0001"
|}
""".stripMargin
)
Expand All @@ -34,7 +36,9 @@ class PaymentItemSpec extends UnitSpec {
"""
|{
| "paymentAmount" : 100.2,
| "clearingDate" : false
| "clearingDate" : false,
| "paymentLot":"01234",
| "paymentLotItem":"0001"
|}
""".stripMargin
)
Expand All @@ -49,7 +53,7 @@ class PaymentItemSpec extends UnitSpec {
)

val paymentItemModel: PaymentItem =
PaymentItem(amount = Some(100.2), received = Some("2017-01-01"))
PaymentItem(amount = Some(100.2), received = Some("2017-01-01"), paymentLot = Some("01234"), paymentLotItem = Some("0001"))

"PaymentItem" when {
"read from valid JSON" should {
Expand All @@ -74,8 +78,7 @@ class PaymentItemSpec extends UnitSpec {
"not write empty fields" in {

val emptyPaymentItemModel: PaymentItem =
PaymentItem(amount = None, received = None)

PaymentItem(amount = None, received = None, paymentLot = None, paymentLotItem = None)
Json.toJson(emptyPaymentItemModel) shouldBe JsObject.empty
}
}
Expand Down
22 changes: 14 additions & 8 deletions test/v1/models/response/payments/PaymentSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class PaymentSpec extends UnitSpec {
taxPeriod = Some(TaxPeriod(from = "2017-02-01", to = "2017-02-28")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(5.00), received = Some("2017-02-11"))
PaymentItem(amount = Some(5.00), received = Some("2017-02-11"), paymentLot = Some("081203010024"), paymentLotItem = Some("000001")),
))
)

Expand All @@ -153,8 +153,8 @@ class PaymentSpec extends UnitSpec {
taxPeriod = Some(TaxPeriod("2017-03-01", "2017-03-25")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(50.00), received = Some("2017-03-11")),
PaymentItem(amount = Some(1000.00), received = Some("2017-03-12"))
PaymentItem(amount = Some(50.00), received = Some("2017-03-11"), paymentLot = Some("081203010024"), paymentLotItem = Some("000001")),
PaymentItem(amount = Some(1000.00), received = Some("2017-03-12"), paymentLot = Some("081203010024"), paymentLotItem = Some("000001"))
))
)

Expand Down Expand Up @@ -205,15 +205,21 @@ class PaymentSpec extends UnitSpec {
| "items": [
| {
| "clearingDate":"2017-02-11",
| "paymentAmount":5.0
| "paymentAmount":5.0,
| "paymentLot":"081203010024",
| "paymentLotItem":"000001"
| },
| {
| "paymentAmount":-15.2
| "paymentAmount":-15.2,
| "paymentLot":"01234",
| "paymentLotItem":"0001"
| },
| {
| "subItem":"001",
| "dueDate":"2017-03-02",
| "amount":1001.00
| "amount":1001.00,
| "paymentLot":"6789",
| "paymentLotItem":"0002"
| }
|
| ]
Expand All @@ -226,8 +232,8 @@ class PaymentSpec extends UnitSpec {
taxPeriod = Some(TaxPeriod("2017-02-01", "2017-02-28")),
`type` = "VAT Return Debit Charge",
paymentItems = Some(Seq(
PaymentItem(amount = Some(5.00), received = Some("2017-02-11")),
PaymentItem(amount = Some(-15.2), received = None)
PaymentItem(amount = Some(5.00), received = Some("2017-02-11"), paymentLot = Some("081203010024"), paymentLotItem = Some("000001")),
PaymentItem(amount = Some(-15.2), received = None, paymentLot = Some("01234"), paymentLotItem = Some("0001"))
))
)

Expand Down
Loading

0 comments on commit 66aca40

Please sign in to comment.