Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 62 additions & 0 deletions app/preview/TemplateParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4009,6 +4009,68 @@ object TemplateParams3 {
"lastName" -> "Ferguson",
"reference" -> "123ABC",
"postcodeFirstPart" -> "BS15"
),
"pillar2_gir_submission_successful" -> Map(
"referenceId" -> "REF123456789",
"pillar2Id" -> "XMPLR0123456789",
"submissionDate" -> "15/10/2025",
"submissionTime" -> "14:35",
"accountingPeriodStart" -> "01/04/2024",
"accountingPeriodEnd" -> "31/03/2025"
),
"pillar2_gir_submission_generic_errors" -> Map(
"referenceId" -> "REF987654321",
"pillar2Id" -> "XMPLR9876543210",
"submissionDate" -> "15/10/2025",
"submissionTime" -> "15:20",
"accountingPeriodStart" -> "01/04/2024",
"accountingPeriodEnd" -> "31/03/2025",
"errors" -> stringify(parse("""[
{
"errorCode": "Error Code 16",
"description": "The structure of the DocRefId is not in the correct format, as set out in the HMRC Pillar 2 Business Rules.",
"docRefIds": "GB2025FRPLRX1234, FR2023GBXPLR1234",
"count": "2"
},
{
"errorCode": "Error Code 21",
"description": "Where the DocTypeIndic is OECD2 or OECD3, the DocSpec element must contain a CorrDocRefId element.",
"docRefIds": "GB2025GB-PLRX123",
"count": "1"
},
{
"errorCode": "Error Code 35",
"description": "The MessageRefId must be unique and must not have been used in a previous message.",
"docRefIds": "GB2025PLRX456789",
"count": "1"
}
]"""))
),
"pillar2_gir_submission_critical_errors" -> Map(
"referenceId" -> "REF555666777",
"pillar2Id" -> "XMPLR5556667777",
"submissionDate" -> "15/10/2025",
"submissionTime" -> "16:45",
"errors" -> stringify(parse("""[
{
"errorCode": "Temp Pillar 2 Error Code 1",
"businessRuleName": "Failed Threat Scan",
"errorLevel": "DocRefId(s)",
"description": "Submissions must not include Prohibited Characters or Entity References in the MessageRefId or DocRefId. Submissions must not include Prohibited Characters, these have to be escaped using Entity References in all element values in the DPIBody."
},
{
"errorCode": "Temp Pillar 2 Error Code 2",
"businessRuleName": "Failed Schema Validation",
"errorLevel": "File",
"description": "The referenced file failed validation against the GIR XML Schema."
},
{
"errorCode": "Temp Pillar 2 Error Code 4",
"businessRuleName": "Test Data",
"errorLevel": "DocRefId(s)",
"description": "The referenced file contains one or more records with a DocTypeIndic value in the range OECD10-OECD13, indicating test data. As a result, the receiving Competent Authority cannot accept this file as a valid GIR file submission."
}
]"""))
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,5 @@ object ServiceIdentifier {

case object Feedback extends ServiceIdentifier { override val name = "feedback" }
case object NgrNotify extends ServiceIdentifier { override val name = "ngr-notify" }
case object Pillar2 extends ServiceIdentifier { override val name = "pillar2" }
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import uk.gov.hmrc.hmrcemailrenderer.templates.ioss.IossTemplates
import uk.gov.hmrc.hmrcemailrenderer.templates.iossNetp.IossNetpTemplates
import uk.gov.hmrc.hmrcemailrenderer.templates.ngr.NgrTemplates
import uk.gov.hmrc.hmrcemailrenderer.templates.penaltyreform.PenReformTemplates
import uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.Pillar2Templates
import uk.gov.hmrc.hmrcemailrenderer.templates.tctr.TctrTemplates
import uk.gov.hmrc.hmrcemailrenderer.templates.tctr.TctrTemplates.tctrGroup
import uk.gov.hmrc.hmrcemailrenderer.templates.tgp.TgpTemplates
Expand Down Expand Up @@ -184,7 +185,8 @@ trait TemplateLocator {
"IOSS NETP" -> IossNetpTemplates.templates,
"TRE" -> treTemplates.templates,
FeedbackTemplates.id -> FeedbackTemplates.templates,
"NGR" -> NgrTemplates.templates
"NGR" -> NgrTemplates.templates,
"Pillar 2" -> Pillar2Templates.templates
)

lazy val all: Seq[MessageTemplate] = templateGroups.values.flatten.toSeq
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2025 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.hmrcemailrenderer.templates.pillar2

import java.time.{ LocalDate, LocalTime }
import java.time.format.DateTimeFormatter

object Pillar2DateTimes {

def ukAllNumericDateToUserFacing(raw: String): String =
LocalDate
.parse(
raw,
DateTimeFormatter.ofPattern("dd/MM/yyyy")
)
.format(DateTimeFormatter.ofPattern("d MMMM YYYY"))

def toTwelveHourUserFacing(raw: String): String =
LocalTime.parse(raw).format(DateTimeFormatter.ofPattern("h:mma"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2023 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.hmrcemailrenderer.templates.pillar2

import uk.gov.hmrc.hmrcemailrenderer.domain.{ MessagePriority, MessageTemplate }
import uk.gov.hmrc.hmrcemailrenderer.templates.FromAddress
import uk.gov.hmrc.hmrcemailrenderer.templates.ServiceIdentifier.Pillar2
import uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.html
import uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.txt

object Pillar2Templates {
val templates = Seq(
MessageTemplate.create(
templateId = "pillar2_gir_submission_successful",
fromAddress = FromAddress.noReply("pillar2"),
service = Pillar2,
subject = "Successful submission of GloBE Information Return (GIR) – Pillar 2 Top-up Taxes",
plainTemplate = txt.girSubmissionSuccessful.f,
htmlTemplate = html.girSubmissionSuccessful.f,
priority = Some(MessagePriority.Urgent)
),
MessageTemplate.create(
templateId = "pillar2_gir_submission_generic_errors",
fromAddress = FromAddress.noReply("pillar2"),
service = Pillar2,
subject = "There is a problem with your GloBE Information Return (GIR) - Pillar 2 Top-up Taxes",
plainTemplate = txt.girSubmissionGenericErrors.f,
htmlTemplate = html.girSubmissionGenericErrors.f,
priority = Some(MessagePriority.Urgent)
),
MessageTemplate.create(
templateId = "pillar2_gir_submission_critical_errors",
fromAddress = FromAddress.noReply("pillar2"),
service = Pillar2,
subject = "There is a problem with your GloBE Information Return (GIR) - Pillar 2 Top-up Taxes",
plainTemplate = txt.girSubmissionCriticalErrors.f,
htmlTemplate = html.girSubmissionCriticalErrors.f,
priority = Some(MessagePriority.Urgent)
)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@*
* Copyright 2023 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.
*@

@import play.api.libs.json.{ Json, JsObject }
@import uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.Pillar2DateTimes.*

@(params: Map[String, Any])

@errorList = @{
params("errors") match {
case errors: String => Json.parse(errors).as[List[JsObject]]
case errors: Seq[_] => errors.asInstanceOf[Seq[Map[String, String]]].map(m => Json.toJson(m).as[JsObject])
case _ => List()
}
}

@uk.gov.hmrc.hmrcemailrenderer.templates.helpers.html.template_main(params, "Critical Schema or Business Rule failure - GloBE Information Return (GIR)") {

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">GIR Reference ID: @{params("referenceId")}</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">Pillar 2 ID: @{params("pillar2Id")}</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">Received: @{toTwelveHourUserFacing(params("submissionTime").toString)} on @{ukAllNumericDateToUserFacing(params("submissionDate").toString)}</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">Your GIR has not been processed because it failed one of the following business rules:</p>

<ul style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0; padding-left: 20px;">
<li style="margin-bottom: 10px;">50005: Failed threat scan – the file contains prohibited characters or invalid entity references</li>
<li style="margin-bottom: 10px;">50007: Failed Schema Validation – the file failed validation against the OECD GIR XML Schema</li>
<li style="margin-bottom: 10px;">50010: Test data – the file has 'DocTypeIndic' values in the range OECD10-OECD13</li>
<li style="margin-bottom: 10px;">Temporary Error Code 3: Empty Elements – the file format is incorrect at either file or record level.</li>
</ul>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">You must correct these errors and re-submit your return as soon as possible.</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">If you have any queries regarding these errors you should contact your software provider.</p>

<table width="100%" cellspacing="0" cellpadding="10px" style="text-align:left; font-size: 19px; border-collapse: collapse; margin: 30px 0;">
<thead>
<tr style="background-color: #005ea5; color: #ffffff;">
<th style="border: 1px solid #bfc1c3; padding: 10px;">Error Code</th>
<th style="border: 1px solid #bfc1c3; padding: 10px;">Business Rule Name</th>
<th style="border: 1px solid #bfc1c3; padding: 10px;">Error Level</th>
<th style="border: 1px solid #bfc1c3; padding: 10px;">Description</th>
</tr>
</thead>
<tbody>
@for(error <- errorList) {
<tr>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "errorCode").as[String]}</td>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "businessRuleName").as[String]}</td>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "errorLevel").as[String]}</td>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "description").as[String]}</td>
</tr>
}
</tbody>
</table>

