From 06e8812286f30d6c8d9c0945358fb4a036729647 Mon Sep 17 00:00:00 2001 From: unakb Date: Mon, 14 Oct 2024 20:41:56 +0000 Subject: [PATCH] feat(j-s): Separate requested defender info from actual assigned defender info --- .../defendant/models/defendant.model.ts | 9 +++ .../20241011090000-update-defendant.js | 73 +++++++++++++++++++ .../defendant/dto/updateDefendant.dto.ts | 15 ++++ .../defendant/models/defendant.model.ts | 16 ++++ .../subpoena/dto/updateSubpoena.dto.ts | 15 ++++ .../app/modules/subpoena/subpoena.service.ts | 14 +++- .../src/app/modules/cases/case.service.ts | 31 ++++---- .../models/internal/internalCase.response.ts | 3 + .../internal/internalDefendant.response.ts | 3 + .../modules/cases/models/subpoena.response.ts | 15 ++-- .../src/components/FormProvider/case.graphql | 3 + .../Advocates/Advocates.strings.ts | 13 ++++ .../Court/Indictments/Advocates/Advocates.tsx | 18 +++++ .../xrd-api/src/app/app.service.ts | 29 ++------ 14 files changed, 211 insertions(+), 46 deletions(-) create mode 100644 apps/judicial-system/backend/migrations/20241011090000-update-defendant.js diff --git a/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts b/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts index 595b696e2c28..f1e16bf6a8aa 100644 --- a/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts +++ b/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts @@ -75,6 +75,15 @@ export class Defendant { @Field(() => DefenderChoice, { nullable: true }) readonly defenderChoice?: DefenderChoice + @Field(() => DefenderChoice, { nullable: true }) + readonly requestedDefenderChoice?: DefenderChoice + + @Field(() => String, { nullable: true }) + readonly requestedDefenderNationalId?: string + + @Field(() => String, { nullable: true }) + readonly requestedDefenderName?: string + @Field(() => SubpoenaType, { nullable: true }) readonly subpoenaType?: SubpoenaType diff --git a/apps/judicial-system/backend/migrations/20241011090000-update-defendant.js b/apps/judicial-system/backend/migrations/20241011090000-update-defendant.js new file mode 100644 index 000000000000..be8bda849016 --- /dev/null +++ b/apps/judicial-system/backend/migrations/20241011090000-update-defendant.js @@ -0,0 +1,73 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.sequelize.transaction(async (t) => { + await queryInterface.addColumn( + 'defendant', + 'requested_defender_choice', + { + type: Sequelize.STRING, + allowNull: true, + }, + { transaction: t }, + ) + await queryInterface.addColumn( + 'defendant', + 'requested_defender_national_id', + { + type: Sequelize.STRING, + allowNull: true, + }, + { transaction: t }, + ) + await queryInterface.addColumn( + 'defendant', + 'requested_defender_name', + { + type: Sequelize.STRING, + allowNull: true, + }, + { transaction: t }, + ) + + await queryInterface.sequelize.query( + `UPDATE "defendant" SET requested_defender_choice = defender_choice`, + { transaction: t }, + ) + + await queryInterface.sequelize.query( + `UPDATE "defendant" SET requested_defender_national_id = defender_national_id`, + { transaction: t }, + ) + + await queryInterface.sequelize.query( + `UPDATE "defendant" SET requested_defender_name = defender_name`, + { transaction: t }, + ) + }) + }, + down: (queryInterface) => { + return queryInterface.sequelize.transaction(async (t) => { + await queryInterface.removeColumn( + 'defendant', + 'requested_defender_choice', + { + transaction: t, + }, + ) + await queryInterface.removeColumn( + 'defendant', + 'requested_defender_national_id', + { + transaction: t, + }, + ) + await queryInterface.removeColumn( + 'defendant', + 'requested_defender_name', + { + transaction: t, + }, + ) + }) + }, +} diff --git a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts index a2e68e97a596..5c51ae0d2813 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts @@ -93,4 +93,19 @@ export class UpdateDefendantDto { @IsEnum(SubpoenaType) @ApiPropertyOptional({ enum: SubpoenaType }) readonly subpoenaType?: SubpoenaType + + @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 } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts b/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts index a72b69edeed0..b8c66a3bc14b 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts @@ -137,4 +137,20 @@ export class Defendant extends Model { @HasMany(() => Subpoena, { foreignKey: 'defendantId' }) @ApiPropertyOptional({ type: () => Subpoena, isArray: true }) subpoenas?: Subpoena[] + + @Column({ + type: DataType.ENUM, + allowNull: true, + values: Object.values(DefenderChoice), + }) + @ApiPropertyOptional({ enum: DefenderChoice }) + requestedDefenderChoice?: DefenderChoice + + @Column({ type: DataType.STRING, allowNull: true }) + @ApiPropertyOptional({ type: String }) + requestedDefenderNationalId?: string + + @Column({ type: DataType.STRING, allowNull: true }) + @ApiPropertyOptional({ type: String }) + requestedDefenderName?: string } diff --git a/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts b/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts index 1154f6fb0f81..5132ae3fb5d2 100644 --- a/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts @@ -49,4 +49,19 @@ export class UpdateSubpoenaDto { @IsString() @ApiPropertyOptional({ type: String }) readonly defenderPhoneNumber?: string + + @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 } diff --git a/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts b/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts index 937d1015920c..c476d085e835 100644 --- a/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts +++ b/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts @@ -20,7 +20,6 @@ import { type User, } from '@island.is/judicial-system/types' -import { indictment } from '../../messages' import { Case } from '../case/models/case.model' import { PdfService } from '../case/pdf.service' import { Defendant } from '../defendant/models/defendant.model' @@ -93,6 +92,9 @@ export class SubpoenaService { defenderEmail, defenderPhoneNumber, defenderName, + requestedDefenderChoice, + requestedDefenderNationalId, + requestedDefenderName, } = update const [numberOfAffectedRows] = await this.subpoenaModel.update(update, { @@ -102,13 +104,21 @@ export class SubpoenaService { }) let defenderAffectedRows = 0 - if (defenderChoice || defenderNationalId) { + if ( + defenderChoice || + defenderNationalId || + requestedDefenderChoice || + requestedDefenderNationalId + ) { const defendantUpdate: Partial = { defenderChoice, defenderNationalId, defenderName, defenderEmail, defenderPhoneNumber, + requestedDefenderChoice, + requestedDefenderNationalId, + requestedDefenderName, } const [defenderUpdateAffectedRows] = await this.defendantModel.update( diff --git a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts index 919a6f7e4fed..03ea716e60d8 100644 --- a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts +++ b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts @@ -117,8 +117,7 @@ export class CaseService { defenderAssignment: UpdateSubpoenaDto, lang?: string, ): Promise { - let defenderChoice = { ...defenderAssignment } - + let chosenLawyer = null if (defenderAssignment.defenderChoice === DefenderChoice.CHOOSE) { if (!defenderAssignment.defenderNationalId) { throw new NotFoundException( @@ -126,7 +125,7 @@ export class CaseService { ) } - const chosenLawyer = await this.lawyersService.getLawyer( + chosenLawyer = await this.lawyersService.getLawyer( defenderAssignment.defenderNationalId, ) @@ -135,20 +134,16 @@ export class CaseService { 'Selected lawyer was not found in the lawyer registry', ) } - - defenderChoice = { - ...defenderChoice, - ...{ - defenderName: chosenLawyer.Name, - defenderEmail: chosenLawyer.Email, - defenderPhoneNumber: chosenLawyer.Phone, - }, - } } - await this.patchSubpoenaInfo(defendantNationalId, caseId, defenderChoice) - + const defenderChoice = { + requestedDefenderChoice: defenderAssignment.defenderChoice, + requestedDefenderNationalId: defenderAssignment.defenderNationalId, + requestedDefenderName: chosenLawyer?.Name, + } + await this.patchDefenseInfo(defendantNationalId, caseId, defenderChoice) const updatedCase = await this.fetchCase(caseId, defendantNationalId) + return SubpoenaResponse.fromInternalCaseResponse( updatedCase, defendantNationalId, @@ -230,10 +225,14 @@ export class CaseService { } } - private async patchSubpoenaInfo( + private async patchDefenseInfo( defendantNationalId: string, caseId: string, - defenderChoice: UpdateSubpoenaDto, + defenderChoice: { + requestedDefenderChoice: DefenderChoice + requestedDefenderNationalId: string | undefined + requestedDefenderName?: string + }, ): Promise { try { const response = await fetch( diff --git a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalCase.response.ts b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalCase.response.ts index efff1d029dd3..bb45692f021d 100644 --- a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalCase.response.ts +++ b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalCase.response.ts @@ -30,6 +30,9 @@ interface Defendant { defenderPhoneNumber?: string defenderChoice?: DefenderChoice subpoenas?: Subpoena[] + requestedDefenderChoice?: DefenderChoice + requestedDefenderNationalId?: string + requestedDefenderName?: string } interface DateLog { diff --git a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalDefendant.response.ts b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalDefendant.response.ts index 808519a0d05c..1bd4dea18b69 100644 --- a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalDefendant.response.ts +++ b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/internal/internalDefendant.response.ts @@ -4,4 +4,7 @@ export class InternalDefendantResponse { id!: string defenderChoice?: DefenderChoice defenderName?: string + requestedDefenderChoice?: DefenderChoice + requestedDefenderNationalId?: string + requestedDefenderName?: string } diff --git a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/subpoena.response.ts b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/subpoena.response.ts index 0c432b55b5b5..4a5ec483e416 100644 --- a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/subpoena.response.ts +++ b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/models/subpoena.response.ts @@ -96,8 +96,9 @@ export class SubpoenaResponse { ), ) - const waivedRight = defendantInfo?.defenderChoice === DefenderChoice.WAIVE - const hasDefender = defendantInfo?.defenderName !== null + const waivedRight = + defendantInfo?.requestedDefenderChoice === DefenderChoice.WAIVE + const hasDefender = defendantInfo?.requestedDefenderNationalId !== null const subpoenas = defendantInfo?.subpoenas ?? [] const hasBeenServed = subpoenas.length > 0 && @@ -121,8 +122,8 @@ export class SubpoenaResponse { subtitle: courtNameAndAddress, hasBeenServed: hasBeenServed, hasChosenDefender: Boolean( - defendantInfo?.defenderChoice && - defendantInfo.defenderChoice !== DefenderChoice.DELAY, + defendantInfo?.requestedDefenderChoice && + defendantInfo.requestedDefenderChoice !== DefenderChoice.DELAY, ), defaultDefenderChoice: DefenderChoice.DELAY, alerts: [ @@ -160,12 +161,12 @@ export class SubpoenaResponse { ], }, - defenderInfo: defendantInfo?.defenderChoice + defenderInfo: defendantInfo?.requestedDefenderChoice ? { - defenderChoice: defendantInfo?.defenderChoice, + defenderChoice: defendantInfo?.requestedDefenderChoice, defenderName: !waivedRight && hasDefender - ? defendantInfo?.defenderName + ? defendantInfo?.requestedDefenderName : undefined, canEdit: canChangeDefenseChoice, courtContactInfo: canChangeDefenseChoice diff --git a/apps/judicial-system/web/src/components/FormProvider/case.graphql b/apps/judicial-system/web/src/components/FormProvider/case.graphql index d45521ec30d9..a8afe466ec62 100644 --- a/apps/judicial-system/web/src/components/FormProvider/case.graphql +++ b/apps/judicial-system/web/src/components/FormProvider/case.graphql @@ -22,6 +22,9 @@ query Case($input: CaseQueryInput!) { defenderPhoneNumber defenderChoice defendantPlea + requestedDefenderChoice + requestedDefenderNationalId + requestedDefenderName serviceRequirement verdictViewDate verdictAppealDeadline diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts index 1250e9fa97b9..ac7bfc63dc14 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts @@ -74,4 +74,17 @@ export const strings = defineMessages({ description: 'Notaður sem texti þegar enginn lögmaður er skráður í dómaraflæði í ákærum.', }, + defenderChoiceAlertTitle: { + id: 'judicial.system.core:court_indictments.advocates.defender_choice_alert_title', + defaultMessage: 'Val á verjanda - {defendantName}', + description: + 'Notaður sem texti þegar ákærði hefur valið verjanda í dómaraflæði í ákærum.', + }, + defenderChoiceAlertMessage: { + id: 'judicial.system.core:court_indictments.advocates.defender_choice_alert_message', + defaultMessage: + '{requestedDefenderChoice, select, WAIVE {Ég óska ekki eftir verjanda.} CHOOSE {Ég óska þess að valinn lögmaður verji skipaður verjandi minn: {requestedDefenderName} kt. {requestedDefenderNationalId}.} DELAY {Ég óska eftir fresti fram að þingfestingu til þess að tilnefna verjanda.} DELEGATE {Ég fel dómara málsins að tilnefna og skipa mér verjanda.} other {Ekkert valið.}}', + description: + 'Notaður sem texti þegar ákærði hefur valið verjanda í dómaraflæði í ákærum.', + }, }) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.tsx index 09e131c55de5..ed25cda84ea6 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.tsx @@ -59,6 +59,24 @@ const Advocates = () => { message={formatMessage(strings.alertBannerText)} type="info" /> + {workingCase.defendants + ?.filter((defendant) => defendant.requestedDefenderChoice) + .map((defendant) => ( + + + + ))} { - let defenderInfo: { - defenderName: string | undefined - defenderEmail: string | undefined - defenderPhoneNumber: string | undefined - } = { - defenderName: undefined, - defenderEmail: undefined, - defenderPhoneNumber: undefined, - } + let defenderName = undefined if ( updateSubpoena.defenderChoice === DefenderChoice.CHOOSE && @@ -120,11 +112,8 @@ export class AppService { const chosenLawyer = await this.lawyersService.getLawyer( updateSubpoena.defenderNationalId, ) - defenderInfo = { - defenderName: chosenLawyer.Name, - defenderEmail: chosenLawyer.Email, - defenderPhoneNumber: chosenLawyer.Phone, - } + + defenderName = chosenLawyer.Name } catch (reason) { // TODO: Reconsider throwing - what happens if registry is down? this.logger.error( @@ -152,11 +141,9 @@ export class AppService { comment: updateSubpoena.comment, servedBy: updateSubpoena.servedBy, serviceDate: updateSubpoena.servedAt, - defenderChoice: updateSubpoena.defenderChoice, - defenderNationalId: updateSubpoena.defenderNationalId, - defenderName: defenderInfo.defenderName, - defenderEmail: defenderInfo.defenderEmail, - defenderPhoneNumber: defenderInfo.defenderPhoneNumber, + requestedDefenderChoice: updateSubpoena.defenderChoice, + requestedDefenderNationalId: updateSubpoena.defenderNationalId, + requestedDefenderName: defenderName, } try { @@ -178,8 +165,8 @@ export class AppService { return { subpoenaComment: response.comment, defenderInfo: { - defenderChoice: response.defendant.defenderChoice, - defenderName: response.defendant.defenderName, + defenderChoice: response.defendant.requestedDefenderChoice, + defenderName: response.defendant.requestedDefenderName, }, } as SubpoenaResponse }