diff --git a/apps/judicial-system/backend/infra/judicial-system-backend.ts b/apps/judicial-system/backend/infra/judicial-system-backend.ts
index aa29ca39050c..bab01682da23 100644
--- a/apps/judicial-system/backend/infra/judicial-system-backend.ts
+++ b/apps/judicial-system/backend/infra/judicial-system-backend.ts
@@ -70,6 +70,8 @@ export const serviceSetup = (): ServiceBuilder<'judicial-system-backend'> =>
EMAIL_REPLY_TO_NAME: '/k8s/judicial-system/EMAIL_REPLY_TO_NAME',
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL',
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL',
+ PRISON_ADMIN_INDICTMENT_EMAILS:
+ '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS',
AUTH_JWT_SECRET: '/k8s/judicial-system/AUTH_JWT_SECRET',
ADMIN_USERS: '/k8s/judicial-system/ADMIN_USERS',
BACKEND_ACCESS_TOKEN: '/k8s/judicial-system/BACKEND_ACCESS_TOKEN',
diff --git a/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts b/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts
index e163917b953f..59ca01645a40 100644
--- a/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts
@@ -74,6 +74,26 @@ export class DefendantService {
return message
}
+ private getMessagesForIndictmentToPrisonAdminChanges(
+ defendant: Defendant,
+ ): Message {
+ const messageType =
+ defendant.isSentToPrisonAdmin === true
+ ? DefendantNotificationType.INDICTMENT_SENT_TO_PRISON_ADMIN
+ : DefendantNotificationType.INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN
+
+ const message = {
+ type: MessageType.DEFENDANT_NOTIFICATION,
+ caseId: defendant.caseId,
+ elementId: defendant.id,
+ body: {
+ type: messageType,
+ },
+ }
+
+ return message
+ }
+
private getUpdatedDefendant(
numberOfAffectedRows: number,
defendants: Defendant[],
@@ -143,19 +163,19 @@ export class DefendantService {
return
}
+ const messages: Message[] = []
+
if (
updatedDefendant.isDefenderChoiceConfirmed &&
!oldDefendant.isDefenderChoiceConfirmed
) {
// Defender choice was just confirmed by the court
- const messages: Message[] = [
- {
- type: MessageType.DELIVERY_TO_COURT_INDICTMENT_DEFENDER,
- user,
- caseId: theCase.id,
- elementId: updatedDefendant.id,
- },
- ]
+ messages.push({
+ type: MessageType.DELIVERY_TO_COURT_INDICTMENT_DEFENDER,
+ user,
+ caseId: theCase.id,
+ elementId: updatedDefendant.id,
+ })
if (
updatedDefendant.defenderChoice === DefenderChoice.CHOOSE ||
@@ -171,9 +191,20 @@ export class DefendantService {
})
}
}
+ } else if (
+ updatedDefendant.isSentToPrisonAdmin !== undefined &&
+ updatedDefendant.isSentToPrisonAdmin !== oldDefendant.isSentToPrisonAdmin
+ ) {
+ messages.push(
+ this.getMessagesForIndictmentToPrisonAdminChanges(updatedDefendant),
+ )
+ }
- return this.messageService.sendMessagesToQueue(messages)
+ if (messages.length === 0) {
+ return
}
+
+ return this.messageService.sendMessagesToQueue(messages)
}
async createForNewCase(
diff --git a/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts b/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts
index 9b5d893e2bc1..34c235472f60 100644
--- a/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/defendant/test/defendantController/update.spec.ts
@@ -209,6 +209,58 @@ describe('DefendantController - Update', () => {
},
)
+ describe('defendant in indictment is sent to prison admin', () => {
+ const defendantUpdate = { isSentToPrisonAdmin: true }
+ const updatedDefendant = { ...defendant, ...defendantUpdate }
+
+ beforeEach(async () => {
+ const mockUpdate = mockDefendantModel.update as jest.Mock
+ mockUpdate.mockResolvedValueOnce([1, [updatedDefendant]])
+
+ await givenWhenThen(defendantUpdate, CaseType.INDICTMENT, caseId)
+ })
+
+ it('should queue messages', () => {
+ expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledWith([
+ {
+ type: MessageType.DEFENDANT_NOTIFICATION,
+ caseId,
+ elementId: defendantId,
+ body: {
+ type: DefendantNotificationType.INDICTMENT_SENT_TO_PRISON_ADMIN,
+ },
+ },
+ ])
+ expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledTimes(1)
+ })
+ })
+
+ describe('defendant in indictment is withdrawn from prison admin', () => {
+ const defendantUpdate = { isSentToPrisonAdmin: false }
+ const updatedDefendant = { ...defendant, ...defendantUpdate }
+
+ beforeEach(async () => {
+ const mockUpdate = mockDefendantModel.update as jest.Mock
+ mockUpdate.mockResolvedValueOnce([1, [updatedDefendant]])
+
+ await givenWhenThen(defendantUpdate, CaseType.INDICTMENT, caseId)
+ })
+
+ it('should queue messages for indictment withdrawn from prison admin', () => {
+ expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledWith([
+ {
+ type: MessageType.DEFENDANT_NOTIFICATION,
+ caseId,
+ elementId: defendantId,
+ body: {
+ type: DefendantNotificationType.INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN,
+ },
+ },
+ ])
+ expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledTimes(1)
+ })
+ })
+
describe('defendant update fails', () => {
let then: Then
diff --git a/apps/judicial-system/backend/src/app/modules/notification/internalNotification.controller.ts b/apps/judicial-system/backend/src/app/modules/notification/internalNotification.controller.ts
index c0e2ca1a0003..5e03c0f784b3 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/internalNotification.controller.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/internalNotification.controller.ts
@@ -34,12 +34,12 @@ import { InstitutionNotificationDto } from './dto/institutionNotification.dto'
import { NotificationDispatchDto } from './dto/notificationDispatch.dto'
import { SubpoenaNotificationDto } from './dto/subpoenaNotification.dto'
import { DeliverResponse } from './models/deliver.response'
-import { CaseNotificationService } from './caseNotification.service'
-import { CivilClaimantNotificationService } from './civilClaimantNotification.service'
-import { DefendantNotificationService } from './defendantNotification.service'
-import { InstitutionNotificationService } from './institutionNotification.service'
+import { CaseNotificationService } from './services/caseNotification/caseNotification.service'
+import { CivilClaimantNotificationService } from './services/civilClaimantNotification/civilClaimantNotification.service'
+import { DefendantNotificationService } from './services/defendantNotification/defendantNotification.service'
+import { InstitutionNotificationService } from './services/institutionNotification/institutionNotification.service'
+import { SubpoenaNotificationService } from './services/subpoenaNotification/subpoenaNotification.service'
import { NotificationDispatchService } from './notificationDispatch.service'
-import { SubpoenaNotificationService } from './subpoenaNotification.service'
@UseGuards(TokenGuard)
@Controller('api/internal')
diff --git a/apps/judicial-system/backend/src/app/modules/notification/notification.config.ts b/apps/judicial-system/backend/src/app/modules/notification/notification.config.ts
index ba742a4742a6..aecd5dabb6c9 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/notification.config.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/notification.config.ts
@@ -14,6 +14,10 @@ export const notificationModuleConfig = defineConfig({
replyToName: env.required('EMAIL_REPLY_TO_NAME', 'Réttarvörslugátt'),
prisonEmail: env.required('PRISON_EMAIL', ''),
prisonAdminEmail: env.required('PRISON_ADMIN_EMAIL', ''),
+ prisonAdminIndictmentEmails: env.required(
+ 'PRISON_ADMIN_INDICTMENT_EMAILS',
+ '',
+ ),
courtsEmails: env.requiredJSON('COURTS_EMAILS', {}) as {
[key: string]: string
},
diff --git a/apps/judicial-system/backend/src/app/modules/notification/notification.module.ts b/apps/judicial-system/backend/src/app/modules/notification/notification.module.ts
index 14fb32c0a565..101978e3d3ba 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/notification.module.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/notification.module.ts
@@ -17,15 +17,15 @@ import {
UserModule,
} from '../index'
import { Notification } from './models/notification.model'
-import { CaseNotificationService } from './caseNotification.service'
-import { CivilClaimantNotificationService } from './civilClaimantNotification.service'
-import { DefendantNotificationService } from './defendantNotification.service'
-import { InstitutionNotificationService } from './institutionNotification.service'
+import { CaseNotificationService } from './services/caseNotification/caseNotification.service'
+import { CivilClaimantNotificationService } from './services/civilClaimantNotification/civilClaimantNotification.service'
+import { DefendantNotificationService } from './services/defendantNotification/defendantNotification.service'
+import { InstitutionNotificationService } from './services/institutionNotification/institutionNotification.service'
+import { SubpoenaNotificationService } from './services/subpoenaNotification/subpoenaNotification.service'
import { InternalNotificationController } from './internalNotification.controller'
import { NotificationController } from './notification.controller'
import { NotificationService } from './notification.service'
import { NotificationDispatchService } from './notificationDispatch.service'
-import { SubpoenaNotificationService } from './subpoenaNotification.service'
@Module({
imports: [
diff --git a/apps/judicial-system/backend/src/app/modules/notification/caseNotification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts
similarity index 99%
rename from apps/judicial-system/backend/src/app/modules/notification/caseNotification.service.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts
index 910270ff53e7..0c4cbba076cb 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/caseNotification.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts
@@ -68,20 +68,20 @@ import {
formatProsecutorCourtDateEmailNotification,
formatProsecutorReadyForCourtEmailNotification,
formatProsecutorReceivedByCourtSmsNotification,
-} from '../../formatters'
-import { notifications } from '../../messages'
-import { type Case, DateLog } from '../case'
-import { CourtService } from '../court'
+} from '../../../../formatters'
+import { notifications } from '../../../../messages'
+import { type Case, DateLog } from '../../../case'
+import { CourtService } from '../../../court'
import {
type CivilClaimant,
type Defendant,
DefendantService,
-} from '../defendant'
-import { EventService } from '../event'
-import { DeliverResponse } from './models/deliver.response'
-import { Notification, Recipient } from './models/notification.model'
-import { BaseNotificationService } from './baseNotification.service'
-import { notificationModuleConfig } from './notification.config'
+} from '../../../defendant'
+import { EventService } from '../../../event'
+import { BaseNotificationService } from '../../baseNotification.service'
+import { DeliverResponse } from '../../models/deliver.response'
+import { Notification, Recipient } from '../../models/notification.model'
+import { notificationModuleConfig } from '../../notification.config'
interface Attachment {
filename: string
diff --git a/apps/judicial-system/backend/src/app/modules/notification/civilClaimantNotification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/services/civilClaimantNotification/civilClaimantNotification.service.ts
similarity index 91%
rename from apps/judicial-system/backend/src/app/modules/notification/civilClaimantNotification.service.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/civilClaimantNotification/civilClaimantNotification.service.ts
index c80250801348..ab8744a8dbd6 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/civilClaimantNotification.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/services/civilClaimantNotification/civilClaimantNotification.service.ts
@@ -16,14 +16,14 @@ import { DEFENDER_INDICTMENT_ROUTE } from '@island.is/judicial-system/consts'
import { capitalize } from '@island.is/judicial-system/formatters'
import { CivilClaimantNotificationType } from '@island.is/judicial-system/types'
-import { Case } from '../case'
-import { CivilClaimant } from '../defendant'
-import { EventService } from '../event'
-import { DeliverResponse } from './models/deliver.response'
-import { Notification, Recipient } from './models/notification.model'
-import { BaseNotificationService } from './baseNotification.service'
+import { Case } from '../../../case'
+import { CivilClaimant } from '../../../defendant'
+import { EventService } from '../../../event'
+import { BaseNotificationService } from '../../baseNotification.service'
+import { DeliverResponse } from '../../models/deliver.response'
+import { Notification, Recipient } from '../../models/notification.model'
+import { notificationModuleConfig } from '../../notification.config'
import { strings } from './civilClaimantNotification.strings'
-import { notificationModuleConfig } from './notification.config'
@Injectable()
export class CivilClaimantNotificationService extends BaseNotificationService {
diff --git a/apps/judicial-system/backend/src/app/modules/notification/civilClaimantNotification.strings.ts b/apps/judicial-system/backend/src/app/modules/notification/services/civilClaimantNotification/civilClaimantNotification.strings.ts
similarity index 100%
rename from apps/judicial-system/backend/src/app/modules/notification/civilClaimantNotification.strings.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/civilClaimantNotification/civilClaimantNotification.strings.ts
diff --git a/apps/judicial-system/backend/src/app/modules/notification/defendantNotification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/services/defendantNotification/defendantNotification.service.ts
similarity index 67%
rename from apps/judicial-system/backend/src/app/modules/notification/defendantNotification.service.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/defendantNotification/defendantNotification.service.ts
index d3f6a0f86f2b..041073d9d4b2 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/defendantNotification.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/services/defendantNotification/defendantNotification.service.ts
@@ -19,14 +19,14 @@ import {
isIndictmentCase,
} from '@island.is/judicial-system/types'
-import { Case } from '../case'
-import { Defendant } from '../defendant'
-import { EventService } from '../event'
-import { DeliverResponse } from './models/deliver.response'
-import { Notification, Recipient } from './models/notification.model'
-import { BaseNotificationService } from './baseNotification.service'
+import { Case } from '../../../case'
+import { Defendant } from '../../../defendant'
+import { EventService } from '../../../event'
+import { BaseNotificationService } from '../../baseNotification.service'
+import { DeliverResponse } from '../../models/deliver.response'
+import { Notification, Recipient } from '../../models/notification.model'
+import { notificationModuleConfig } from '../../notification.config'
import { strings } from './defendantNotification.strings'
-import { notificationModuleConfig } from './notification.config'
@Injectable()
export class DefendantNotificationService extends BaseNotificationService {
@@ -179,6 +179,80 @@ export class DefendantNotificationService extends BaseNotificationService {
return { delivered: true }
}
+ private sendIndictmentSentToPrisonAdminNotification(theCase: Case) {
+ const formattedSubject = this.formatMessage(
+ strings.indictmentSentToPrisonAdminSubject,
+ {
+ courtCaseNumber: theCase.courtCaseNumber,
+ },
+ )
+
+ const formattedBody = this.formatMessage(
+ strings.indictmentSentToPrisonAdminBody,
+ {
+ courtCaseNumber: theCase.courtCaseNumber,
+ linkStart: ``,
+ linkEnd: '',
+ },
+ )
+
+ // We want to send separate emails to each recipient
+ const to = this.config.email.prisonAdminIndictmentEmails
+ .split(',')
+ .map((email) => email.trim())
+ .map((email) => {
+ return {
+ name: 'Fangelsismálastofnun',
+ email,
+ }
+ })
+
+ return this.sendEmails(
+ theCase,
+ DefendantNotificationType.INDICTMENT_SENT_TO_PRISON_ADMIN,
+ formattedSubject,
+ formattedBody,
+ to,
+ )
+ }
+
+ private sendIndictmentWithdrawnFromPrisonAdminNotification(theCase: Case) {
+ const courtCaseNumber = theCase.courtCaseNumber
+
+ const formattedSubject = this.formatMessage(
+ strings.indictmentWithdrawnFromPrisonAdminSubject,
+ {
+ courtCaseNumber,
+ },
+ )
+
+ const formattedBody = this.formatMessage(
+ strings.indictmentWithdrawnFromPrisonAdminBody,
+ {
+ courtCaseNumber,
+ },
+ )
+
+ // We want to send separate emails to each recipient
+ const to = this.config.email.prisonAdminIndictmentEmails
+ .split(',')
+ .map((email) => email.trim())
+ .map((email) => {
+ return {
+ name: 'Fangelsismálastofnun',
+ email,
+ }
+ })
+
+ return this.sendEmails(
+ theCase,
+ DefendantNotificationType.INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN,
+ formattedSubject,
+ formattedBody,
+ to,
+ )
+ }
+
private sendNotification(
notificationType: DefendantNotificationType,
theCase: Case,
@@ -189,6 +263,10 @@ export class DefendantNotificationService extends BaseNotificationService {
return this.sendDefendantSelectedDefenderNotification(theCase)
case DefendantNotificationType.DEFENDER_ASSIGNED:
return this.sendDefenderAssignedNotification(theCase, defendant)
+ case DefendantNotificationType.INDICTMENT_SENT_TO_PRISON_ADMIN:
+ return this.sendIndictmentSentToPrisonAdminNotification(theCase)
+ case DefendantNotificationType.INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN:
+ return this.sendIndictmentWithdrawnFromPrisonAdminNotification(theCase)
default:
throw new InternalServerErrorException(
`Invalid notification type: ${notificationType}`,
diff --git a/apps/judicial-system/backend/src/app/modules/notification/defendantNotification.strings.ts b/apps/judicial-system/backend/src/app/modules/notification/services/defendantNotification/defendantNotification.strings.ts
similarity index 54%
rename from apps/judicial-system/backend/src/app/modules/notification/defendantNotification.strings.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/defendantNotification/defendantNotification.strings.ts
index 0bd021c0dc53..02eebc37019c 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/defendantNotification.strings.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/services/defendantNotification/defendantNotification.strings.ts
@@ -27,4 +27,29 @@ export const strings = {
description:
'Body of the notification when a defender is assigned a confirmed as a defender in indictment cases',
}),
+ indictmentSentToPrisonAdminSubject: defineMessage({
+ id: 'judicial.system.backend:defendant_notifications.indictment_sent_to_prison_admin_subject',
+ defaultMessage: 'Mál {courtCaseNumber} til fullnustu',
+ description:
+ 'Titill í tilkynningu til FMST þegar mál er sent til fullnustu',
+ }),
+ indictmentSentToPrisonAdminBody: defineMessage({
+ id: 'judicial.system.backend:defendant_notifications.indictment_sent_to_prison_admin_body',
+ defaultMessage:
+ 'Ríkissaksóknari hefur sent mál {courtCaseNumber} til fullnustu.
Skjöl málsins eru aðgengileg á {linkStart}yfirlitssíðu málsins í Réttarvörslugátt{linkEnd}.',
+ description: 'Texti í tilkynningu til FMST þegar mál er sent til fullnustu',
+ }),
+ indictmentWithdrawnFromPrisonAdminSubject: defineMessage({
+ id: 'judicial.system.backend:defendant_notifications.indictment_withdrawn_from_prison_admin_subject',
+ defaultMessage: 'Mál {courtCaseNumber} afturkallað úr fullnustu',
+ description:
+ 'Titill í tilkynningu til FMST þegar mál er afturkallað úr fullnustu',
+ }),
+ indictmentWithdrawnFromPrisonAdminBody: defineMessage({
+ id: 'judicial.system.backend:defendant_notifications.indictment_withdrawn_from_prison_admin_body',
+ defaultMessage:
+ 'Ríkissaksóknari hefur afturkallað mál {courtCaseNumber} úr fullnustu.',
+ description:
+ 'Texti í tilkynningu til FMST þegar mál er afturkallað úr fullnustu',
+ }),
}
diff --git a/apps/judicial-system/backend/src/app/modules/notification/institutionNotification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/services/institutionNotification/institutionNotification.service.ts
similarity index 87%
rename from apps/judicial-system/backend/src/app/modules/notification/institutionNotification.service.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/institutionNotification/institutionNotification.service.ts
index 82727cab9a70..8d3c9ae9af2a 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/institutionNotification.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/services/institutionNotification/institutionNotification.service.ts
@@ -12,14 +12,14 @@ import { type ConfigType } from '@island.is/nest/config'
import { InstitutionNotificationType } from '@island.is/judicial-system/types'
-import { InternalCaseService } from '../case'
-import { EventService } from '../event'
-import { type User, UserService } from '../user'
-import { DeliverResponse } from './models/deliver.response'
-import { Notification } from './models/notification.model'
-import { BaseNotificationService } from './baseNotification.service'
+import { InternalCaseService } from '../../../case'
+import { EventService } from '../../../event'
+import { type User, UserService } from '../../../user'
+import { BaseNotificationService } from '../../baseNotification.service'
+import { DeliverResponse } from '../../models/deliver.response'
+import { Notification } from '../../models/notification.model'
+import { notificationModuleConfig } from '../../notification.config'
import { strings } from './institutionNotification.strings'
-import { notificationModuleConfig } from './notification.config'
@Injectable()
export class InstitutionNotificationService extends BaseNotificationService {
diff --git a/apps/judicial-system/backend/src/app/modules/notification/institutionNotification.strings.ts b/apps/judicial-system/backend/src/app/modules/notification/services/institutionNotification/institutionNotification.strings.ts
similarity index 100%
rename from apps/judicial-system/backend/src/app/modules/notification/institutionNotification.strings.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/institutionNotification/institutionNotification.strings.ts
diff --git a/apps/judicial-system/backend/src/app/modules/notification/subpoenaNotification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/services/subpoenaNotification/subpoenaNotification.service.ts
similarity index 92%
rename from apps/judicial-system/backend/src/app/modules/notification/subpoenaNotification.service.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/subpoenaNotification/subpoenaNotification.service.ts
index 41a4630f0c92..575d73abd748 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/subpoenaNotification.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/services/subpoenaNotification/subpoenaNotification.service.ts
@@ -15,12 +15,12 @@ import { type ConfigType } from '@island.is/nest/config'
import { ROUTE_HANDLER_ROUTE } from '@island.is/judicial-system/consts'
import { SubpoenaNotificationType } from '@island.is/judicial-system/types'
-import { Case } from '../case'
-import { EventService } from '../event'
-import { DeliverResponse } from './models/deliver.response'
-import { Notification, Recipient } from './models/notification.model'
-import { BaseNotificationService } from './baseNotification.service'
-import { notificationModuleConfig } from './notification.config'
+import { Case } from '../../../case'
+import { EventService } from '../../../event'
+import { BaseNotificationService } from '../../baseNotification.service'
+import { DeliverResponse } from '../../models/deliver.response'
+import { Notification, Recipient } from '../../models/notification.model'
+import { notificationModuleConfig } from '../../notification.config'
import { strings } from './subpoenaNotification.strings'
@Injectable()
diff --git a/apps/judicial-system/backend/src/app/modules/notification/subpoenaNotification.strings.ts b/apps/judicial-system/backend/src/app/modules/notification/services/subpoenaNotification/subpoenaNotification.strings.ts
similarity index 100%
rename from apps/judicial-system/backend/src/app/modules/notification/subpoenaNotification.strings.ts
rename to apps/judicial-system/backend/src/app/modules/notification/services/subpoenaNotification/subpoenaNotification.strings.ts
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts b/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts
index 8c89e945896c..c5ea4ac34521 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts
@@ -24,16 +24,16 @@ import { DefendantService } from '../../defendant'
import { eventModuleConfig, EventService } from '../../event'
import { InstitutionService } from '../../institution'
import { UserService } from '../../user'
-import { CaseNotificationService } from '../caseNotification.service'
-import { CivilClaimantNotificationService } from '../civilClaimantNotification.service'
-import { DefendantNotificationService } from '../defendantNotification.service'
-import { InstitutionNotificationService } from '../institutionNotification.service'
import { InternalNotificationController } from '../internalNotification.controller'
import { Notification } from '../models/notification.model'
import { notificationModuleConfig } from '../notification.config'
import { NotificationController } from '../notification.controller'
import { NotificationService } from '../notification.service'
import { NotificationDispatchService } from '../notificationDispatch.service'
+import { CaseNotificationService } from '../services/caseNotification/caseNotification.service'
+import { CivilClaimantNotificationService } from '../services/civilClaimantNotification/civilClaimantNotification.service'
+import { DefendantNotificationService } from '../services/defendantNotification/defendantNotification.service'
+import { InstitutionNotificationService } from '../services/institutionNotification/institutionNotification.service'
jest.mock('@island.is/judicial-system/message')
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/defendantNotification/sendIndictmentSentToPrisonAdminNotification.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/defendantNotification/sendIndictmentSentToPrisonAdminNotification.spec.ts
new file mode 100644
index 000000000000..1c5f3468bbfa
--- /dev/null
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/defendantNotification/sendIndictmentSentToPrisonAdminNotification.spec.ts
@@ -0,0 +1,144 @@
+import { uuid } from 'uuidv4'
+
+import { EmailService } from '@island.is/email-service'
+
+import { ROUTE_HANDLER_ROUTE } from '@island.is/judicial-system/consts'
+import {
+ CaseType,
+ DefendantNotificationType,
+} from '@island.is/judicial-system/types'
+
+import { createTestingNotificationModule } from '../../createTestingNotificationModule'
+
+import { Case } from '../../../../case'
+import { Defendant } from '../../../../defendant'
+import { DefendantNotificationDto } from '../../../dto/defendantNotification.dto'
+import { DeliverResponse } from '../../../models/deliver.response'
+import { Notification } from '../../../models/notification.model'
+
+jest.mock('../../../../../factories')
+
+interface Then {
+ result: DeliverResponse
+ error: Error
+}
+
+type GivenWhenThen = (
+ caseId: string,
+ defendantId: string,
+ theCase: Case,
+ defendant: Defendant,
+ notificationDto: DefendantNotificationDto,
+) => Promise
+
+describe('InternalNotificationController - Defendant - Send indictment sent to prison admin notification', () => {
+ const caseId = uuid()
+ const defendantId = uuid()
+ const emails = [
+ 'prisonadminindictment@omnitrix.is',
+ 'prisonadminindictment2@omnitrix.is',
+ ]
+
+ let mockEmailService: EmailService
+ let mockNotificationModel: typeof Notification
+ let defendantNotificationDTO: DefendantNotificationDto
+
+ let givenWhenThen: GivenWhenThen
+
+ beforeEach(async () => {
+ process.env.PRISON_ADMIN_INDICTMENT_EMAILS = emails.join(',')
+
+ const { emailService, internalNotificationController, notificationModel } =
+ await createTestingNotificationModule()
+
+ defendantNotificationDTO = {
+ type: DefendantNotificationType.INDICTMENT_SENT_TO_PRISON_ADMIN,
+ }
+
+ mockEmailService = emailService
+ mockNotificationModel = notificationModel
+
+ givenWhenThen = async (
+ caseId: string,
+ defendantId: string,
+ theCase: Case,
+ defendant: Defendant,
+ notificationDto: DefendantNotificationDto,
+ ) => {
+ const then = {} as Then
+
+ try {
+ then.result =
+ await internalNotificationController.sendDefendantNotification(
+ caseId,
+ defendantId,
+ theCase,
+ defendant,
+ notificationDto,
+ )
+ } catch (error) {
+ then.error = error as Error
+ }
+
+ return then
+ }
+ })
+
+ describe('when sending indictment to prison admin', () => {
+ const defendant = {
+ id: defendantId,
+ } as Defendant
+
+ const theCase = {
+ id: caseId,
+ courtCaseNumber: 'S-123-456/2024',
+ type: CaseType.INDICTMENT,
+ defendants: [defendant],
+ } as Case
+
+ beforeEach(async () => {
+ await givenWhenThen(
+ caseId,
+ defendantId,
+ theCase,
+ defendant,
+ defendantNotificationDTO,
+ )
+ })
+
+ it('should send a notification to prison admin emails', () => {
+ expect(mockEmailService.sendEmail).toBeCalledTimes(emails.length)
+ emails.forEach((email) => {
+ expect(mockEmailService.sendEmail).toBeCalledWith(
+ expect.objectContaining({
+ to: [
+ {
+ name: 'Fangelsismálastofnun',
+ address: email,
+ },
+ ],
+
+ attachments: undefined,
+ subject: `Mál S-123-456/2024 til fullnustu`,
+ html: expect.stringContaining(ROUTE_HANDLER_ROUTE),
+ text: expect.stringContaining(
+ 'Ríkissaksóknari hefur sent mál S-123-456/2024 til fullnustu.',
+ ),
+ }),
+ )
+ })
+ })
+
+ it('should record notification', () => {
+ expect(mockNotificationModel.create).toHaveBeenCalledTimes(1)
+ expect(mockNotificationModel.create).toHaveBeenCalledWith({
+ caseId,
+ type: defendantNotificationDTO.type,
+ recipients: emails.map((email) => ({
+ address: email,
+ success: true,
+ })),
+ })
+ })
+ })
+})
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/defendantNotification/sendIndictmentWithdrawnFromPrisonAdminNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/defendantNotification/sendIndictmentWithdrawnFromPrisonAdminNotifications.spec.ts
new file mode 100644
index 000000000000..3a35e28ac53e
--- /dev/null
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/defendantNotification/sendIndictmentWithdrawnFromPrisonAdminNotifications.spec.ts
@@ -0,0 +1,140 @@
+import { uuid } from 'uuidv4'
+
+import { EmailService } from '@island.is/email-service'
+
+import {
+ CaseType,
+ DefendantNotificationType,
+} from '@island.is/judicial-system/types'
+
+import { createTestingNotificationModule } from '../../createTestingNotificationModule'
+
+import { Case } from '../../../../case'
+import { Defendant } from '../../../../defendant'
+import { DefendantNotificationDto } from '../../../dto/defendantNotification.dto'
+import { DeliverResponse } from '../../../models/deliver.response'
+import { Notification } from '../../../models/notification.model'
+
+jest.mock('../../../../../factories')
+
+interface Then {
+ result: DeliverResponse
+ error: Error
+}
+
+type GivenWhenThen = (
+ caseId: string,
+ defendantId: string,
+ theCase: Case,
+ defendant: Defendant,
+ notificationDto: DefendantNotificationDto,
+) => Promise
+
+describe('InternalNotificationController - Defendant - Send indictment withdrawn from prison admin notification', () => {
+ const caseId = uuid()
+ const defendantId = uuid()
+ const emails = [
+ 'prisonadminindictment@omnitrix.is',
+ 'prisonadminindictment2@omnitrix.is',
+ ]
+
+ let mockEmailService: EmailService
+ let mockNotificationModel: typeof Notification
+ let defendantNotificationDTO: DefendantNotificationDto
+
+ let givenWhenThen: GivenWhenThen
+
+ beforeEach(async () => {
+ process.env.PRISON_ADMIN_INDICTMENT_EMAILS = emails.join(',')
+
+ const { emailService, internalNotificationController, notificationModel } =
+ await createTestingNotificationModule()
+
+ defendantNotificationDTO = {
+ type: DefendantNotificationType.INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN,
+ }
+
+ mockEmailService = emailService
+ mockNotificationModel = notificationModel
+
+ givenWhenThen = async (
+ caseId: string,
+ defendantId: string,
+ theCase: Case,
+ defendant: Defendant,
+ notificationDto: DefendantNotificationDto,
+ ) => {
+ const then = {} as Then
+
+ try {
+ then.result =
+ await internalNotificationController.sendDefendantNotification(
+ caseId,
+ defendantId,
+ theCase,
+ defendant,
+ notificationDto,
+ )
+ } catch (error) {
+ then.error = error as Error
+ }
+
+ return then
+ }
+ })
+
+ describe('when withdrawing indictment from prison admin', () => {
+ const defendant = {
+ id: defendantId,
+ } as Defendant
+
+ const theCase = {
+ id: caseId,
+ courtCaseNumber: 'S-123-456/2024',
+ type: CaseType.INDICTMENT,
+ defendants: [defendant],
+ } as Case
+
+ beforeEach(async () => {
+ await givenWhenThen(
+ caseId,
+ defendantId,
+ theCase,
+ defendant,
+ defendantNotificationDTO,
+ )
+ })
+
+ it('should send a notification to prison admin emails', () => {
+ expect(mockEmailService.sendEmail).toBeCalledTimes(emails.length)
+ emails.forEach((email) => {
+ expect(mockEmailService.sendEmail).toBeCalledWith(
+ expect.objectContaining({
+ to: [
+ {
+ name: 'Fangelsismálastofnun',
+ address: email,
+ },
+ ],
+ subject: `Mál S-123-456/2024 afturkallað úr fullnustu`,
+ text: expect.stringContaining(
+ 'Ríkissaksóknari hefur afturkallað mál S-123-456/2024 úr fullnustu.',
+ ),
+ }),
+ )
+ })
+ })
+
+ it('should record notification', () => {
+ expect(mockNotificationModel.create).toHaveBeenCalledTimes(1)
+ expect(mockNotificationModel.create).toHaveBeenCalledWith({
+ caseId,
+ type: defendantNotificationDTO.type,
+ recipients: emails.map((email) => ({
+ address: email,
+ success: true,
+ })),
+ })
+ })
+ })
+})
diff --git a/charts/judicial-system/values.dev.yaml b/charts/judicial-system/values.dev.yaml
index b8ffb857f3cd..dd58423affdc 100644
--- a/charts/judicial-system/values.dev.yaml
+++ b/charts/judicial-system/values.dev.yaml
@@ -226,6 +226,7 @@ judicial-system-backend:
NOVA_URL: '/k8s/judicial-system/NOVA_URL'
NOVA_USERNAME: '/k8s/judicial-system/NOVA_USERNAME'
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
+ PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
diff --git a/charts/judicial-system/values.prod.yaml b/charts/judicial-system/values.prod.yaml
index 79a47b052253..dc74c1e64d61 100644
--- a/charts/judicial-system/values.prod.yaml
+++ b/charts/judicial-system/values.prod.yaml
@@ -226,6 +226,7 @@ judicial-system-backend:
NOVA_URL: '/k8s/judicial-system/NOVA_URL'
NOVA_USERNAME: '/k8s/judicial-system/NOVA_USERNAME'
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
+ PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
diff --git a/charts/judicial-system/values.staging.yaml b/charts/judicial-system/values.staging.yaml
index c7c7b8263784..3dacb3f6fb4a 100644
--- a/charts/judicial-system/values.staging.yaml
+++ b/charts/judicial-system/values.staging.yaml
@@ -226,6 +226,7 @@ judicial-system-backend:
NOVA_URL: '/k8s/judicial-system/NOVA_URL'
NOVA_USERNAME: '/k8s/judicial-system/NOVA_USERNAME'
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
+ PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
diff --git a/charts/services/judicial-system-backend/values.dev.yaml b/charts/services/judicial-system-backend/values.dev.yaml
index 54cc5578a728..8aeb2656041e 100644
--- a/charts/services/judicial-system-backend/values.dev.yaml
+++ b/charts/services/judicial-system-backend/values.dev.yaml
@@ -139,6 +139,7 @@ secrets:
NOVA_URL: '/k8s/judicial-system/NOVA_URL'
NOVA_USERNAME: '/k8s/judicial-system/NOVA_USERNAME'
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
+ PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
diff --git a/charts/services/judicial-system-backend/values.prod.yaml b/charts/services/judicial-system-backend/values.prod.yaml
index 35e807945f14..2807d821b9d9 100644
--- a/charts/services/judicial-system-backend/values.prod.yaml
+++ b/charts/services/judicial-system-backend/values.prod.yaml
@@ -139,6 +139,7 @@ secrets:
NOVA_URL: '/k8s/judicial-system/NOVA_URL'
NOVA_USERNAME: '/k8s/judicial-system/NOVA_USERNAME'
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
+ PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
diff --git a/charts/services/judicial-system-backend/values.staging.yaml b/charts/services/judicial-system-backend/values.staging.yaml
index 57039508f4ca..7221f2acfd51 100644
--- a/charts/services/judicial-system-backend/values.staging.yaml
+++ b/charts/services/judicial-system-backend/values.staging.yaml
@@ -139,6 +139,7 @@ secrets:
NOVA_URL: '/k8s/judicial-system/NOVA_URL'
NOVA_USERNAME: '/k8s/judicial-system/NOVA_USERNAME'
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL'
+ PRISON_ADMIN_INDICTMENT_EMAILS: '/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS'
PRISON_EMAIL: '/k8s/judicial-system/PRISON_EMAIL'
XROAD_CLIENT_CERT: '/k8s/judicial-system/XROAD_CLIENT_CERT'
XROAD_CLIENT_KEY: '/k8s/judicial-system/XROAD_CLIENT_KEY'
diff --git a/libs/judicial-system/types/src/lib/notification.ts b/libs/judicial-system/types/src/lib/notification.ts
index 6c449ffc196e..e9b8df060e63 100644
--- a/libs/judicial-system/types/src/lib/notification.ts
+++ b/libs/judicial-system/types/src/lib/notification.ts
@@ -23,6 +23,8 @@ export enum CaseNotificationType {
export enum DefendantNotificationType {
DEFENDANT_SELECTED_DEFENDER = 'DEFENDANT_SELECTED_DEFENDER',
DEFENDER_ASSIGNED = 'DEFENDER_ASSIGNED',
+ INDICTMENT_SENT_TO_PRISON_ADMIN = 'INDICTMENT_SENT_TO_PRISON_ADMIN',
+ INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN = 'INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN',
}
export enum SubpoenaNotificationType {
@@ -60,6 +62,8 @@ export enum NotificationType {
CASE_FILES_UPDATED = CaseNotificationType.CASE_FILES_UPDATED,
DEFENDANT_SELECTED_DEFENDER = DefendantNotificationType.DEFENDANT_SELECTED_DEFENDER,
DEFENDER_ASSIGNED = DefendantNotificationType.DEFENDER_ASSIGNED,
+ INDICTMENT_SENT_TO_PRISON_ADMIN = DefendantNotificationType.INDICTMENT_SENT_TO_PRISON_ADMIN,
+ INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN = DefendantNotificationType.INDICTMENT_WITHDRAWN_FROM_PRISON_ADMIN,
SERVICE_SUCCESSFUL = SubpoenaNotificationType.SERVICE_SUCCESSFUL,
SERVICE_FAILED = SubpoenaNotificationType.SERVICE_FAILED,
SPOKESPERSON_ASSIGNED = CivilClaimantNotificationType.SPOKESPERSON_ASSIGNED,