<p style="font-size: 20px; line-height: 1.315789474; margin: 60px 0 30px 0;">From the HMRC Pillar 2 team</p>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@import play.api.libs.json.{ Json, JsObject }
@import uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.Pillar2DateTimes.*

@(params: Map[String, Any])

@errorList = @{
params("errors") match {
case errors: String => Json.parse(errors).as[List[JsObject]]
case errors: Seq[_] => errors.asInstanceOf[Seq[Map[String, String]]].map(m => Json.toJson(m).as[JsObject])
case _ => List()
}
}

Critical Schema or Business Rule failure - GloBE Information Return (GIR)

GIR Reference ID: @{params("referenceId")}

Pillar 2 ID: @{params("pillar2Id")}

Received: @{toTwelveHourUserFacing(params("submissionTime").toString)} on @{ukAllNumericDateToUserFacing(params("submissionDate").toString)}

Your GIR has not been processed because it failed one of the following business rules:

- 50005: Failed threat scan – the file contains prohibited characters or invalid entity references
- 50007: Failed Schema Validation – the file failed validation against the OECD GIR XML Schema
- 50010: Test data – the file has 'DocTypeIndic' values in the range OECD10-OECD13
- Temporary Error Code 3: Empty Elements – the file format is incorrect at either file or record level.

