-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from hmrc/feature/yta-3215
YTA-3215: Added endpoint for Payment History with Allocations.
- Loading branch information
Showing
23 changed files
with
1,359 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
app/uk/gov/hmrc/epayeapi/controllers/GetPaymentHistoryWithAllocationsController.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright 2018 HM Revenue & Customs | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package uk.gov.hmrc.epayeapi.controllers | ||
|
||
import javax.inject.{Inject, Singleton} | ||
|
||
import akka.stream.Materializer | ||
import play.api.libs.json.Json | ||
import play.api.mvc.{Action, EssentialAction, Result} | ||
import uk.gov.hmrc.auth.core.AuthConnector | ||
import uk.gov.hmrc.domain.EmpRef | ||
import uk.gov.hmrc.epayeapi.connectors.{EpayeApiConfig, EpayeConnector} | ||
import uk.gov.hmrc.epayeapi.models.Formats.paymentHistoryWithAllocationsJsonWrites | ||
import uk.gov.hmrc.epayeapi.models.TaxYear | ||
import uk.gov.hmrc.epayeapi.models.in.{EpayePaymentHistory, EpayePaymentHistoryWithAllocations, EpayeResponse, EpayeSuccess} | ||
import uk.gov.hmrc.epayeapi.models.out.PaymentHistoryWithAllocationsJson | ||
|
||
import scala.concurrent.ExecutionContext | ||
|
||
@Singleton | ||
case class GetPaymentHistoryWithAllocationsController @Inject() ( | ||
config: EpayeApiConfig, | ||
authConnector: AuthConnector, | ||
epayeConnector: EpayeConnector, | ||
implicit val ec: ExecutionContext, | ||
implicit val mat: Materializer | ||
) | ||
extends ApiController | ||
with EpayeErrorHandler { | ||
|
||
def getPaymentHistoryWithAllocations(empRef: EmpRef, taxYear: TaxYear): EssentialAction = { | ||
EmpRefAction(empRef) { | ||
Action.async { implicit request => | ||
val epayePaymentHistory = epayeConnector.getPaymentHistoryWithAllocations(empRef, taxYear, hc) | ||
epayePaymentHistory.map { | ||
successHandler(empRef, taxYear) orElse errorHandler | ||
} | ||
} | ||
} | ||
} | ||
|
||
private def successHandler(empRef: EmpRef, taxYear: TaxYear): PartialFunction[EpayeResponse[EpayePaymentHistoryWithAllocations], Result] = { | ||
case EpayeSuccess(epayePaymentHistory) => | ||
val paymentHistory = PaymentHistoryWithAllocationsJson.transform(config.apiBaseUrl, empRef, taxYear, epayePaymentHistory) | ||
|
||
Ok(Json.toJson(paymentHistory)) | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
app/uk/gov/hmrc/epayeapi/models/in/EpayePaymentHistoryWithAllocations.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright 2018 HM Revenue & Customs | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package uk.gov.hmrc.epayeapi.models.in | ||
|
||
import org.joda.time.LocalDate | ||
import uk.gov.hmrc.epayeapi.models.TaxYear | ||
|
||
case class EpayePaymentHistoryWithAllocations( | ||
taxYear: TaxYear, | ||
payments: Seq[EpayePaymentHistoryWithAllocationsPayment] | ||
) | ||
|
||
case class EpayePaymentHistoryWithAllocationsPayment( | ||
paymentDate: Option[LocalDate], | ||
method: Option[String], | ||
amount: BigDecimal, | ||
allocatedAmount: BigDecimal, | ||
allocations: Seq[EpayePaymentAllocation] | ||
) | ||
|
||
trait EpayePaymentAllocation { | ||
def period: EpayeTaxPeriod | ||
def amount: BigDecimal | ||
def code: Option[EpayeCode] | ||
|
||
lazy val taxYear: TaxYear = TaxYear(period.startingTaxYear) | ||
lazy val taxMonth: EpayeTaxMonth = EpayeTaxMonth.fromLocalDate(period.taxFrom) | ||
} | ||
|
||
case class EpayeRtiPaymentAllocation( | ||
period: EpayeTaxPeriod, | ||
amount: BigDecimal | ||
) extends EpayePaymentAllocation { | ||
lazy val code: Option[EpayeCode] = None | ||
} | ||
|
||
case class EpayeNonRtiPaymentAllocation( | ||
period: EpayeTaxPeriod, | ||
amount: BigDecimal, | ||
code: Option[EpayeCode] | ||
) extends EpayePaymentAllocation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright 2018 HM Revenue & Customs | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package uk.gov.hmrc.epayeapi.models.in | ||
|
||
import org.joda.time.LocalDate | ||
|
||
case class EpayeTaxPeriod(taxFrom: LocalDate, taxTo: LocalDate) { | ||
/** | ||
* Gets the TaxMonth from a tax period. This requires the period's start date to be on the 6th of the given month | ||
* and the end date to be on the 5th of the next month otherwise it is considered invalid | ||
* | ||
* Note: For quirky reasons which will go away soon, the start date is also valid if it is on the 4th... | ||
* | ||
*/ | ||
def taxMonth: Option[Int] = { | ||
implicit val dateAscendingOrdering = uk.gov.hmrc.epayeapi.models.ImplicitOrderings.localDateDescendingOrdering.reverse | ||
|
||
val Seq(lowerDate, upperDate) = Seq(taxFrom, taxTo).sorted | ||
val expectedTo1 = lowerDate.plusMonths(1).minusDays(1) | ||
val isTaxToCorrect1 = expectedTo1 == upperDate | ||
(lowerDate.getMonthOfYear, lowerDate.getDayOfMonth) match { | ||
case (m, 6) if isTaxToCorrect1 => Some(((m + 8) % 12) + 1) | ||
case _ => None | ||
} | ||
} | ||
|
||
def taxYear: Option[Int] = | ||
if (taxFrom == startOfTaxYear && taxTo == endOfTaxYear) { | ||
Some(taxFrom.getYear) | ||
} else { | ||
None | ||
} | ||
|
||
def startingTaxYear: Int = | ||
if (taxFrom.isBefore(startOfTaxYear)) { | ||
taxFrom.getYear - 1 | ||
} else { | ||
taxFrom.getYear | ||
} | ||
|
||
private def startOfTaxYear: LocalDate = new LocalDate(taxFrom.getYear, 4, 6) | ||
|
||
private def endOfTaxYear: LocalDate = startOfTaxYear.plusYears(1).minusDays(1) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
app/uk/gov/hmrc/epayeapi/models/out/PaymentHistoryWithAllocationsJson.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/* | ||
* Copyright 2018 HM Revenue & Customs | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package uk.gov.hmrc.epayeapi.models.out | ||
|
||
import org.joda.time.LocalDate | ||
import play.api.Logger | ||
import uk.gov.hmrc.domain.EmpRef | ||
import uk.gov.hmrc.epayeapi.models.{TaxMonth, TaxYear} | ||
import uk.gov.hmrc.epayeapi.models.in.{EpayePaymentAllocation, EpayePaymentHistoryWithAllocations, EpayePaymentHistoryWithAllocationsPayment, EpayeRtiPaymentAllocation} | ||
|
||
case class PaymentHistoryWithAllocationsJson ( | ||
taxOfficeNumber: String, | ||
taxOfficeReference: String, | ||
taxYear: TaxYear, | ||
payments: Seq[PaymentWithAllocations], | ||
_links: PaymentHistoryWithAllocationsLinks | ||
) | ||
|
||
case class PaymentWithAllocations( | ||
paymentDate: LocalDate, | ||
method: Option[String], | ||
amount: BigDecimal, | ||
allocatedAmount: BigDecimal, | ||
allocations: Seq[PaymentAllocation] | ||
) | ||
|
||
case class PaymentAllocation( | ||
taxYear: TaxYear, | ||
taxMonth: TaxMonth, | ||
amount: BigDecimal, | ||
code: Option[String] | ||
) | ||
|
||
object PaymentAllocation{ | ||
def transform(epayePaymentAllocation: EpayePaymentAllocation): PaymentAllocation = { | ||
PaymentAllocation( | ||
epayePaymentAllocation.taxYear, | ||
TaxMonth(epayePaymentAllocation.taxYear, epayePaymentAllocation.taxMonth.month), | ||
epayePaymentAllocation.amount, | ||
epayePaymentAllocation.code.map{_.name} | ||
) | ||
} | ||
} | ||
|
||
case class PaymentHistoryWithAllocationsLinks ( | ||
empRefs: Link, | ||
summary: Link, | ||
statements: Link, | ||
payments: Link, | ||
self: Link, | ||
next: Link, | ||
previous: Link | ||
) | ||
|
||
object PaymentWithAllocations { | ||
import uk.gov.hmrc.epayeapi.models.ImplicitOrderings.localDateDescendingOrdering | ||
|
||
implicit val paymentDescendingOrdering = Ordering.by[PaymentWithAllocations, (LocalDate, BigDecimal)](payment => (payment.paymentDate, -payment.amount)) | ||
|
||
private lazy val paymentMethods: Map[String, String] = Map( | ||
"TPS RECEIPTS BY DEBIT CARD" -> "Debit Card", | ||
"PAYMENTS MADE BY CHEQUE" -> "Cheque", | ||
"CHEQUE RECEIPTS" -> "Cheque", | ||
"BACS RECEIPTS" -> "BACS", | ||
"CHAPS" -> "CHAPS", | ||
"TPS RECEIPTS BY CREDIT CARD" -> "Credit Card", | ||
"NATIONAL DIRECT DEBIT RECEIPTS" -> "Direct Debit", | ||
"BILLPAY/OLPG/GIROBANK" -> "Online Payment", | ||
"BANK LODGEMENT PAYMENT" -> "Bank Lodgement", | ||
"BANK GIRO RECEIPTS" -> "Giro Receipts", | ||
"BANK GIRO IN CREDITS" -> "Giro Credits", | ||
"FPS RECEIPTS" -> "FPS Receipts", | ||
"CREDIT FOR INTERNET RECEIPTS" -> "Internet Receipts", | ||
"GIROBANK RECEIPTS" -> "Girobank", | ||
"GIROBANK/ POST OFFICE" -> "Post Office", | ||
"NIL DECLARATIONS" -> "Nil Declarations", | ||
"PAYMASTER" -> "Paymaster", | ||
"VOLUNTARY DIRECT PAYMENTS" -> "Voluntary Payments" | ||
) withDefault { unknown => | ||
Logger.warn(s"Invalid payment method: [${unknown}].") | ||
"UNKNOWN" | ||
} | ||
|
||
def transform(paymentMethodMaybe: Option[String]): Option[String] = { | ||
paymentMethodMaybe.map { paymentMethods } | ||
} | ||
} | ||
|
||
object PaymentHistoryWithAllocationsJson { | ||
def transform( | ||
apiBaseUrl: String, | ||
empRef: EmpRef, | ||
taxYear: TaxYear, | ||
epayePaymentHistory: EpayePaymentHistoryWithAllocations): PaymentHistoryWithAllocationsJson = { | ||
|
||
val payments: Seq[PaymentWithAllocations] = for { | ||
epayePayment <- epayePaymentHistory.payments | ||
epayePaymentDate <- epayePayment.paymentDate | ||
} yield toPaymentWithAllocations(epayePayment, epayePaymentDate) | ||
|
||
PaymentHistoryWithAllocationsJson( | ||
empRef.taxOfficeNumber, | ||
empRef.taxOfficeReference, | ||
taxYear, | ||
payments.sorted(PaymentWithAllocations.paymentDescendingOrdering), | ||
PaymentHistoryWithAllocationsLinks( | ||
empRefs = Link.empRefsLink, | ||
summary = Link.summaryLink(empRef), | ||
statements = Link.statementsLink(empRef), | ||
payments = Link.paymentHistoryLink(empRef, taxYear), | ||
self = Link.paymentHistoryWithAllocationsLink(empRef, taxYear), | ||
next = Link.paymentHistoryWithAllocationsLink(empRef, taxYear.next), | ||
previous = Link.paymentHistoryWithAllocationsLink(empRef, taxYear.previous) | ||
) | ||
) | ||
} | ||
|
||
private def toPaymentWithAllocations( | ||
epayePaymentWithAllocations: EpayePaymentHistoryWithAllocationsPayment, | ||
epayePaymentDate: LocalDate): PaymentWithAllocations = { | ||
|
||
PaymentWithAllocations( | ||
epayePaymentDate, | ||
PaymentWithAllocations.transform(epayePaymentWithAllocations.method), | ||
epayePaymentWithAllocations.amount, | ||
epayePaymentWithAllocations.allocatedAmount, | ||
epayePaymentWithAllocations.allocations.map{ PaymentAllocation.transform }) | ||
} | ||
} |
Oops, something went wrong.