Skip to content

Commit e948883

Browse files
authored
Merge pull request #36 from hmrc/feature/YTA-3163/retrieve-emprefs-from-epaye-service
Feature/yta 3163/retrieve emprefs from epaye service
2 parents 3179ee5 + 713926b commit e948883

20 files changed

+583
-522
lines changed

app/uk/gov/hmrc/epayeapi/controllers/ApiController.scala

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
package uk.gov.hmrc.epayeapi.controllers
1818

1919
import akka.stream.Materializer
20+
import play.api.Logger
2021
import play.api.libs.json.Json
2122
import play.api.libs.streams.Accumulator
2223
import play.api.mvc._
2324
import uk.gov.hmrc.auth.core._
24-
import uk.gov.hmrc.auth.core.retrieve.{Retrieval, Retrievals}
25+
import uk.gov.hmrc.auth.core.retrieve.Retrievals
2526
import uk.gov.hmrc.domain.EmpRef
2627
import uk.gov.hmrc.epayeapi.models.Formats._
2728
import uk.gov.hmrc.epayeapi.models.out.ApiErrorJson
@@ -43,37 +44,22 @@ trait ApiController extends BaseController with AuthorisedFunctions {
4344
Accumulator.done {
4445
authorised(enrolment) {
4546
action(request).run()
46-
} recover recoverAuthFailure
47+
} recover logAuthError(recoverAuthFailure)
4748
}
4849
}
4950

50-
def EnrolmentsAction(enrolment: Enrolment, retrieveEnrolments: Retrieval[Enrolments])(action: Enrolments => EssentialAction): EssentialAction = {
51-
EssentialAction { implicit request =>
52-
Accumulator.done {
53-
authorised(enrolment.withDelegatedAuthRule("epaye-auth"))
54-
.retrieve(retrieveEnrolments) { enrolments =>
55-
action(enrolments)(request).run()
56-
} recover recoverAuthFailure
57-
}
58-
}
59-
}
51+
def EmpRefAction(empRefFromUrl: EmpRef)(action: EssentialAction): EssentialAction = {
52+
val enrolment = epayeEnrolment
53+
.withEmpRef(empRefFromUrl)
54+
.withDelegatedAuth
6055

61-
def EmpRefsAction(action: Set[EmpRef] => EssentialAction): EssentialAction =
62-
EnrolmentsAction(epayeEnrolment, epayeRetrieval) { enrolments =>
63-
EssentialAction { request =>
64-
action(enrolments.enrolments.flatMap(enrolmentToEmpRef))(request)
65-
}
66-
}
56+
AuthorisedAction(enrolment)(action)
57+
}
6758

