Skip to content

Commit

Permalink
Merge branch 'main' into my-pages/error-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Oct 23, 2024
2 parents 919b70f + f2f1f12 commit 1983cd6
Show file tree
Hide file tree
Showing 30 changed files with 662 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@ export class UpdateCivilClaimantInput {
@IsOptional()
@Field(() => Boolean, { nullable: true })
readonly caseFilesSharedWithSpokesperson?: boolean

@Allow()
@IsOptional()
@Field(() => Boolean, { nullable: true })
readonly isSpokespersonConfirmed?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,14 @@ export class UpdateDefendantInput {
@IsOptional()
@Field(() => SubpoenaType, { nullable: true })
readonly subpoenaType?: SubpoenaType

@Allow()
@IsOptional()
@Field(() => Boolean, { nullable: true })
readonly isDefenderChoiceConfirmed?: boolean

@Allow()
@IsOptional()
@Field(() => Boolean, { nullable: true })
readonly caseFilesSharedWithDefender?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ export class CivilClaimant {

@Field(() => Boolean, { nullable: true })
readonly caseFilesSharedWithSpokesperson?: boolean

@Field(() => Boolean, { nullable: true })
readonly isSpokespersonConfirmed?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,10 @@ export class Defendant {

@Field(() => [Subpoena], { nullable: true })
readonly subpoenas?: Subpoena[]

@Field(() => Boolean, { nullable: true })
readonly isDefenderChoiceConfirmed?: boolean

@Field(() => Boolean, { nullable: true })
readonly caseFilesSharedWithDefender?: boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) =>
Promise.all([
queryInterface.addColumn(
'defendant',
'is_defender_choice_confirmed',
{
type: Sequelize.BOOLEAN,
allowNull: true,
},
{ transaction: t },
),
queryInterface.addColumn(
'defendant',
'case_files_shared_with_defender',
{
type: Sequelize.BOOLEAN,
allowNull: true,
},
{ transaction: t },
),
]),
)
},
down: (queryInterface) => {
return queryInterface.sequelize.transaction((t) =>
Promise.all([
queryInterface.removeColumn(
'defendant',
'is_defender_choice_confirmed',
{
transaction: t,
},
),
queryInterface.removeColumn(
'defendant',
'case_files_shared_with_defender',
{
transaction: t,
},
),
]),
)
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) =>
queryInterface.addColumn(
'civil_claimant',
'is_spokesperson_confirmed',
{
type: Sequelize.BOOLEAN,
allowNull: true,
},
{ transaction: t },
),
)
},
down: (queryInterface) => {
return queryInterface.sequelize.transaction((t) =>
queryInterface.removeColumn(
'civil_claimant',
'is_spokesperson_confirmed',
{
transaction: t,
},
),
)
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,18 @@ const canDefenceUserAccessIndictmentCase = (
}

// Check case defender assignment
if (Defendant.isDefenderOfDefendant(user.nationalId, theCase.defendants)) {
if (
Defendant.isConfirmedDefenderOfDefendant(
user.nationalId,
theCase.defendants,
)
) {
return true
}

// Check case spokesperson assignment
if (
CivilClaimant.isSpokespersonOfCivilClaimant(
CivilClaimant.isConfirmedSpokespersonOfCivilClaimant(
user.nationalId,
theCase.civilClaimants,
) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ const getDefenceUserCasesQueryFilter = (user: User): WhereOptions => {
[Op.in]: Sequelize.literal(`
(SELECT case_id
FROM defendant
WHERE defender_national_id in ('${normalizedNationalId}', '${formattedNationalId}'))
WHERE defender_national_id in ('${normalizedNationalId}', '${formattedNationalId}') and is_defender_choice_confirmed = true)
`),
},
},
Expand All @@ -292,7 +292,7 @@ const getDefenceUserCasesQueryFilter = (user: User): WhereOptions => {
[Op.in]: Sequelize.literal(`
(SELECT case_id
FROM civil_claimant
WHERE has_spokesperson = true AND spokesperson_national_id in ('${normalizedNationalId}', '${formattedNationalId}'))
WHERE has_spokesperson = true AND spokesperson_national_id in ('${normalizedNationalId}', '${formattedNationalId}') and is_spokesperson_confirmed = true)
`),
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ describe('getCasesQueryFilter', () => {
[Op.in]: Sequelize.literal(`
(SELECT case_id
FROM defendant
WHERE defender_national_id in ('${user.nationalId}', '${user.nationalId}'))
WHERE defender_national_id in ('${user.nationalId}', '${user.nationalId}') and is_defender_choice_confirmed = true)
`),
},
},
Expand All @@ -468,7 +468,7 @@ describe('getCasesQueryFilter', () => {
[Op.in]: Sequelize.literal(`
(SELECT case_id
FROM civil_claimant
WHERE has_spokesperson = true AND spokesperson_national_id in ('${user.nationalId}', '${user.nationalId}'))
WHERE has_spokesperson = true AND spokesperson_national_id in ('${user.nationalId}', '${user.nationalId}') and is_spokesperson_confirmed = true)
`),
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,31 @@ describe.each(defenceRoles)('defence user %s', (role) => {
const theCase = {
type,
state,
defendants: [{}, { defenderNationalId: user.nationalId }, {}],
defendants: [
{},
{
defenderNationalId: user.nationalId,
},
{},
],
dateLogs: [{ dateType: DateType.ARRAIGNMENT_DATE, date: new Date() }],
} as Case

verifyNoAccess(theCase, user)
})

describe('confirmed defender assigned to case', () => {
const theCase = {
type,
state,
defendants: [
{},
{
defenderNationalId: user.nationalId,
isDefenderChoiceConfirmed: true,
},
{},
],
dateLogs: [{ dateType: DateType.ARRAIGNMENT_DATE, date: new Date() }],
} as Case

Expand Down Expand Up @@ -263,13 +287,35 @@ describe.each(defenceRoles)('defence user %s', (role) => {
verifyNoAccess(theCase, user)
})

describe('spokesperson assigned to case', () => {
describe('non confirmed spokesperson assigned to case', () => {
const theCase = {
type,
state,
civilClaimants: [
{},
{
hasSpokesperson: true,
spokespersonNationalId: user.nationalId,
},
{},
],
dateLogs: [{ dateType: DateType.ARRAIGNMENT_DATE, date: new Date() }],
} as Case

verifyNoAccess(theCase, user)
})

describe('confirmed spokesperson assigned to case', () => {
const theCase = {
type,
state,
civilClaimants: [
{},
{ hasSpokesperson: true, spokespersonNationalId: user.nationalId },
{
hasSpokesperson: true,
spokespersonNationalId: user.nationalId,
isSpokespersonConfirmed: true,
},
{},
],
dateLogs: [{ dateType: DateType.ARRAIGNMENT_DATE, date: new Date() }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,17 @@ export const defenderGeneratedPdfRule: RolesRule = {
}

// Allow if the user is a defender of a defendant of the case
if (Defendant.isDefenderOfDefendant(user.nationalId, theCase.defendants)) {
if (
Defendant.isConfirmedDefenderOfDefendantWithCaseFileAccess(
user.nationalId,
theCase.defendants,
)
) {
return true
}

if (
CivilClaimant.isSpokespersonOfCivilClaimantWithCaseFileAccess(
CivilClaimant.isConfirmedSpokespersonOfCivilClaimantWithCaseFileAccess(
user.nationalId,
theCase.civilClaimants,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ import type { User } from '@island.is/judicial-system/types'
import {
CaseState,
CaseType,
isDistrictCourtUser,
NotificationType,
} from '@island.is/judicial-system/types'

import { Case } from '../case/models/case.model'
import { CourtService } from '../court'
import { CreateDefendantDto } from './dto/createDefendant.dto'
import { InternalUpdateDefendantDto } from './dto/internalUpdateDefendant.dto'
import { UpdateDefendantDto } from './dto/updateDefendant.dto'
import { Defendant } from './models/defendant.model'
import { DeliverResponse } from './models/deliver.response'
Expand Down Expand Up @@ -199,8 +201,18 @@ export class DefendantService {
async updateByNationalId(
caseId: string,
defendantNationalId: string,
update: UpdateDefendantDto,
update: InternalUpdateDefendantDto,
): Promise<Defendant> {
// The reason we have a separate dto for this is because requests that end here
// are initiated by outside API's which should not be able to edit other fields
// Defendant updated originating from the judicial system should use the UpdateDefendantDto
// and go through the update method above using the defendantId.
// This is also why we set the isDefenderChoiceConfirmed to false here - the judge needs to confirm all changes.
update = {
...update,
isDefenderChoiceConfirmed: false,
} as UpdateDefendantDto

const [numberOfAffectedRows, defendants] = await this.defendantModel.update(
update,
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { IsEnum, IsOptional, IsString } from 'class-validator'

import { ApiPropertyOptional } from '@nestjs/swagger'

import { DefenderChoice } from '@island.is/judicial-system/types'

export class InternalUpdateDefendantDto {
@IsOptional()
@IsString()
@ApiPropertyOptional({ type: String })
readonly defenderName?: string

@IsOptional()
@IsString()
@ApiPropertyOptional({ type: String })
readonly defenderNationalId?: string

@IsOptional()
@IsString()
@ApiPropertyOptional({ type: String })
readonly defenderEmail?: string

@IsOptional()
@IsString()
@ApiPropertyOptional({ type: String })
readonly defenderPhoneNumber?: string

@IsOptional()
@IsEnum(DefenderChoice)
@ApiPropertyOptional({ enum: DefenderChoice })
readonly defenderChoice?: DefenderChoice

@IsOptional()
@IsEnum(DefenderChoice)
@ApiPropertyOptional({ enum: DefenderChoice })
readonly requestedDefenderChoice?: DefenderChoice

@IsOptional()
@IsString()
@ApiPropertyOptional({ type: String })
readonly requestedDefenderNationalId?: string

@IsOptional()
@IsString()
@ApiPropertyOptional({ type: String })
readonly requestedDefenderName?: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ export class UpdateCivilClaimantDto {
@IsBoolean()
@ApiPropertyOptional({ type: Boolean })
readonly caseFilesSharedWithSpokesperson?: boolean

@IsOptional()
@IsBoolean()
@ApiPropertyOptional({ type: Boolean })
readonly isSpokespersonConfirmed?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,14 @@ export class UpdateDefendantDto {
@IsString()
@ApiPropertyOptional({ type: String })
readonly requestedDefenderName?: string

@IsOptional()
@IsBoolean()
@ApiPropertyOptional({ type: Boolean })
readonly isDefenderChoiceConfirmed?: boolean

@IsOptional()
@IsBoolean()
@ApiPropertyOptional({ type: Boolean })
readonly caseFilesSharedWithDefender?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {

import { Case, CaseExistsGuard, CurrentCase } from '../case'
import { DeliverDefendantToCourtDto } from './dto/deliverDefendantToCourt.dto'
import { UpdateDefendantDto } from './dto/updateDefendant.dto'
import { InternalUpdateDefendantDto } from './dto/internalUpdateDefendant.dto'
import { CurrentDefendant } from './guards/defendant.decorator'
import { DefendantExistsGuard } from './guards/defendantExists.guard'
import { Defendant } from './models/defendant.model'
Expand Down Expand Up @@ -71,7 +71,7 @@ export class InternalDefendantController {
@Param('caseId') caseId: string,
@Param('defendantNationalId') defendantNationalId: string,
@CurrentCase() theCase: Case,
@Body() updatedDefendantChoice: UpdateDefendantDto,
@Body() updatedDefendantChoice: InternalUpdateDefendantDto,
): Promise<Defendant> {
this.logger.debug(`Updating defendant info for ${caseId}`)

Expand Down
Loading

0 comments on commit 1983cd6

Please sign in to comment.