Skip to content

Commit

Permalink
feat(j-s): Deliver assigned court roles for indictments to court (#15205
Browse files Browse the repository at this point in the history
)

* feat(j-s): Robot email for assigned roles in indictment case

* Update message.ts

* feat(j-s): Trigger for updating court role

* Update deliverIndictmentAssignedRolesToCourt.spec.ts

* Merge conflicts resolved

* fix(j-s): test cleanup

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
unakb and kodiakhq[bot] authored Jun 18, 2024
1 parent 17a146e commit ec6c19e
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 1 deletion.
39 changes: 39 additions & 0 deletions apps/judicial-system/backend/src/app/modules/case/case.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,21 @@ export class CaseService {
return this.messageService.sendMessagesToQueue(messages)
}

private addMessagesForIndictmentCourtRoleAssigned(
theCase: Case,
user: TUser,
assignedNationalId: string,
): Promise<void> {
return this.messageService.sendMessagesToQueue([
{
type: MessageType.DELIVERY_TO_COURT_INDICTMENT_COURT_ROLES,
user,
caseId: theCase.id,
elementId: assignedNationalId,
},
])
}

private addMessagesForCourtCaseConnectionToQueue(
theCase: Case,
user: TUser,
Expand Down Expand Up @@ -1203,6 +1218,30 @@ export class CaseService {
}
}

if (
isIndictmentCase(updatedCase.type) &&
![
CaseState.DRAFT,
CaseState.SUBMITTED,
CaseState.WAITING_FOR_CONFIRMATION,
].includes(updatedCase.state)
) {
const updatedRole =
updatedCase.judge?.nationalId !== theCase.judge?.nationalId
? updatedCase.judge
: updatedCase.registrar?.nationalId !== theCase.registrar?.nationalId
? updatedCase.registrar
: null

if (updatedRole?.nationalId) {
await this.addMessagesForIndictmentCourtRoleAssigned(
updatedCase,
user,
updatedRole.nationalId,
)
}
}

// This only applies to restriction cases
if (updatedCase.appealCaseNumber) {
if (updatedCase.appealCaseNumber !== theCase.appealCaseNumber) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,33 @@ export class InternalCaseController {
)
}

@UseGuards(CaseExistsGuard, new CaseTypeGuard(indictmentCases))
@Post(
`case/:caseId/${
messageEndpoint[MessageType.DELIVERY_TO_COURT_INDICTMENT_COURT_ROLES]
}/:nationalId`,
)
@ApiOkResponse({
type: DeliverResponse,
description: 'Delivers assigned roles in indictment case to court',
})
deliverIndictmentAssignedRoleToCourt(
@Param('caseId') caseId: string,
@CurrentCase() theCase: Case,
@Body() deliverDto: DeliverDto,
@Param('nationalId') nationalId: string,
): Promise<DeliverResponse> {
this.logger.debug(
`Delivering the assigned roles of indictment case ${caseId} to court`,
)

return this.internalCaseService.deliverIndictmentAssignedRolesToCourt(
theCase,
deliverDto.user,
nationalId,
)
}