You must correct these errors and re-submit your return as soon as possible.

If you have any queries regarding these errors you should contact your software provider.

CRITICAL ERRORS IDENTIFIED:
@for(error <- errorList) {
Error Code: @{(error \ "errorCode").as[String]}
Business Rule Name: @{(error \ "businessRuleName").as[String]}
Error Level: @{(error \ "errorLevel").as[String]}
Description: @{(error \ "description").as[String]}
---
}

From the HMRC Pillar 2 team

@{uk.gov.hmrc.hmrcemailrenderer.templates.helpers.txt.template_footer()}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@*
* Copyright 2023 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.
*@

@import play.api.libs.json.{ Json, JsObject }
@import uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.Pillar2DateTimes.*

@(params: Map[String, Any])

@errorList = @{
params("errors") match {
case errors: String => Json.parse(errors).as[List[JsObject]]
case errors: Seq[_] => errors.asInstanceOf[Seq[Map[String, String]]].map(m => Json.toJson(m).as[JsObject])
case _ => List()
}
}

@uk.gov.hmrc.hmrcemailrenderer.templates.helpers.html.template_main(params, "Errors identified in GloBE Information Return (GIR)") {

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">GIR Reference ID: @{params("referenceId")}</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">Pillar 2 ID: @{params("pillar2Id")}</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">Accounting period: @{ukAllNumericDateToUserFacing(params("accountingPeriodStart").toString)} to @{ukAllNumericDateToUserFacing(params("accountingPeriodEnd").toString)}</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">Received: @{toTwelveHourUserFacing(params("submissionTime").toString)} on @{ukAllNumericDateToUserFacing(params("submissionDate").toString)}</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">We have received your GIR submission and identified the following errors. You must correct these errors and re-submit your return as soon as possible.</p>

<p style="font-size: 20px; line-height: 1.315789474; margin: 0 0 30px 0;">If you have any queries regarding these errors you should contact your software provider.</p>

<table width="100%" cellspacing="0" cellpadding="10px" style="text-align:left; font-size: 19px; border-collapse: collapse; margin: 30px 0;">
<thead>
<tr style="background-color: #005ea5; color: #ffffff;">
<th style="border: 1px solid #bfc1c3; padding: 10px;">Error Code</th>
<th style="border: 1px solid #bfc1c3; padding: 10px;">Description</th>
<th style="border: 1px solid #bfc1c3; padding: 10px;">DocRefId in Error</th>
<th style="border: 1px solid #bfc1c3; padding: 10px;">Count</th>
</tr>
</thead>
<tbody>
@for(error <- errorList) {
<tr>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "errorCode").as[String]}</td>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "description").as[String]}</td>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "docRefIds").asOpt[String].getOrElse("")}</td>
<td style="border: 1px solid #bfc1c3; padding: 10px;">@{(error \ "count").as[String]}</td>
</tr>
}
</tbody>
</table>

<p style="font-size: 20px; line-height: 1.315789474; margin: 60px 0 30px 0;">From the HMRC Pillar 2 team</p>

}
Loading