Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
38fbc5c
[PIL-2186] - Move to Scala37
joshua-lamptey Oct 9, 2025
c9574b5
[PIL-2186] - imports
joshua-lamptey Oct 10, 2025
27315bc
[PIL-2186] - scalafix
joshua-lamptey Oct 10, 2025
5661b16
[PIL-2186] - imports
joshua-lamptey Oct 10, 2025
991d1ef
[PIL-2186] - attempt scalacoptions fix
joshua-lamptey Oct 10, 2025
f07a837
Removed implicit keyword and replaced with Scala 3
joshua-lamptey Oct 20, 2025
0f9113e
[PIL-2186] - fixes
joshua-lamptey Oct 21, 2025
0ce16dc
[PIL-2186] - extension
joshua-lamptey Oct 21, 2025
1c7ba11
[PIL-2186] - import fix
joshua-lamptey Oct 21, 2025
5fa12a1
[PIL-2186] - import
joshua-lamptey Oct 21, 2025
af27a56
[PIL-2186] - lower coverage while keeping it above 90 still
joshua-lamptey Oct 21, 2025
aee5996
[PIL-2186] - use direct ec global impl
joshua-lamptey Oct 21, 2025
92c01cc
[PIL-2186] - mockito update
joshua-lamptey Oct 21, 2025
ddb33b5
[PIL-2186] - mockito update
joshua-lamptey Oct 21, 2025
be83d59
[PIL-2186] - mockito update
joshua-lamptey Oct 21, 2025
550d4f5
[PIL-2186] - try adding distinct back to it project
joshua-lamptey Oct 21, 2025
e4f1b65
[PIL-2186] - remove tpolecat, stop using deprecated 'in' in build.sbt
joshua-lamptey Oct 22, 2025
07d4d62
Revert "[PIL-2186] - remove tpolecat, stop using deprecated 'in' in b…
joshua-lamptey Oct 22, 2025
e2436ce
[PIL-2186] - add back tpolecat
joshua-lamptey Oct 22, 2025
08b91e4
[PIL-2186] - ignore duplicate flags warning to unblock build
joshua-lamptey Oct 22, 2025
8813bf0
[PIL-2186] - addressed comments
joshua-lamptey Oct 22, 2025
56d3566
[PIL-2186] - change compile to thisbuild to apply to both subprojects
joshua-lamptey Oct 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
version = 3.0.5
version = 3.9.10
runner.dialect = Scala3
style = defaultWithAlign
maxColumn = 150
lineEndings = unix
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package uk.gov.hmrc.pillar2submissionapi.connectors

import play.api.Logging
import play.api.libs.json.Json
import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse}
Expand All @@ -30,12 +31,12 @@ import scala.concurrent.{ExecutionContext, Future}