@UseGuards(CaseExistsGuard, new CaseTypeGuard(indictmentCases))
@Post(
`case/:caseId/${
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,41 @@ export class InternalCaseService {
})
}

async deliverIndictmentAssignedRolesToCourt(
theCase: Case,
user: TUser,
nationalId?: string,
): Promise<DeliverResponse> {
const assignedRole =
theCase.judge?.nationalId === nationalId
? {
name: theCase.judge?.name,
role: UserRole.DISTRICT_COURT_JUDGE,
}
: theCase.registrar?.nationalId === nationalId
? {
name: theCase.registrar?.name,
role: UserRole.DISTRICT_COURT_REGISTRAR,
}
: {}

return this.courtService
.updateIndictmentCaseWithAssignedRoles(
user,
theCase.id,
theCase.courtCaseNumber,
assignedRole,
)
.then(() => ({ delivered: true }))
.catch((reason) => {
this.logger.error(
`Failed to update indictment case ${theCase.id} with assigned roles`,
{ reason },
)

return { delivered: false }
})
}
async deliverCaseFilesRecordToCourt(
theCase: Case,
policeCaseNumber: string,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { uuid } from 'uuidv4'

import { CaseType, User, UserRole } from '@island.is/judicial-system/types'

import { createTestingCaseModule } from '../createTestingCaseModule'

import { CourtService } from '../../../court'
import { Case } from '../../models/case.model'
import { DeliverResponse } from '../../models/deliver.response'

interface Then {
result: DeliverResponse
error: Error
}

type GivenWhenThen = (
caseId: string,
theCase: Case,
nationalId: string,
) => Promise<Then>

describe('InternalCaseController - Deliver assigned roles for indictment case to court', () => {
const user = { id: uuid() } as User
const caseId = uuid()
const courtCaseNumber = uuid()

const theCase = {
id: caseId,
type: CaseType.INDICTMENT,
courtCaseNumber,
judge: { name: 'Test Dómari', nationalId: '0101010101' },
registrar: { name: 'Test Ritari', nationalId: '0202020202' },
} as Case

let mockCourtService: CourtService
let givenWhenThen: GivenWhenThen

beforeAll(async () => {
const { courtService, internalCaseController } =
await createTestingCaseModule()

mockCourtService = courtService
const mockUpdateIndictmentCaseWithAssignedRoles =
mockCourtService.updateIndictmentCaseWithAssignedRoles as jest.Mock
mockUpdateIndictmentCaseWithAssignedRoles.mockResolvedValue(uuid())

givenWhenThen = async (
caseId: string,
theCase: Case,
nationalId: string,
) => {
const then = {} as Then

await internalCaseController
.deliverIndictmentAssignedRoleToCourt(
caseId,
theCase,
{ user },
nationalId,
)
.then((result) => (then.result = result))
.catch((error) => (then.error = error))

return then
}
})

describe('deliver assigned roles in indictment case to court', () => {
let then: Then

beforeAll(async () => {
then = await givenWhenThen(caseId, theCase, '0101010101')
})

it('should deliver the assigned roles to the court', () => {
expect(
mockCourtService.updateIndictmentCaseWithAssignedRoles,
).toHaveBeenCalledWith(user, theCase.id, theCase.courtCaseNumber, {
name: theCase.judge?.name,
role: UserRole.DISTRICT_COURT_JUDGE,
})

expect(then.result).toEqual({ delivered: true })
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { indictmentCases } from '@island.is/judicial-system/types'

import { CaseExistsGuard } from '../../guards/caseExists.guard'
import { CaseTypeGuard } from '../../guards/caseType.guard'
import { InternalCaseController } from '../../internalCase.controller'

describe('InternalCaseController - Deliver assigned roles in indictment case to court guards', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let guards: any[]

beforeEach(() => {
guards = Reflect.getMetadata(
'__guards__',
InternalCaseController.prototype.deliverIndictmentAssignedRoleToCourt,
)
})

it('should have the right guard configuration', () => {
expect(new guards[0]()).toBeInstanceOf(CaseExistsGuard)
expect(guards[1]).toBeInstanceOf(CaseTypeGuard)
expect(guards[1]).toEqual({
allowedCaseTypes: indictmentCases,
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { ConfigType } from '@island.is/nest/config'

import { CourtClientService } from '@island.is/judicial-system/court-client'
import { sanitize } from '@island.is/judicial-system/formatters'
import type { User } from '@island.is/judicial-system/types'
import type { User, UserRole } from '@island.is/judicial-system/types'
import {
CaseAppealRulingDecision,
CaseDecision,
Expand Down Expand Up @@ -128,6 +128,7 @@ enum RobotEmailType {
APPEAL_CASE_CONCLUSION = 'APPEAL_CASE_CONCLUSION',
APPEAL_CASE_FILE = 'APPEAL_CASE_FILE',
NEW_INDICTMENT_INFO = 'INDICTMENT_INFO',
INDICTMENT_CASE_ASSIGNED_ROLES = 'INDICTMENT_CASE_ASSIGNED_ROLES',
INDICTMENT_CASE_DEFENDER_INFO = 'INDICTMENT_CASE_DEFENDER_INFO',
}

Expand Down Expand Up @@ -643,6 +644,37 @@ export class CourtService {
}
}

async updateIndictmentCaseWithAssignedRoles(
user: User,
caseId: string,
courtCaseNumber?: string,
assignedRole?: { name?: string; role?: UserRole },
): Promise<unknown> {
try {
const subject = `Ákæra - ${courtCaseNumber} - úthlutun`
const content = JSON.stringify(assignedRole)

return this.sendToRobot(
subject,
content,
RobotEmailType.INDICTMENT_CASE_ASSIGNED_ROLES,
caseId,
)
} catch (error) {
this.eventService.postErrorEvent(
'Failed to update indictment case with assigned roles',
{
caseId,
actor: user.name,
courtCaseNumber,
},
error,
)

throw error
}
}

async updateAppealCaseWithReceivedDate(
user: User,
caseId: string,
Expand Down
3 changes: 3 additions & 0 deletions libs/judicial-system/message/src/lib/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export enum MessageType {
DELIVERY_TO_COURT_DEFENDANT = 'DELIVERY_TO_COURT_DEFENDANT',
DELIVERY_TO_COURT_INDICTMENT = 'DELIVERY_TO_COURT_INDICTMENT',
DELIVERY_TO_COURT_INDICTMENT_INFO = 'DELIVERY_TO_COURT_INDICTMENT_INFO',
DELIVERY_TO_COURT_INDICTMENT_COURT_ROLES = 'DELIVERY_TO_COURT_INDICTMENT_COURT_ROLES',
DELIVERY_TO_COURT_INDICTMENT_DEFENDER = 'DELIVERY_TO_COURT_INDICTMENT_DEFENDER',
DELIVERY_TO_COURT_CASE_FILE = 'DELIVERY_TO_COURT_CASE_FILE',
DELIVERY_TO_COURT_CASE_FILES_RECORD = 'DELIVERY_TO_COURT_CASE_FILES_RECORD',
Expand Down Expand Up @@ -32,6 +33,8 @@ export const messageEndpoint: { [key in MessageType]: string } = {
DELIVERY_TO_COURT_PROSECUTOR: 'deliverProsecutorToCourt',
DELIVERY_TO_COURT_DEFENDANT: 'deliverDefendantToCourt',
DELIVERY_TO_COURT_INDICTMENT: 'deliverIndictmentToCourt',
DELIVERY_TO_COURT_INDICTMENT_COURT_ROLES:
'deliverIndictmentCourtRolesToCourt',
DELIVERY_TO_COURT_INDICTMENT_INFO: 'deliverIndictmentInfoToCourt',
DELIVERY_TO_COURT_INDICTMENT_DEFENDER: 'deliverIndictmentDefenderToCourt',
DELIVERY_TO_COURT_CASE_FILE: 'deliverCaseFileToCourt',
Expand Down

0 comments on commit ec6c19e

Please sign in to comment.