diff --git a/app/preview/TemplateParams.scala b/app/preview/TemplateParams.scala index 95badcaff..68763148d 100644 --- a/app/preview/TemplateParams.scala +++ b/app/preview/TemplateParams.scala @@ -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." + } + ]""")) ) ) } diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/ServiceIdentifier.scala b/app/uk/gov/hmrc/hmrcemailrenderer/templates/ServiceIdentifier.scala index 36d660a6d..9e3b218e4 100644 --- a/app/uk/gov/hmrc/hmrcemailrenderer/templates/ServiceIdentifier.scala +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/ServiceIdentifier.scala @@ -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" } } diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocator.scala b/app/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocator.scala index caed24537..2ea3a6416 100644 --- a/app/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocator.scala +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocator.scala @@ -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 @@ -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 diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2DateTimes.scala b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2DateTimes.scala new file mode 100644 index 000000000..39378a7f6 --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2DateTimes.scala @@ -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")) +} diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2Templates.scala b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2Templates.scala new file mode 100644 index 000000000..452fe9621 --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2Templates.scala @@ -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) + ) + ) +} diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionCriticalErrors.scala.html b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionCriticalErrors.scala.html new file mode 100644 index 000000000..27ecc21fc --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionCriticalErrors.scala.html @@ -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)") { + +

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:

+ + + +

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.

+ + + + + + + + + + + + @for(error <- errorList) { + + + + + + + } + +
Error CodeBusiness Rule NameError LevelDescription
@{(error \ "errorCode").as[String]}@{(error \ "businessRuleName").as[String]}@{(error \ "errorLevel").as[String]}@{(error \ "description").as[String]}
+ +

From the HMRC Pillar 2 team

+ +} diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionCriticalErrors.scala.txt b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionCriticalErrors.scala.txt new file mode 100644 index 000000000..933632303 --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionCriticalErrors.scala.txt @@ -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()} diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionGenericErrors.scala.html b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionGenericErrors.scala.html new file mode 100644 index 000000000..be3a821f2 --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionGenericErrors.scala.html @@ -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)") { + +

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

+ +

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

+ +

Accounting period: @{ukAllNumericDateToUserFacing(params("accountingPeriodStart").toString)} to @{ukAllNumericDateToUserFacing(params("accountingPeriodEnd").toString)}

+ +

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

+ +

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.

+ +

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

+ + + + + + + + + + + + @for(error <- errorList) { + + + + + + + } + +
Error CodeDescriptionDocRefId in ErrorCount
@{(error \ "errorCode").as[String]}@{(error \ "description").as[String]}@{(error \ "docRefIds").asOpt[String].getOrElse("")}@{(error \ "count").as[String]}
+ +

From the HMRC Pillar 2 team

