Skip to content

Commit

Permalink
Merge branch 'main' into j-s/order-indictment-case-files
Browse files Browse the repository at this point in the history
  • Loading branch information
unakb authored Jan 8, 2025
2 parents 29a8fc4 + e0cf15e commit c210203
Show file tree
Hide file tree
Showing 100 changed files with 1,881 additions and 423 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ codemagic.yaml
/apps/services/regulations-admin-backend/ @island-is/hugsmidjan
/apps/services/user-profile/ @island-is/hugsmidjan @island-is/juni @island-is/aranja
/apps/web/components/Grant/ @island-is/hugsmidjan
/apps/web/components/GrantCardsList/ @island-is/hugsmidjan
/apps/web/screens/Grants/ @island-is/hugsmidjan
/apps/web/screens/Regulations/ @island-is/hugsmidjan
/apps/web/components/Regulations/ @island-is/hugsmidjan
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { ApiScope } from '@island.is/auth/scopes'
import { FinanceClientService } from '@island.is/clients/finance'
import { AuditService } from '@island.is/nest/audit'
import {
Body,
Controller,
Header,
Param,
Post,
Res,
UseGuards,
Query,
} from '@nestjs/common'
import { ApiOkResponse } from '@nestjs/swagger'
import { Response } from 'express'
Expand All @@ -39,19 +39,20 @@ export class FinanceDocumentController {
@CurrentUser() user: User,
@Res() res: Response,
@Param('pdfId') pdfId: string,
@Body('annualDoc') annualDoc?: string,
@Query('action') action?: string,
) {
const documentResponse = annualDoc
? await this.financeService.getAnnualStatusDocument(
user.nationalId,
pdfId,
user,
)
: await this.financeService.getFinanceDocument(
user.nationalId,
pdfId,
user,
)
const documentResponse =
action === 'annualDoc'
? await this.financeService.getAnnualStatusDocument(
user.nationalId,
pdfId,
user,
)
: await this.financeService.getFinanceDocument(
user.nationalId,
pdfId,
user,
)

const documentBase64 = documentResponse?.docment?.document

Expand Down
2 changes: 2 additions & 0 deletions apps/judicial-system/backend/infra/judicial-system-backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ export const serviceSetup = (): ServiceBuilder<'judicial-system-backend'> =>
PRISON_ADMIN_EMAIL: '/k8s/judicial-system/PRISON_ADMIN_EMAIL',
PRISON_ADMIN_INDICTMENT_EMAILS:
'/k8s/judicial-system/PRISON_ADMIN_INDICTMENT_EMAILS',
PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL:
'/k8s/judicial-system/PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL',
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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,11 @@ export const notifications = {
defaultMessage: 'Landsréttur',
description: 'Nafn á Landsrétti í tölvupóstum',
},
publicProsecutorCriminalRecords: {
id: 'judicial.system.backend:notifications.email_names.public_prosecutor_criminal_records',
defaultMessage: 'Ritari sakaskrár',
description: 'Nafn á ritara sakaskrá í tölvupóstum',
},
}),
COAJudgeAssigned: defineMessages({
subject: {
Expand Down Expand Up @@ -837,9 +842,9 @@ export const notifications = {
description: 'Fyrirsögn í pósti til dómstóls þegar ákæra er afturkölluð',
},
body: {
id: 'judicial.system.backend:notifications.court_revoked_indictment_email.body',
id: 'judicial.system.backend:notifications.court_revoked_indictment_email.body_v1',
defaultMessage:
'{prosecutorsOffice} hefur afturkallað ákæru {courtCaseNumber, select, NONE {í máli sem ekki hefur enn fengið málsnúmer} other {í máli {courtCaseNumber}}}.',
'{prosecutorsOffice} hefur afturkallað ákæru í máli {caseNumber}.',
description: 'Texti í pósti til dómstóls þegar ákæra er afturkölluð',
},
}),
Expand Down
44 changes: 41 additions & 3 deletions apps/judicial-system/backend/src/app/modules/case/case.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,13 @@ export const caseListInclude: Includeable[] = [
order: [['created', 'DESC']],
separate: true,
},
{
model: Subpoena,
as: 'subpoenas',
required: false,
order: [['created', 'DESC']],
separate: true,
},
],
separate: true,
},
Expand Down Expand Up @@ -861,6 +868,17 @@ export class CaseService {
type: MessageType.DELIVERY_TO_COURT_INDICTMENT_CANCELLATION_NOTICE,
user,
caseId: theCase.id,
// Upon case cancellation, we send the same notification type to:
// (1) relevant court emails
// (2) court system (via robot).
//
// When a case is revoked without a court case number, we send email (1).
// The court must then add the case number in the system, triggering notification (2) for full cancellation.
//
// The court system requires a case number before posting data via robot, so it must be added despite the cancellation.
// Notifications (1) and (2) must match, thus we use the flag below to ensure the same message is sent.
// Without the flag, email (2) would get notification including the court case number.
// For more context: https://github.com/island-is/island.is/pull/17385/files#r1904268032
body: { withCourtCaseNumber: false },
})
}
Expand Down Expand Up @@ -1063,7 +1081,7 @@ export class CaseService {
)
}