@Singleton
class GIRConnector @Inject() (
val config: AppConfig,
val http: HttpClientV2
)(implicit ec: ExecutionContext)
val config: AppConfig,
val http: HttpClientV2
)(using ec: ExecutionContext)
extends Logging {

def createGIR(request: GIRSubmission)(implicit hc: HeaderCarrier): Future[HttpResponse] = {
def createGIR(request: GIRSubmission)(using hc: HeaderCarrier): Future[HttpResponse] = {
val url = s"${config.stubBaseUrl}/pillar2/test/globe-information-return"
logger.info(s"Calling $url to create GIR submission")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import scala.concurrent.{ExecutionContext, Future}

class ObligationAndSubmissionsConnector @Inject() (val config: AppConfig, val http: HttpClientV2) extends Logging {

def getData(dateFrom: LocalDate, dateTo: LocalDate)(implicit hc: HeaderCarrier, ec: ExecutionContext): Future[HttpResponse] = {
def getData(dateFrom: LocalDate, dateTo: LocalDate)(using hc: HeaderCarrier, ec: ExecutionContext): Future[HttpResponse] = {
val url =
s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/obligations-and-submissions/$dateFrom/$dateTo"
logger.info(s"Calling the Obligations and Submissions with url: $url")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package uk.gov.hmrc.pillar2submissionapi.connectors
import play.api.Logging
import play.api.libs.json.Format.GenericFormat
import play.api.libs.json.Json
import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse}
Expand All @@ -30,30 +31,30 @@ import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class OverseasReturnNotificationConnector @Inject() (val config: AppConfig, val http: HttpClientV2)(implicit ec: ExecutionContext) extends Logging {
class OverseasReturnNotificationConnector @Inject() (val config: AppConfig, val http: HttpClientV2)(using ec: ExecutionContext) extends Logging {

private val ORNSubmitUrl: String = s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/overseas-return-notification/submit"
private val ORNAmendUrl: String = s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/overseas-return-notification/amend"
private def ORNRetrieveUrl(accountingPeriodFrom: String, accountingPeriodTo: String): String =
s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/overseas-return-notification/$accountingPeriodFrom/$accountingPeriodTo"

def submitORN(ORNSubmission: ORNSubmission)(implicit hc: HeaderCarrier): Future[HttpResponse] = {
def submitORN(ORNSubmission: ORNSubmission)(using hc: HeaderCarrier): Future[HttpResponse] = {
logger.info(s"Calling $ORNSubmitUrl to submit a ORN")
http
.post(URI.create(ORNSubmitUrl).toURL)
.withBody(Json.toJson(ORNSubmission))
.execute[HttpResponse]
}

def amendORN(ORNSubmission: ORNSubmission)(implicit hc: HeaderCarrier): Future[HttpResponse] = {
def amendORN(ORNSubmission: ORNSubmission)(using hc: HeaderCarrier): Future[HttpResponse] = {
logger.info(s"Calling $ORNAmendUrl to amend a ORN")
http
.put(URI.create(ORNAmendUrl).toURL)
.withBody(Json.toJson(ORNSubmission))
.execute[HttpResponse]
}

def retrieveORN(accountingPeriodFrom: String, accountingPeriodTo: String)(implicit hc: HeaderCarrier): Future[HttpResponse] = {
def retrieveORN(accountingPeriodFrom: String, accountingPeriodTo: String)(using hc: HeaderCarrier): Future[HttpResponse] = {
val url = ORNRetrieveUrl(accountingPeriodFrom, accountingPeriodTo)
logger.info(s"Calling $url to retrieve a ORN")
http
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package uk.gov.hmrc.pillar2submissionapi.connectors
import play.api.Logging
import play.api.libs.json.Format.GenericFormat
import play.api.libs.json.Json
import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse}
Expand All @@ -30,11 +31,11 @@ import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class SubmitBTNConnector @Inject() (val config: AppConfig, val http: HttpClientV2)(implicit ec: ExecutionContext) extends Logging {
class SubmitBTNConnector @Inject() (val config: AppConfig, val http: HttpClientV2)(using ec: ExecutionContext) extends Logging {

private val BTNSubmissionUrl: String = s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/below-threshold-notification/submit"

def submitBTN(BTNSubmission: BTNSubmission)(implicit hc: HeaderCarrier): Future[HttpResponse] = {
def submitBTN(BTNSubmission: BTNSubmission)(using hc: HeaderCarrier): Future[HttpResponse] = {
logger.info(s"Calling $BTNSubmissionUrl to submit a BTN")
http
.post(URI.create(BTNSubmissionUrl).toURL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SubscriptionConnector @Inject() (val config: AppConfig, val http: HttpClie

def readSubscription(
plrReference: String
)(implicit hc: HeaderCarrier, ec: ExecutionContext): Future[Either[Result, SubscriptionData]] = {
)(using hc: HeaderCarrier, ec: ExecutionContext): Future[Either[Result, SubscriptionData]] = {
val subscriptionUrl = s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/subscription/read-subscription/$plrReference"

val request = http
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package uk.gov.hmrc.pillar2submissionapi.connectors

import play.api.Logging
import play.api.libs.json.Json
import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse}
Expand All @@ -31,12 +32,12 @@ import scala.concurrent.{ExecutionContext, Future}

@Singleton
class TestOrganisationConnector @Inject() (
val config: AppConfig,
val http: HttpClientV2
)(implicit ec: ExecutionContext)
val config: AppConfig,
val http: HttpClientV2
)(using ec: ExecutionContext)
extends Logging {

def createTestOrganisation(pillar2Id: String, request: TestOrganisation)(implicit hc: HeaderCarrier): Future[TestOrganisationWithId] = {
def createTestOrganisation(pillar2Id: String, request: TestOrganisation)(using hc: HeaderCarrier): Future[TestOrganisationWithId] = {
val url = s"${config.stubBaseUrl}/pillar2/test/organisation/$pillar2Id"
logger.info(s"Calling $url to create test organisation")

Expand All @@ -49,14 +50,14 @@ class TestOrganisationConnector @Inject() (
case 201 => Json.parse(response.body).as[TestOrganisationWithId]
case 409 => throw OrganisationAlreadyExists(pillar2Id)
case 500 => throw DatabaseError("create")
case _ =>
case _ =>
logger.warn(s"Unexpected response from create organisation with status: ${response.status}")
throw UnexpectedResponse
}
}
}

def getTestOrganisation(pillar2Id: String)(implicit hc: HeaderCarrier): Future[TestOrganisationWithId] = {
def getTestOrganisation(pillar2Id: String)(using hc: HeaderCarrier): Future[TestOrganisationWithId] = {
val url = s"${config.stubBaseUrl}/pillar2/test/organisation/$pillar2Id"
logger.info(s"Calling $url to get test organisation")

Expand All @@ -67,14 +68,14 @@ class TestOrganisationConnector @Inject() (
response.status match {
case 200 => Json.parse(response.body).as[TestOrganisationWithId]
case 404 => throw OrganisationNotFound(pillar2Id)
case _ =>
case _ =>
logger.warn(s"Unexpected response from get organisation with status: ${response.status}")
throw UnexpectedResponse
}
}
}

def updateTestOrganisation(pillar2Id: String, request: TestOrganisation)(implicit hc: HeaderCarrier): Future[TestOrganisationWithId] = {
def updateTestOrganisation(pillar2Id: String, request: TestOrganisation)(using hc: HeaderCarrier): Future[TestOrganisationWithId] = {
val url = s"${config.stubBaseUrl}/pillar2/test/organisation/$pillar2Id"
logger.info(s"Calling $url to update test organisation")

Expand All @@ -87,14 +88,14 @@ class TestOrganisationConnector @Inject() (
case 200 => Json.parse(response.body).as[TestOrganisationWithId]
case 404 => throw OrganisationNotFound(pillar2Id)
case 500 => throw DatabaseError("update")
case _ =>
case _ =>
logger.warn(s"Unexpected response from update organisation with status: ${response.status}")
throw UnexpectedResponse
}
}
}

def deleteTestOrganisation(pillar2Id: String)(implicit hc: HeaderCarrier): Future[Unit] = {
def deleteTestOrganisation(pillar2Id: String)(using hc: HeaderCarrier): Future[Unit] = {
val url = s"${config.stubBaseUrl}/pillar2/test/organisation/$pillar2Id"
logger.info(s"Calling $url to delete test organisation")

Expand All @@ -106,7 +107,7 @@ class TestOrganisationConnector @Inject() (
case 204 => ()
case 404 => throw OrganisationNotFound(pillar2Id)
case 500 => throw DatabaseError("Failed to delete organisation and submission data")
case _ =>
case _ =>
logger.warn(s"Unexpected response from delete organisation with status: ${response.status}")
throw UnexpectedResponse
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package uk.gov.hmrc.pillar2submissionapi.connectors
import play.api.Logging
import play.api.libs.json.Format.GenericFormat
import play.api.libs.json.Json
import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue
import uk.gov.hmrc.http.HttpReads.Implicits._
import uk.gov.hmrc.http.client.HttpClientV2
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse}
Expand All @@ -30,18 +31,18 @@ import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class UKTaxReturnConnector @Inject() (val config: AppConfig, val http: HttpClientV2)(implicit ec: ExecutionContext) extends Logging {
class UKTaxReturnConnector @Inject() (val config: AppConfig, val http: HttpClientV2)(using ec: ExecutionContext) extends Logging {

private val uktrSubmissionUrl: String = s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/submit-uk-tax-return"
private val uktrAmendmentUrl: String = s"${config.pillar2BaseUrl}/report-pillar2-top-up-taxes/amend-uk-tax-return"

def submitUKTR(uktrSubmission: UKTRSubmission)(implicit hc: HeaderCarrier): Future[HttpResponse] = {
def submitUKTR(uktrSubmission: UKTRSubmission)(using hc: HeaderCarrier): Future[HttpResponse] = {
logger.info(s"Calling pillar2 backend: $uktrSubmissionUrl")
val request = http.post(URI.create(uktrSubmissionUrl).toURL()).withBody(Json.toJson(uktrSubmission))
request.execute[HttpResponse]
}

def amendUKTR(uktrSubmission: UKTRSubmission)(implicit hc: HeaderCarrier): Future[HttpResponse] = {
def amendUKTR(uktrSubmission: UKTRSubmission)(using hc: HeaderCarrier): Future[HttpResponse] = {
logger.info(s"Calling pillar2 backend: $uktrAmendmentUrl")
val request = http.put(URI.create(uktrAmendmentUrl).toURL()).withBody(Json.toJson(uktrSubmission))
request.execute[HttpResponse]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ class Pillar2ErrorHandler extends HttpErrorHandler with Logging {
val ret = e match {
case InvalidDateRange | InvalidDateFormat | InvalidJson | EmptyRequestBody | MissingHeader(_) | IncorrectHeaderValue =>
Results.BadRequest(Pillar2ErrorResponse(e.code, e.message))
case MissingCredentials | InvalidCredentials => Results.Unauthorized(Pillar2ErrorResponse(e.code, e.message))
case ForbiddenError | InvalidEnrolment | TestEndpointDisabled => Results.Forbidden(Pillar2ErrorResponse(e.code, e.message))
case OrganisationNotFound(_) | ORNNotFoundException => Results.NotFound(Pillar2ErrorResponse(e.code, e.message))
case OrganisationAlreadyExists(_) => Results.Conflict(Pillar2ErrorResponse(e.code, e.message))
case DownstreamValidationError(_, _) => Results.UnprocessableEntity(Pillar2ErrorResponse(e.code, e.message))
case MissingCredentials | InvalidCredentials => Results.Unauthorized(Pillar2ErrorResponse(e.code, e.message))
case ForbiddenError | InvalidEnrolment | TestEndpointDisabled => Results.Forbidden(Pillar2ErrorResponse(e.code, e.message))
case OrganisationNotFound(_) | ORNNotFoundException => Results.NotFound(Pillar2ErrorResponse(e.code, e.message))
case OrganisationAlreadyExists(_) => Results.Conflict(Pillar2ErrorResponse(e.code, e.message))
case DownstreamValidationError(_, _) => Results.UnprocessableEntity(Pillar2ErrorResponse(e.code, e.message))
case DatabaseError(_) | UnexpectedResponse | NoSubscriptionData(_) =>
Results.InternalServerError(Pillar2ErrorResponse(e.code, e.message))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ import scala.concurrent.{ExecutionContext, Future}

@Singleton
class AuthenticatedIdentifierAction @Inject() (
override val authConnector: AuthConnector,
val config: AppConfig
)(implicit val executionContext: ExecutionContext)
override val authConnector: AuthConnector,
val config: AppConfig
)(using val executionContext: ExecutionContext)
extends IdentifierAction
with AuthorisedFunctions
with Logging {
Expand Down Expand Up @@ -74,7 +74,7 @@ class AuthenticatedIdentifierAction @Inject() (
}

override protected def transform[A](request: RequestWithPillar2Id[A]): Future[IdentifierRequest[A]] = {
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)
given hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)
if (!request.headers.get(HeaderNames.authorisation).exists(_.trim.nonEmpty)) throw MissingCredentials
else {
val retrievals = Retrievals.internalId and Retrievals.groupIdentifier and
Expand All @@ -101,7 +101,7 @@ class AuthenticatedIdentifierAction @Inject() (
}
}

private def agentAuth[A](request: RequestWithPillar2Id[A], pillar2Id: String)(implicit hc: HeaderCarrier): Future[IdentifierRequest[A]] = {
private def agentAuth[A](request: RequestWithPillar2Id[A], pillar2Id: String)(using hc: HeaderCarrier): Future[IdentifierRequest[A]] = {
val retrievals = Retrievals.internalId and Retrievals.groupIdentifier and
Retrievals.allEnrolments and Retrievals.affinityGroup and
Retrievals.credentialRole and Retrievals.credentials
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import uk.gov.hmrc.pillar2submissionapi.controllers.error.MissingHeader.MissingP
import scala.concurrent.{ExecutionContext, Future}

case class Pillar2IdHeaderExistsAction @Inject() (
parser: BodyParsers.Default
)(implicit val executionContext: ExecutionContext)
parser: BodyParsers.Default
)(using val executionContext: ExecutionContext)
extends Pillar2IdHeaderAction {

override protected def transform[A](request: Request[A]): Future[RequestWithPillar2Id[A]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ import javax.inject.Inject
import scala.concurrent.{ExecutionContext, Future}

class SubscriptionDataRetrievalActionImpl @Inject() (
val subscriptionConnector: SubscriptionConnector
)(implicit val executionContext: ExecutionContext)
val subscriptionConnector: SubscriptionConnector
)(using val executionContext: ExecutionContext)
extends SubscriptionDataRetrievalAction
with Logging {

override protected def transform[A](request: IdentifierRequest[A]): Future[SubscriptionDataRequest[A]] = {
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)
given hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)

subscriptionConnector.readSubscription(request.clientPillar2Id).flatMap {
case Left(_) => Future.failed(NoSubscriptionData(request.clientPillar2Id))
case Left(_) => Future.failed(NoSubscriptionData(request.clientPillar2Id))
case Right(subscriptionData) =>
Future.successful(
SubscriptionDataRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ class ObligationsAndSubmissionsController @Inject() (
identify: IdentifierAction,
pillar2IdAction: Pillar2IdHeaderExistsAction,
obligationAndSubmissionsService: ObligationsAndSubmissionsService
)(implicit ec: ExecutionContext)
)(using ec: ExecutionContext)
extends BackendController(cc) {

def retrieveData(fromDate: String, toDate: String): Action[AnyContent] = (pillar2IdAction andThen identify).async { request =>
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request).withExtraHeaders("X-Pillar2-Id" -> request.clientPillar2Id)
given hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request).withExtraHeaders("X-Pillar2-Id" -> request.clientPillar2Id)
Try {
val accountingPeriod = ObligationsAndSubmissions(fromDate = LocalDate.parse(fromDate), toDate = LocalDate.parse(toDate))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ import scala.io.Source
class DocumentationController @Inject() (assets: Assets, cc: ControllerComponents, appConfig: AppConfig) extends BackendController(cc) {

def definition(): Action[AnyContent] = Action {
val json = Json.parse(Source.fromResource("public/api/definition.json").mkString)
val json = Json.parse(Source.fromResource("public/api/definition.json").mkString)
val optimus = (__ \ "api" \ "versions").json.update(
Reads
.list(
.list(using
(__ \ "status").json.update(Reads.of[JsString].map(_ => JsString(appConfig.apiPlatformStatus)))
andThen
(__ \ "endpointsEnabled").json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ class BTNSubmissionController @Inject() (
getSubscription: SubscriptionDataRetrievalAction,
pillar2IdAction: Pillar2IdHeaderExistsAction,
submitBTNService: SubmitBTNService
)(implicit ec: ExecutionContext)
)(using ec: ExecutionContext)
extends BackendController(cc) {

def submitBTN: Action[AnyContent] = (pillar2IdAction andThen identify andThen getSubscription).async { request =>
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request).withExtraHeaders("X-Pillar2-Id" -> request.clientPillar2Id)
given hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request).withExtraHeaders("X-Pillar2-Id" -> request.clientPillar2Id)
request.body.asJson match {
case Some(request) =>
request.validate[BTNSubmission] match {
Expand Down
Loading