+ +} diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionGenericErrors.scala.txt b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionGenericErrors.scala.txt new file mode 100644 index 000000000..840e44f33 --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionGenericErrors.scala.txt @@ -0,0 +1,39 @@ +@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() + } +} + +Errors identified in GloBE Information Return (GIR) + +GIR Reference ID: @{params("referenceId")} + +Pillar 2 ID: @{params("pillar2Id")} + +Accounting period: @{ukAllNumericDateToUserFacing(params("accountingPeriodStart").toString)} to @{ukAllNumericDateToUserFacing(params("accountingPeriodEnd").toString)} + +Received: @{toTwelveHourUserFacing(params("submissionTime").toString)} on @{ukAllNumericDateToUserFacing(params("submissionDate").toString)} + +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. + +If you have any queries regarding these errors you should contact your software provider. + +ERRORS IDENTIFIED: +@for(error <- errorList) { +Error Code: @{(error \ "errorCode").as[String]} +Description: @{(error \ "description").as[String]} +DocRefId in Error: @{(error \ "docRefIds").asOpt[String].getOrElse("")} +Count: @{(error \ "count").as[String]} +--- +} + +From the HMRC Pillar 2 team + +@{uk.gov.hmrc.hmrcemailrenderer.templates.helpers.txt.template_footer()} diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionSuccessful.scala.html b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionSuccessful.scala.html new file mode 100644 index 000000000..68b6f9b41 --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionSuccessful.scala.html @@ -0,0 +1,34 @@ +@* + * 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 uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.Pillar2DateTimes.* + +@(params: Map[String, Any]) +@uk.gov.hmrc.hmrcemailrenderer.templates.helpers.html.template_main(params, "Your GloBE Information Return (GIR) has been received") { + +

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

+ +

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

+ +

Accounting period: @{ukAllNumericDateToUserFacing(params("accountingPeriodStart").toString)} to @{ukAllNumericDateToUserFacing(params("accountingPeriodEnd").toString)}

+ +

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

+ +

If you have any queries you can contact the Pillar 2 team at pillar2mailbox@@hmrc.gov.uk

+ +

From the HMRC Pillar 2 team

+ +} diff --git a/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionSuccessful.scala.txt b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionSuccessful.scala.txt new file mode 100644 index 000000000..13018123b --- /dev/null +++ b/app/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/girSubmissionSuccessful.scala.txt @@ -0,0 +1,17 @@ +@import uk.gov.hmrc.hmrcemailrenderer.templates.pillar2.Pillar2DateTimes.* + +@(params: Map[String, Any])Your GloBE Information Return (GIR) has been received + +GIR Reference ID: @{params("referenceId")} + +Pillar 2 ID: @{params("pillar2Id")} + +Accounting period: @{ukAllNumericDateToUserFacing(params("accountingPeriodStart").toString)} to @{ukAllNumericDateToUserFacing(params("accountingPeriodEnd").toString)} + +Received: @{toTwelveHourUserFacing(params("submissionTime").toString)} on @{ukAllNumericDateToUserFacing(params("submissionDate").toString)} + +If you have any queries you can contact the Pillar 2 team at pillar2mailbox@@hmrc.gov.uk + +From the HMRC Pillar 2 team + +@{uk.gov.hmrc.hmrcemailrenderer.templates.helpers.txt.template_footer()} diff --git a/test/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocatorSpec.scala b/test/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocatorSpec.scala index c13a8d377..66638b852 100644 --- a/test/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocatorSpec.scala +++ b/test/uk/gov/hmrc/hmrcemailrenderer/templates/TemplateLocatorSpec.scala @@ -147,7 +147,8 @@ class TemplateLocatorSpec extends AnyWordSpecLike with should.Matchers with Opti "CIR", "IOSS NETP", "TRE", - "NGR" + "NGR", + "Pillar 2" ) } @@ -1097,7 +1098,10 @@ class TemplateLocatorSpec extends AnyWordSpecLike with should.Matchers with Opti "tgp_download_record_failure_notification_email", "tgp_download_record_failure_notification_email_cy", "ngr_registration_successful", - "ngr_add_property_request_sent" + "ngr_add_property_request_sent", + "pillar2_gir_submission_successful", + "pillar2_gir_submission_generic_errors", + "pillar2_gir_submission_critical_errors" ) } } diff --git a/test/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2TemplatesSpec.scala b/test/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2TemplatesSpec.scala new file mode 100644 index 000000000..6b70b5505 --- /dev/null +++ b/test/uk/gov/hmrc/hmrcemailrenderer/templates/pillar2/Pillar2TemplatesSpec.scala @@ -0,0 +1,233 @@ +/* + * 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 org.scalatestplus.play.PlaySpec +import uk.gov.hmrc.hmrcemailrenderer.domain.{ MessagePriority, MessageTemplate } +import uk.gov.hmrc.hmrcemailrenderer.templates.CommonParamsForSpec +import uk.gov.hmrc.hmrcemailrenderer.templates.ServiceIdentifier.Pillar2 + +class Pillar2TemplatesSpec extends PlaySpec with CommonParamsForSpec { + + "GIR Successful Submission Template" must { + + val successTemplate: MessageTemplate = MessageTemplate.create( + templateId = "pillar2_gir_submission_successful", + fromAddress = "pillar2@notifications.service.gov.uk", + 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) + ) + + val params = commonParameters ++ Map( + "referenceId" -> "REF123456", + "pillar2Id" -> "XMPLR0123456789", + "submissionDate" -> "01/01/2024", + "submissionTime" -> "14:30", + "accountingPeriodStart" -> "01/04/2023", + "accountingPeriodEnd" -> "31/03/2024" + ) + + "include correct subject" in { + successTemplate.subject( + params + ) mustBe "Successful submission of GloBE Information Return (GIR) – Pillar 2 Top-up Taxes" + } + + "include htmlTemplate body with correct content" in { + val htmlContent = successTemplate.htmlTemplate(params).toString + htmlContent must include("Your GloBE Information Return (GIR) has been received") + htmlContent must include("GIR Reference ID: REF123456") + htmlContent must include("Pillar 2 ID: XMPLR0123456789") + htmlContent must include("Accounting period: 1 April 2023 to 31 March 2024") + htmlContent must include("Received: 2:30pm on 1 January 2024") + htmlContent must include( + "If you have any queries you can contact the Pillar 2 team at pillar2mailbox@hmrc.gov.uk" + ) + htmlContent must include("From the HMRC Pillar 2 team") + } + + "include txtTemplate body with correct content" in { + val txtContent = successTemplate.plainTemplate(params).toString + txtContent must include("Your GloBE Information Return (GIR) has been received") + txtContent must include("GIR Reference ID: REF123456") + txtContent must include("Pillar 2 ID: XMPLR0123456789") + txtContent must include("Accounting period: 1 April 2023 to 31 March 2024") + txtContent must include("Received: 2:30pm on 1 January 2024") + txtContent must include("If you have any queries you can contact the Pillar 2 team at pillar2mailbox@hmrc.gov.uk") + txtContent must include("From the HMRC Pillar 2 team") + } + } + + "GIR Generic Errors Template" must { + + val genericErrorsTemplate: MessageTemplate = MessageTemplate.create( + templateId = "pillar2_gir_submission_generic_errors", + fromAddress = "pillar2@notifications.service.gov.uk", + 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) + ) + + val errors = Seq( + Map( + "errorCode" -> "Error Code 16", + "description" -> "The structure of the DocRefId is not in the correct format", + "docRefIds" -> "GB2025FRPLRX1234, FR2023GBXPLR1234", + "count" -> "2" + ), + Map( + "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" + ) + ) + + val paramsBase = commonParameters ++ Map( + "referenceId" -> "REF123456", + "pillar2Id" -> "XMPLR0123456789", + "submissionDate" -> "01/01/2024", + "submissionTime" -> "14:30", + "accountingPeriodStart" -> "01/04/2023", + "accountingPeriodEnd" -> "31/03/2024" + ) + + val params: Map[String, Any] = paramsBase ++ Map("errors" -> errors) + + "include correct subject" in { + genericErrorsTemplate.subject( + paramsBase + ) mustBe "There is a problem with your GloBE Information Return (GIR) - Pillar 2 Top-up Taxes" + } + + "include htmlTemplate body with error table" in { + val htmlContent = genericErrorsTemplate.htmlTemplate(params).toString + htmlContent must include("Errors identified in GloBE Information Return (GIR)") + htmlContent must include("GIR Reference ID: REF123456") + htmlContent must include("Pillar 2 ID: XMPLR0123456789") + htmlContent must include("Accounting period: 1 April 2023 to 31 March 2024") + htmlContent must include("Received: 2:30pm on 1 January 2024") + htmlContent must include("We have received your GIR submission and identified the following errors.") + htmlContent must include("You must correct these errors and re-submit your return as soon as possible.") + htmlContent must include("Error Code 16") + htmlContent must include("The structure of the DocRefId is not in the correct format") + htmlContent must include("GB2025FRPLRX1234, FR2023GBXPLR1234") + htmlContent must include("Error Code 21") + htmlContent must include("From the HMRC Pillar 2 team") + } + + "include txtTemplate body with errors" in { + val txtContent = genericErrorsTemplate.plainTemplate(params).toString + txtContent must include("Errors identified in GloBE Information Return (GIR)") + txtContent must include("GIR Reference ID: REF123456") + txtContent must include("Pillar 2 ID: XMPLR0123456789") + txtContent must include("Accounting period: 1 April 2023 to 31 March 2024") + txtContent must include("Received: 2:30pm on 1 January 2024") + txtContent must include("We have received your GIR submission and identified the following errors.") + txtContent must include("You must correct these errors and re-submit your return as soon as possible.") + txtContent must include("Error Code 16") + txtContent must include("The structure of the DocRefId is not in the correct format") + txtContent must include("GB2025FRPLRX1234, FR2023GBXPLR1234") + txtContent must include("Error Code 21") + txtContent must include("From the HMRC Pillar 2 team") + } + } + + "GIR Critical Errors Template" must { + + val criticalErrorsTemplate: MessageTemplate = MessageTemplate.create( + templateId = "pillar2_gir_submission_critical_errors", + fromAddress = "pillar2@notifications.service.gov.uk", + 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) + ) + + val errors = Seq( + Map( + "errorCode" -> "Temp Pillar 2 Error Code 1", + "businessRuleName" -> "Failed Threat Scan", + "errorLevel" -> "DocRefId(s)", + "description" -> "Submissions must not include Prohibited Characters or Entity References" + ), + Map( + "errorCode" -> "Temp Pillar 2 Error Code 2", + "businessRuleName" -> "Failed Schema Validation", + "errorLevel" -> "File", + "description" -> "The referenced file failed validation against the GIR XML Schema" + ) + ) + + val paramsBase = commonParameters ++ Map( + "referenceId" -> "REF123456", + "pillar2Id" -> "XMPLR0123456789", + "submissionDate" -> "01/01/2024", + "submissionTime" -> "14:30" + ) + + val params: Map[String, Any] = paramsBase ++ Map("errors" -> errors) + + "include correct subject" in { + criticalErrorsTemplate.subject( + paramsBase + ) mustBe "There is a problem with your GloBE Information Return (GIR) - Pillar 2 Top-up Taxes" + } + + "include htmlTemplate body with critical error details" in { + val htmlContent = criticalErrorsTemplate.htmlTemplate(params).toString + htmlContent must include("Critical Schema or Business Rule failure - GloBE Information Return (GIR)") + htmlContent must include("GIR Reference ID: REF123456") + htmlContent must include("Pillar 2 ID: XMPLR0123456789") + htmlContent must include("Received: 2:30pm on 1 January 2024") + htmlContent must include("Your GIR has not been processed because it failed one of the following business rules:") + htmlContent must include("50005: Failed threat scan") + htmlContent must include("50007: Failed Schema Validation") + htmlContent must include("50010: Test data") + htmlContent must include("Temporary Error Code 3: Empty Elements") + htmlContent must include("Temp Pillar 2 Error Code 1") + htmlContent must include("Failed Threat Scan") + htmlContent must include("Temp Pillar 2 Error Code 2") + htmlContent must include("Failed Schema Validation") + htmlContent must include("From the HMRC Pillar 2 team") + } + + "include txtTemplate body with critical errors" in { + val txtContent = criticalErrorsTemplate.plainTemplate(params).toString + txtContent must include("Critical Schema or Business Rule failure - GloBE Information Return (GIR)") + txtContent must include("GIR Reference ID: REF123456") + txtContent must include("Pillar 2 ID: XMPLR0123456789") + txtContent must include("Received: 2:30pm on 1 January 2024") + txtContent must include("Your GIR has not been processed because it failed one of the following business rules:") + txtContent must include("50005: Failed threat scan") + txtContent must include("50007: Failed Schema Validation") + txtContent must include("50010: Test data") + txtContent must include("Temporary Error Code 3: Empty Elements") + txtContent must include("Temp Pillar 2 Error Code 1") + txtContent must include("Failed Threat Scan") + txtContent must include("Temp Pillar 2 Error Code 2") + txtContent must include("Failed Schema Validation") + txtContent must include("From the HMRC Pillar 2 team") + } + } +}