68-
def EmpRefAction(empRefFromUrl: EmpRef)(action: EssentialAction): EssentialAction = {
69-
EmpRefsAction { empRefsFromAuth =>
70-
EssentialAction { request =>
71-
empRefsFromAuth.find(_ == empRefFromUrl) match {
72-
case Some(empRef) => action(request)
73-
case None => Accumulator.done(invalidEmpRef)
74-
}
75-
}
76-
}
59+
def logAuthError(pf: PartialFunction[Throwable, Result]): PartialFunction[Throwable, Result] = {
60+
case ex: Throwable =>
61+
Logger.info("Recovering from auth error:", ex)
62+
pf(ex)
7763
}
7864

7965
def recoverAuthFailure: PartialFunction[Throwable, Result] = {
@@ -97,13 +83,14 @@ trait ApiController extends BaseController with AuthorisedFunctions {
9783
def invalidEmpRef: Result =
9884
Forbidden(Json.toJson(InvalidEmpRef))
9985

100-
private def enrolmentToEmpRef(enrolment: Enrolment): Option[EmpRef] = {
101-
for {
102-
"IR-PAYE" <- Option(enrolment.key)
103-
tn <- enrolment.identifiers.find(_.key == "TaxOfficeNumber")
104-
tr <- enrolment.identifiers.find(_.key == "TaxOfficeReference")
105-
if enrolment.isActivated
106-
} yield EmpRef(tn.value, tr.value)
86+
implicit class EnrolmentOps(val enrolment: Enrolment) {
87+
def withDelegatedAuth: Enrolment =
88+
enrolment.withDelegatedAuthRule("epaye-auth")
89+
90+
def withEmpRef(empRef: EmpRef): Enrolment =
91+
enrolment
92+
.withIdentifier("TaxOfficeNumber", empRef.taxOfficeNumber)
93+
.withIdentifier("TaxOfficeReference", empRef.taxOfficeReference)
10794
}
10895
}
10996

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2018 HM Revenue & Customs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package uk.gov.hmrc.epayeapi.controllers
18+
19+
import play.api.Logger
20+
import play.api.libs.json.{JsError, Json}
21+
import play.api.mvc.{Controller, Result}
22+
import uk.gov.hmrc.epayeapi.models.Formats._
23+
import uk.gov.hmrc.epayeapi.models.in._
24+
import uk.gov.hmrc.epayeapi.models.out.ApiErrorJson
25+
import uk.gov.hmrc.epayeapi.models.out.ApiErrorJson.EmpRefNotFound
26+
27+
trait EpayeErrorHandler extends Controller {
28+
def errorHandler: PartialFunction[EpayeResponse[_], Result] = {
29+
case EpayeJsonError(err) =>
30+
Logger.error(s"epaye service returned invalid json: ${Json.prettyPrint(JsError.toJson(err))}")
31+
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
32+
case EpayeNotFound() =>
33+
Logger.info("epaye service returned a 404")
34+
NotFound(Json.toJson(EmpRefNotFound))
35+
case EpayeError(status, _) =>
36+
Logger.error(s"epaye service returned unexpected response: status=$status")
37+
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
38+
case EpayeException(message) =>
39+
Logger.error(s"Caught exception while calling epaye service: message=$message")
40+
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
41+
}
42+
43+
}

app/uk/gov/hmrc/epayeapi/controllers/GetAnnualStatementController.scala

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,15 @@ package uk.gov.hmrc.epayeapi.controllers
1919
import javax.inject.{Inject, Singleton}
2020

2121
import akka.stream.Materializer
22-
import play.api.Logger
2322
import play.api.libs.json.Json
24-
import play.api.mvc.{Action, EssentialAction}
23+
import play.api.mvc.{Action, EssentialAction, Result}
2524
import uk.gov.hmrc.auth.core.AuthConnector
2625
import uk.gov.hmrc.domain.EmpRef
2726
import uk.gov.hmrc.epayeapi.connectors.{EpayeApiConfig, EpayeConnector}
2827
import uk.gov.hmrc.epayeapi.models.Formats._
2928
import uk.gov.hmrc.epayeapi.models.TaxYear
3029
import uk.gov.hmrc.epayeapi.models.in._
31-
import uk.gov.hmrc.epayeapi.models.out.ApiErrorJson.EmpRefNotFound
32-
import uk.gov.hmrc.epayeapi.models.out.{AnnualStatementJson, ApiErrorJson}
30+
import uk.gov.hmrc.epayeapi.models.out.AnnualStatementJson
3331

3432
import scala.concurrent.ExecutionContext
3533

@@ -41,23 +39,20 @@ case class GetAnnualStatementController @Inject() (
4139
implicit val ec: ExecutionContext,
4240
implicit val mat: Materializer
4341
)
44-
extends ApiController {
42+
extends ApiController
43+
with EpayeErrorHandler {
4544

4645
def getAnnualStatement(empRef: EmpRef, taxYear: TaxYear): EssentialAction =
4746
EmpRefAction(empRef) {
4847
Action.async { request =>
4948
epayeConnector.getAnnualStatement(empRef, taxYear, hc(request)).map {
50-
case EpayeSuccess(epayeAnnualStatement) =>
51-
Ok(Json.toJson(AnnualStatementJson(config.apiBaseUrl, empRef, taxYear, epayeAnnualStatement)))
52-
case EpayeJsonError(err) =>
53-
Logger.error(s"Upstream returned invalid json: $err")
54-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
55-
case EpayeNotFound() =>
56-
NotFound(Json.toJson(EmpRefNotFound))
57-
case error: EpayeResponse[_] =>
58-
Logger.error(s"Error while fetching totals: $error")
59-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
49+
successHandler(empRef, taxYear).orElse(errorHandler)
6050
}
6151
}
6252
}
53+
54+
def successHandler(empRef: EmpRef, taxYear: TaxYear): PartialFunction[EpayeResponse[EpayeAnnualStatement], Result] = {
55+
case EpayeSuccess(epayeAnnualStatement) =>
56+
Ok(Json.toJson(AnnualStatementJson(config.apiBaseUrl, empRef, taxYear, epayeAnnualStatement)))
57+
}
6358
}

app/uk/gov/hmrc/epayeapi/controllers/GetEmpRefsController.scala

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ case class GetEmpRefsController @Inject() (
3939
implicit val ec: ExecutionContext,
4040
implicit val mat: Materializer
4141
)
42-
extends ApiController {
42+
extends ApiController
43+
with EpayeErrorHandler {
4344

4445
def getEmpRefs(): EssentialAction = AuthorisedAction(epayeEnrolment) {
4546
Action.async { implicit request =>
@@ -52,18 +53,8 @@ case class GetEmpRefsController @Inject() (
5253

5354
def successHandler: PartialFunction[EpayeResponse[EpayeEmpRefsResponse], Result] = {
5455
case EpayeSuccess(EpayeEmpRefsResponse(empRefs)) =>
56+
Logger.error(s"EmpRefs received: $empRefs")
5557
val empRefsJson = EmpRefsJson.fromSeq(config.apiBaseUrl, empRefs)
5658
Ok(Json.toJson(empRefsJson))
5759
}
58-
59-
def errorHandler: PartialFunction[EpayeResponse[EpayeEmpRefsResponse], Result] = {
60-
case EpayeJsonError(err) =>
61-
Logger.error(s"Upstream returned invalid json: $err")
62-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
63-
case EpayeNotFound() =>
64-
NotFound(Json.toJson(EmpRefNotFound))
65-
case error: EpayeResponse[_] =>
66-
Logger.error(s"Error while fetching totals: $error")
67-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
68-
}
6960
}

app/uk/gov/hmrc/epayeapi/controllers/GetMonthlyStatementController.scala

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,14 @@ package uk.gov.hmrc.epayeapi.controllers
1919
import javax.inject.{Inject, Singleton}
2020

2121
import akka.stream.Materializer
22-
import play.api.Logger
2322
import play.api.libs.json.Json
24-
import play.api.mvc.{Action, EssentialAction}
23+
import play.api.mvc.{Action, EssentialAction, Result}
2524
import uk.gov.hmrc.auth.core.AuthConnector
2625
import uk.gov.hmrc.domain.EmpRef
2726
import uk.gov.hmrc.epayeapi.connectors.{EpayeApiConfig, EpayeConnector}
2827
import uk.gov.hmrc.epayeapi.models.Formats._
29-
import uk.gov.hmrc.epayeapi.models.in.{EpayeJsonError, EpayeNotFound, EpayeResponse, EpayeSuccess}
30-
import uk.gov.hmrc.epayeapi.models.out.ApiErrorJson.EmpRefNotFound
31-
import uk.gov.hmrc.epayeapi.models.out.{ApiErrorJson, MonthlyStatementJson}
28+
import uk.gov.hmrc.epayeapi.models.in._
29+
import uk.gov.hmrc.epayeapi.models.out.MonthlyStatementJson
3230
import uk.gov.hmrc.epayeapi.models.{TaxMonth, TaxYear}
3331

3432
import scala.concurrent.ExecutionContext
@@ -41,7 +39,8 @@ case class GetMonthlyStatementController @Inject() (
4139
implicit val ec: ExecutionContext,
4240
implicit val mat: Materializer
4341
)
44-
extends ApiController {
42+
extends ApiController
43+
with EpayeErrorHandler {
4544

4645
def getStatement(empRef: EmpRef, taxYear: TaxYear, taxMonth: TaxMonth): EssentialAction =
4746
EmpRefAction(empRef) {
@@ -52,25 +51,13 @@ case class GetMonthlyStatementController @Inject() (
5251
taxYear,
5352
taxMonth
5453
).map {
55-
case EpayeSuccess(json) =>
56-
Ok(Json.toJson(
57-
MonthlyStatementJson(
58-
config.apiBaseUrl,
59-
empRef,
60-
taxYear,
61-
taxMonth,
62-
json
63-
)
64-
))
65-
case EpayeNotFound() =>
66-
NotFound(Json.toJson(EmpRefNotFound))
67-
case EpayeJsonError(error) =>
68-
Logger.error(s"Upstream returned invalid json: $error")
69-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
70-
case error: EpayeResponse[_] =>
71-
Logger.error(s"Error while fetching totals: $error")
72-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
54+
successHandler(empRef, taxYear, taxMonth) orElse errorHandler
7355
}
7456
}
7557
}
58+
59+
def successHandler(empRef: EmpRef, taxYear: TaxYear, taxMonth: TaxMonth): PartialFunction[EpayeResponse[EpayeMonthlyStatement], Result] = {
60+
case EpayeSuccess(json) =>
61+
Ok(Json.toJson(MonthlyStatementJson(config.apiBaseUrl, empRef, taxYear, taxMonth, json)))
62+
}
7663
}

app/uk/gov/hmrc/epayeapi/controllers/GetSummaryController.scala

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,14 @@ package uk.gov.hmrc.epayeapi.controllers
1919
import javax.inject.{Inject, Singleton}
2020

2121
import akka.stream.Materializer
22-
import play.api.Logger
2322
import play.api.libs.json.Json
24-
import play.api.mvc.{Action, EssentialAction}
23+
import play.api.mvc.{Action, EssentialAction, Result}
2524
import uk.gov.hmrc.auth.core.AuthConnector
2625
import uk.gov.hmrc.domain.EmpRef
2726
import uk.gov.hmrc.epayeapi.connectors.{EpayeApiConfig, EpayeConnector}
2827
import uk.gov.hmrc.epayeapi.models.Formats._
29-
import uk.gov.hmrc.epayeapi.models.in.{EpayeJsonError, EpayeNotFound, EpayeResponse, EpayeSuccess}
30-
import uk.gov.hmrc.epayeapi.models.out.ApiErrorJson.EmpRefNotFound
31-
import uk.gov.hmrc.epayeapi.models.out.{ApiErrorJson, SummaryJson}
28+
import uk.gov.hmrc.epayeapi.models.in._
29+
import uk.gov.hmrc.epayeapi.models.out.SummaryJson
3230

3331
import scala.concurrent.ExecutionContext
3432

@@ -40,23 +38,20 @@ case class GetSummaryController @Inject() (
4038
implicit val ec: ExecutionContext,
4139
implicit val mat: Materializer
4240
)
43-
extends ApiController {
41+
extends ApiController
42+
with EpayeErrorHandler {
4443

4544
def getSummary(empRef: EmpRef): EssentialAction =
4645
EmpRefAction(empRef) {
4746
Action.async { request =>
4847
epayeConnector.getTotal(empRef, hc(request)).map {
49-
case EpayeSuccess(totals) =>
50-
Ok(Json.toJson(SummaryJson(config.apiBaseUrl, empRef, totals)))
51-
case EpayeJsonError(err) =>
52-
Logger.error(s"Upstream returned invalid json: $err")
53-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
54-
case EpayeNotFound() =>
55-
NotFound(Json.toJson(EmpRefNotFound))
56-
case error: EpayeResponse[_] =>
57-
Logger.error(s"Error while fetching totals: $error")
58-
InternalServerError(Json.toJson(ApiErrorJson.InternalServerError))
48+
successHandler(empRef) orElse errorHandler
5949
}
6050
}
6151
}
52+
53+
def successHandler(empRef: EmpRef): PartialFunction[EpayeResponse[EpayeTotalsResponse], Result] = {
54+
case EpayeSuccess(totals) =>
55+
Ok(Json.toJson(SummaryJson(config.apiBaseUrl, empRef, totals)))
56+
}
6257
}

app/uk/gov/hmrc/epayeapi/modules/AppModule.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import uk.gov.hmrc.play.config.ServicesConfig
3232
class AppModule() extends AbstractModule {
3333
def configure(): Unit = {
3434
bind(classOf[PlayAuthConnector]).to(classOf[MicroserviceAuthConnector]).asEagerSingleton()
35-
// bind(classOf[WSHttp]).to(classOf[WSHttp]).asEagerSingleton()
3635
bind(classOf[Startup]).to(classOf[AppStartup]).asEagerSingleton()
3736
}
3837

app/uk/gov/hmrc/epayeapi/router/ApiRouter.scala

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
package uk.gov.hmrc.epayeapi.router
18-
18+
import ApiRouter._
1919
import javax.inject.{Inject, Singleton}
2020

2121
import play.api.routing.Router.Routes
@@ -34,28 +34,6 @@ case class ApiRouter @Inject() (
3434
getMonthlyStatementController: GetMonthlyStatementController
3535
) extends SimpleRouter {
3636

37-
object TaxOfficeNumber {
38-
val regex = "([0-9a-zA-Z]{3})".r
39-
def unapply(string: String): Option[String] = {
40-
string match {
41-
case regex(result) => Some(result)
42-
case _ => None
43-
}
44-
}
45-
}
46-
47-
48-
object TaxOfficeReference {
49-
val regex = "([0-9a-zA-Z]{7,10})".r
50-
def unapply(string: String): Option[String] = {
51-
string match {
52-
case regex(result) => Some(result)
53-
case _ => None
54-
}
55-
}
56-
}
57-
58-
5937
val appRoutes = Router.from {
6038
case GET(p"/") =>
6139
getEmpRefsController.getEmpRefs()
@@ -73,3 +51,25 @@ case class ApiRouter @Inject() (
7351
val routes: Routes = prodRoutes.routes.orElse(appRoutes.routes)
7452

7553
}
54+
55+
object ApiRouter {
56+
object TaxOfficeNumber {
57+
val regex = "(\\d{3})".r
58+
def unapply(string: String): Option[String] = {
59+
string match {
60+
case regex(result) => Some(result)
61+
case _ => None
62+
}
63+
}
64+
}
65+
66+
object TaxOfficeReference {
67+
val regex = "([0-9A-Z]{1,10})".r
68+
def unapply(string: String): Option[String] = {
69+
string match {
70+
case regex(result) => Some(result)
71+
case _ => None
72+
}
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)