private addMessagesForRevokedIndictmentCaseToQueue(
private async addMessagesForRevokedIndictmentCaseToQueue(
theCase: Case,
user: TUser,
): Promise<void> {
Expand All @@ -1078,6 +1096,21 @@ export class CaseService {
})
}

const subpoenasToRevoke = await this.subpoenaService.findByCaseId(
theCase.id,
)

if (subpoenasToRevoke?.length > 0) {
messages.push(
...subpoenasToRevoke.map((subpoena) => ({
type: MessageType.DELIVERY_TO_POLICE_SUBPOENA_REVOCATION,
user,
caseId: theCase.id,
elementId: [subpoena.defendantId, subpoena.id],
})),
)
}

return this.messageService.sendMessagesToQueue(messages)
}

Expand Down Expand Up @@ -1461,9 +1494,14 @@ export class CaseService {
[CaseState.SUBMITTED, CaseState.RECEIVED].includes(updatedCase.state)
) {
const isJudgeChanged =
updatedCase.judge?.nationalId !== theCase.judge?.nationalId
updatedCase.judge &&
updatedCase.judge.email &&
updatedCase.judge.nationalId !== theCase.judge?.nationalId

const isRegistrarChanged =
updatedCase.registrar?.nationalId !== theCase.registrar?.nationalId
updatedCase.registrar &&
updatedCase.registrar.email &&
updatedCase.registrar.nationalId !== theCase.registrar?.nationalId

if (isJudgeChanged) {
await this.addMessagesForDistrictCourtJudgeAssignedToQueue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ const prosecutorFields: (keyof UpdateCaseDto)[] = [
'hasCivilClaims',
]

const publicProsecutorFields: (keyof UpdateCaseDto)[] = ['indictmentReviewerId']
const publicProsecutorFields: (keyof UpdateCaseDto)[] = [
'indictmentReviewerId',
'indictmentReviewDecision',
]

const districtCourtFields: (keyof UpdateCaseDto)[] = [
'defenderName',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -672,23 +672,24 @@ export class InternalCaseService {
): Promise<DeliverResponse> {
await this.refreshFormatMessage()

const courtCaseNumber = withCourtCaseNumber && theCase.courtCaseNumber
const caseNumber = courtCaseNumber || theCase.policeCaseNumbers.join(', ')

return this.courtService
.updateIndictmentCaseWithCancellationNotice(
user,
theCase.id,
theCase.court?.name,
theCase.courtCaseNumber,
this.formatMessage(notifications.courtRevokedIndictmentEmail.subject, {
courtCaseNumber:
(withCourtCaseNumber && theCase.courtCaseNumber) || 'NONE',
courtCaseNumber: courtCaseNumber || 'NONE',
}),
stripHtmlTags(
`${this.formatMessage(
notifications.courtRevokedIndictmentEmail.body,
{
prosecutorsOffice: theCase.creatingProsecutor?.institution?.name,
courtCaseNumber:
(withCourtCaseNumber && theCase.courtCaseNumber) || 'NONE',
caseNumber,
},
)} ${this.formatMessage(notifications.emailTail)}`,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ describe('InternalCaseController - Deliver indictment cancellation notice to cou
const courtName = uuid()
const courtCaseNumber = uuid()
const prosecutorsOffice = uuid()
const policeCase1 = '007-2022-01'
const policeCase2 = '007-2022-02'

const policeCaseNumbers = [policeCase1, policeCase2]

const theCase = {
id: caseId,
type: CaseType.INDICTMENT,
creatingProsecutor: { institution: { name: prosecutorsOffice } },
court: { name: courtName },
courtCaseNumber,
policeCaseNumbers,
} as Case

let mockCourtService: CourtService
Expand Down Expand Up @@ -88,7 +93,7 @@ describe('InternalCaseController - Deliver indictment cancellation notice to cou
})
})

describe('deliver cancellation notice without court case number', () => {
describe('deliver cancellation notice with police case numbers', () => {
let then: Then

beforeAll(async () => {
Expand All @@ -104,7 +109,7 @@ describe('InternalCaseController - Deliver indictment cancellation notice to cou
courtName,
courtCaseNumber,
'Ákæra afturkölluð',
`${prosecutorsOffice} hefur afturkallað ákæru í máli sem ekki hefur enn fengið málsnúmer. Hægt er að nálgast yfirlitssíðu málsins á rettarvorslugatt.island.is.`,
`${prosecutorsOffice} hefur afturkallað ákæru í máli ${policeCase1}, ${policeCase2}. Hægt er að nálgast yfirlitssíðu málsins á rettarvorslugatt.island.is.`,
)

expect(then.result).toEqual({ delivered: true })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export const notificationModuleConfig = defineConfig({
'PRISON_ADMIN_INDICTMENT_EMAILS',
'',
),
publicProsecutorCriminalRecordsEmail: env.required(
'PUBLIC_PROSECUTOR_CRIMINAL_RECORDS_EMAIL',
'',
),
courtsEmails: env.requiredJSON('COURTS_EMAILS', {}) as {
[key: string]: string
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import {
Injectable,
InternalServerErrorException,
} from '@nestjs/common'
import { ConfigType } from '@nestjs/config'

import { type Logger, LOGGER_PROVIDER } from '@island.is/logging'

import { MessageService, MessageType } from '@island.is/judicial-system/message'
import {
CaseFileCategory,
EventNotificationType,
IndictmentCaseNotificationType,
InstitutionNotificationType,
Expand Down Expand Up @@ -71,15 +71,28 @@ export class NotificationDispatchService {
private async dispatchIndictmentSentToPublicProsecutorNotifications(
theCase: Case,
): Promise<void> {
return this.messageService.sendMessagesToQueue([
const messages = [
{
type: MessageType.INDICTMENT_CASE_NOTIFICATION,
caseId: theCase.id,
body: {
type: IndictmentCaseNotificationType.INDICTMENT_VERDICT_INFO,
},
},
])
]
const hasCriminalRecordFiles = theCase.caseFiles?.some(
(file) => file.category === CaseFileCategory.CRIMINAL_RECORD_UPDATE,
)
if (hasCriminalRecordFiles) {
messages.push({
type: MessageType.INDICTMENT_CASE_NOTIFICATION,
caseId: theCase.id,
body: {
type: IndictmentCaseNotificationType.CRIMINAL_RECORD_FILES_UPLOADED,
},
})
}
return this.messageService.sendMessagesToQueue(messages)
}

async dispatchEventNotification(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,10 @@ export class CaseNotificationService extends BaseNotificationService {
const official =
role === UserRole.DISTRICT_COURT_JUDGE ? theCase.judge : theCase.registrar

if (!official?.email) {
return Promise.resolve({ success: true })
}

return this.sendEmail(
this.formatMessage(notifications.courtOfficialAssignedEmail.subject, {
courtCaseNumber: theCase.courtCaseNumber,
Expand Down Expand Up @@ -1439,24 +1443,25 @@ export class CaseNotificationService extends BaseNotificationService {
recipientName?: string,
recipientEmail?: string,
): Promise<Recipient> {
const { courtCaseNumber } = theCase
const subject = this.formatMessage(
notifications.courtRevokedIndictmentEmail.subject,
{
courtCaseNumber: theCase.courtCaseNumber ?? 'NONE',
courtCaseNumber: courtCaseNumber || 'NONE',
},
)
const body = this.formatMessage(
notifications.courtRevokedIndictmentEmail.body,
{
prosecutorsOffice: theCase.creatingProsecutor?.institution?.name,
courtCaseNumber: theCase.courtCaseNumber ?? 'NONE',
caseNumber: courtCaseNumber || theCase.policeCaseNumbers.join(', '),
},
)

return this.sendEmail(subject, body, recipientName, recipientEmail)
}

private async sendRevodeNotificationsForIndictmentCase(
private async sendRevokeNotificationsForIndictmentCase(
theCase: Case,
): Promise<DeliverResponse> {
const promises: Promise<Recipient>[] = []
Expand Down Expand Up @@ -1534,7 +1539,7 @@ export class CaseNotificationService extends BaseNotificationService {
if (isRequestCase(theCase.type)) {
return this.sendRevokedNotificationsForRequestCase(theCase)
} else {
return this.sendRevodeNotificationsForIndictmentCase(theCase)
return this.sendRevokeNotificationsForIndictmentCase(theCase)
}
}
//#endregion
Expand Down
Loading

0 comments on commit c210203

Please sign in to comment.