From 5c0c30e67b9211837d598e016c9478b535844541 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 26 Jan 2024 13:56:46 +0000 Subject: [PATCH 01/44] rectifying data type mismatches, add un-defined Enums and attributes, adding in-line comments --- src/models/adr-details.ts | 103 +++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 25 deletions(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index 7767fee..6ed3593 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -1,6 +1,7 @@ import { DynamoDbImage, parseStringArray } from "../services/dynamodb-images"; import { Maybe } from "./optionals"; +// define AdrDetails' high-level attributes data types export interface AdrDetails { vehicleDetails?: VehicleDetails; listStatementApplicable?: boolean; @@ -9,12 +10,13 @@ export interface AdrDetails { brakeDeclarationsSeen?: boolean; brakeDeclarationIssuer?: string; brakeEndurance?: boolean; - weight?: string; - compatibilityGroupJ?: boolean; + weight?: number; + compatibilityGroupJ?: string; documents?: string[]; permittedDangerousGoods?: string[]; - additionalExaminerNotes?: string; + additionalExaminerNotes?: AdditionalExaminerNotes; applicantDetails?: ApplicantDetails; + dangerousGoods?: boolean; memosApply?: string[]; additionalNotes?: AdditionalNotes; adrTypeApprovalNo?: string; @@ -22,11 +24,45 @@ export interface AdrDetails { tank?: Tank; } +// define Enums +export type VehicleDetailsTypeEnum = "Artic tractor" | "Rigid box body" | "Rigid sheeted load" | "Rigid tank" | + "Rigid skeletal" | "Rigid battery" | "Full drawbar box body" | + "Full drawbar sheeted load" | "Full drawbar tank" | "Full drawbar skeletal" | + "Full drawbar battery" | "Centre axle box body" | "Centre axle sheeted load" | + "Centre axle tank" | "Centre axle skeletal" | "Centre axle battery" | + "Semi trailer box body" | "Semi trailer sheeted load" | "Semi trailer tank" | + "Semi trailer skeletal" | "Semi trailer battery Enum" + +export type Tc2TypeEnum = "initial"; + +export type Tc3TypeEnum = "intermediate" | "periodic" | "exceptional"; + +export type permittedDangerousGoodsEnum = "FP <61 (FL)" | "AT" | "Class 5.1 Hydrogen Peroxide (OX)" | "MEMU" | + "Carbon Disulphide" | "Hydrogen" | "Explosives (type 2)" | "Explosives (type 3)" + +export type compatibilityGroupJEnum = "I" | "E" + +export type additionalNotesNumberEnum = "1" | "1A" | "2" | "3" | "V1B" | "T1B" + +export type substancesPermittedEnum = "Substances permitted under the tank code and any special provisions specified in 9 may be carried" | + "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried" + +export type memosApplyEnum = "07/09 3mth leak ext" + +// define AdrDetails' sub-attributes data types export interface VehicleDetails { - type?: string; + type?: VehicleDetailsTypeEnum; approvalDate?: string; } +export type AdditionalExaminerNotes = AdditionalExaminerNotesItems[]; + +export interface AdditionalExaminerNotesItems { + note?: string; + createdAtDate?: string; + lastUpdatedBy?: string; +} + export interface ApplicantDetails { name?: string; street?: string; @@ -36,8 +72,8 @@ export interface ApplicantDetails { } export interface AdditionalNotes { - number?: string[]; - guidanceNotes?: string[]; + number?: additionalNotesNumberEnum[]; + // guidanceNotes?: string[]; } export interface Tank { @@ -58,6 +94,7 @@ export interface TankDetails { export interface TankStatement { substancesPermitted?: string; + select?: string; statement?: string; productListRefNo?: string; productListUnNo?: string[]; @@ -65,23 +102,21 @@ export interface TankStatement { } export interface Tc2Details { - tc2Type?: Tc2Type; + tc2Type?: Tc2TypeEnum; tc2IntermediateApprovalNo?: string; tc2IntermediateExpiryDate?: string; } -export type Tc2Type = "initial"; export type Tc3Details = Tc3DetailsItem[]; export interface Tc3DetailsItem { - tc3Type?: Tc3Type; + tc3Type?: Tc3TypeEnum; tc3PeriodicNumber?: string; tc3PeriodicExpiryDate?: string; } -export type Tc3Type = "intermediate" | "periodic" | "exceptional"; - +// function to parse AdrDetails' high-level and sub attributes + return AdrDetails object export const parseAdrDetails = ( adrDetails?: DynamoDbImage ): Maybe => { @@ -93,10 +128,10 @@ export const parseAdrDetails = ( "additionalNotes" )!; const additionalNotes: AdditionalNotes = { - number: parseStringArray(additionalNotesImage.getList("number")), - guidanceNotes: parseStringArray( - additionalNotesImage.getList("guidanceNotes") - ), + number: parseStringArray(additionalNotesImage.getList("number")) as additionalNotesNumberEnum[], + // guidanceNotes: parseStringArray( + // additionalNotesImage.getList("guidanceNotes") + // ), }; const applicantDetailsImage: DynamoDbImage = adrDetails.getMap( @@ -114,7 +149,7 @@ export const parseAdrDetails = ( "vehicleDetails" )!; const vehicleDetails: VehicleDetails = { - type: vehicleDetailsImage.getString("type"), + type: vehicleDetailsImage.getString("type") as VehicleDetailsTypeEnum, approvalDate: vehicleDetailsImage.getString("approvalDate"), }; @@ -124,7 +159,7 @@ export const parseAdrDetails = ( const tc2DetailsImage: DynamoDbImage = tankDetailsImage.getMap("tc2Details")!; const tc2Details: Tc2Details = { - tc2Type: tc2DetailsImage.getString("tc2Type") as Tc2Type, + tc2Type: tc2DetailsImage.getString("tc2Type") as Tc2TypeEnum, tc2IntermediateApprovalNo: tc2DetailsImage.getString( "tc2IntermediateApprovalNo" ), @@ -141,7 +176,7 @@ export const parseAdrDetails = ( for (const key of tc3DetailsImage.getKeys()) { const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; tc3Details.push({ - tc3Type: tc3DetailsItemImage.getString("tc3Type") as Tc3Type, + tc3Type: tc3DetailsItemImage.getString("tc3Type") as Tc3TypeEnum, tc3PeriodicNumber: tc3DetailsItemImage.getString("tc3PeriodicNumber"), tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( "tc3PeriodicExpiryDate" @@ -151,7 +186,7 @@ export const parseAdrDetails = ( const tankDetails: TankDetails = { tankManufacturer: tankDetailsImage.getString("tankManufacturer"), - yearOfManufacture: 0, + yearOfManufacture: tankDetailsImage.getNumber("yearOfManufacture"), tankCode: tankDetailsImage.getString("tankCode"), specialProvisions: tankDetailsImage.getString("specialProvisions"), tankManufacturerSerialNo: tankDetailsImage.getString( @@ -164,7 +199,8 @@ export const parseAdrDetails = ( const tankStatementImage: DynamoDbImage = tankImage.getMap("tankStatement")!; const tankStatement: TankStatement = { - substancesPermitted: tankStatementImage.getString("substancesPermitted"), + substancesPermitted: tankStatementImage.getString("substancesPermitted") as substancesPermittedEnum, + select: tankStatementImage.getString("select"), statement: tankStatementImage.getString("statement"), productListRefNo: tankStatementImage.getString("productListRefNo"), productListUnNo: parseStringArray( @@ -178,6 +214,22 @@ export const parseAdrDetails = ( tankStatement, }; + + const additionalExaminerNotesImage: DynamoDbImage = adrDetails.getList( + "additionalExaminerNotes" + )!; + const additionalExaminerNotes: AdditionalExaminerNotes = []; + + for (const key of additionalExaminerNotesImage.getKeys()) { + const additionalExaminerNotesItemImage = additionalExaminerNotesImage.getMap(key)!; + additionalExaminerNotes.push({ + note: additionalExaminerNotesItemImage.getString("note"), + createdAtDate: additionalExaminerNotesItemImage.getString("createdAtDate"), + lastUpdatedBy: additionalExaminerNotesItemImage.getString("lastUpdatedBy"), + }); + }; + + return { vehicleDetails, listStatementApplicable: adrDetails.getBoolean("listStatementApplicable"), @@ -186,15 +238,16 @@ export const parseAdrDetails = ( brakeDeclarationsSeen: adrDetails.getBoolean("brakeDeclarationsSeen"), brakeDeclarationIssuer: adrDetails.getString("brakeDeclarationIssuer"), brakeEndurance: adrDetails.getBoolean("brakeEndurance"), - weight: adrDetails.getString("weight"), - compatibilityGroupJ: adrDetails.getBoolean("compatibilityGroupJ"), + weight: adrDetails.getNumber("weight"), + compatibilityGroupJ: adrDetails.getString("compatibilityGroupJ") as compatibilityGroupJEnum, documents: parseStringArray(adrDetails.getList("documents")), permittedDangerousGoods: parseStringArray( adrDetails.getList("permittedDangerousGoods") - ), - additionalExaminerNotes: adrDetails.getString("additionalExaminerNotes"), + ) as permittedDangerousGoodsEnum[], + additionalExaminerNotes: additionalExaminerNotes, applicantDetails, - memosApply: parseStringArray(adrDetails.getList("memosApply")), + dangerousGoods: adrDetails.getBoolean("dangerousGoods"), + memosApply: parseStringArray(adrDetails.getList("memosApply")) as memosApplyEnum[], additionalNotes, adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo"), adrCertificateNotes: adrDetails.getString("adrCertificateNotes"), From 96b894ec39954074951c087e7c873468e1464cd0 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 26 Jan 2024 13:57:57 +0000 Subject: [PATCH 02/44] add AdrCertificateDetails interface and parsing function --- src/models/adr-certificate-details.ts | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/models/adr-certificate-details.ts diff --git a/src/models/adr-certificate-details.ts b/src/models/adr-certificate-details.ts new file mode 100644 index 0000000..b3ebca2 --- /dev/null +++ b/src/models/adr-certificate-details.ts @@ -0,0 +1,49 @@ +import { DynamoDbImage } from "../services/dynamodb-images"; +import { Maybe } from "./optionals"; + +// define AdrCertificateDetails' high-level attributes data types +export interface AdrCertificateDetails { + adrPassCertificateDetails?: AdrPassCertificateDetails; +} + +// define Enums +export type certificateIdEnum = "PASS" | "REPLACEMENT" + +// define AdrCertificateDetails' sub-attributes data types +export type AdrPassCertificateDetails = AdrPassCertificateDetailsItems[]; + +export interface AdrPassCertificateDetailsItems { + createdByName?: string; + certificateType?: string; + generatedTimestamp?: string; + certificateId?: string; + } + +// function to parse AdrCertificateDetails' high-level and sub attributes + return AdrCertificateDetails object +export const parseAdrCertificateDetails = ( + certificateDetails?: DynamoDbImage + ): Maybe => { + if (!certificateDetails) { + return undefined; + } + + const adrPassCertificateDetailsImage: DynamoDbImage = certificateDetails.getList( + "adrPassCertificateDetails" + )!; + const adrPassCertificateDetails: AdrPassCertificateDetails = []; + + for (const key of adrPassCertificateDetailsImage.getKeys()) { + const adrPassCertificateDetailsItemImage = adrPassCertificateDetailsImage.getMap(key)!; + adrPassCertificateDetails.push({ + createdByName: adrPassCertificateDetailsItemImage.getString("createdByName"), + certificateType: adrPassCertificateDetailsItemImage.getString("certificateType"), + generatedTimestamp: adrPassCertificateDetailsItemImage.getString("generatedTimestamp"), + certificateId: adrPassCertificateDetailsItemImage.getString("certificateId") as certificateIdEnum, + }); + } + + + return { + adrPassCertificateDetails + }; +}; \ No newline at end of file From 722ebfdb4b07a892402bb51e75d7eccee431174a Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 26 Jan 2024 16:35:21 +0000 Subject: [PATCH 03/44] adding guidanceNotes Enum --- src/models/adr-details.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index 6ed3593..fcb8480 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -44,6 +44,8 @@ export type compatibilityGroupJEnum = "I" | "E" export type additionalNotesNumberEnum = "1" | "1A" | "2" | "3" | "V1B" | "T1B" +export type additionalNotesguidanceNotesEnum = "New certificate requested" | "M145 Statement" + export type substancesPermittedEnum = "Substances permitted under the tank code and any special provisions specified in 9 may be carried" | "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried" @@ -73,7 +75,7 @@ export interface ApplicantDetails { export interface AdditionalNotes { number?: additionalNotesNumberEnum[]; - // guidanceNotes?: string[]; + guidanceNotes?: additionalNotesguidanceNotesEnum[]; } export interface Tank { @@ -129,9 +131,9 @@ export const parseAdrDetails = ( )!; const additionalNotes: AdditionalNotes = { number: parseStringArray(additionalNotesImage.getList("number")) as additionalNotesNumberEnum[], - // guidanceNotes: parseStringArray( - // additionalNotesImage.getList("guidanceNotes") - // ), + guidanceNotes: parseStringArray( + additionalNotesImage.getList("guidanceNotes") + ) as additionalNotesguidanceNotesEnum[], }; const applicantDetailsImage: DynamoDbImage = adrDetails.getMap( From f373b0a3cf1d60affc1031234565d1706e7cbccb Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 29 Jan 2024 10:36:55 +0000 Subject: [PATCH 04/44] adding m145 attribute as per documentation change --- src/models/adr-details.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index fcb8480..ba1a65d 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -18,6 +18,7 @@ export interface AdrDetails { applicantDetails?: ApplicantDetails; dangerousGoods?: boolean; memosApply?: string[]; + m145?: boolean; additionalNotes?: AdditionalNotes; adrTypeApprovalNo?: string; adrCertificateNotes?: string; @@ -44,7 +45,7 @@ export type compatibilityGroupJEnum = "I" | "E" export type additionalNotesNumberEnum = "1" | "1A" | "2" | "3" | "V1B" | "T1B" -export type additionalNotesguidanceNotesEnum = "New certificate requested" | "M145 Statement" +// export type additionalNotesguidanceNotesEnum = "New certificate requested" | "M145 Statement" export type substancesPermittedEnum = "Substances permitted under the tank code and any special provisions specified in 9 may be carried" | "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried" @@ -75,7 +76,7 @@ export interface ApplicantDetails { export interface AdditionalNotes { number?: additionalNotesNumberEnum[]; - guidanceNotes?: additionalNotesguidanceNotesEnum[]; + // guidanceNotes?: additionalNotesguidanceNotesEnum[]; } export interface Tank { @@ -131,9 +132,9 @@ export const parseAdrDetails = ( )!; const additionalNotes: AdditionalNotes = { number: parseStringArray(additionalNotesImage.getList("number")) as additionalNotesNumberEnum[], - guidanceNotes: parseStringArray( - additionalNotesImage.getList("guidanceNotes") - ) as additionalNotesguidanceNotesEnum[], + // guidanceNotes: parseStringArray( + // additionalNotesImage.getList("guidanceNotes") + // ) as additionalNotesguidanceNotesEnum[], }; const applicantDetailsImage: DynamoDbImage = adrDetails.getMap( @@ -250,6 +251,7 @@ export const parseAdrDetails = ( applicantDetails, dangerousGoods: adrDetails.getBoolean("dangerousGoods"), memosApply: parseStringArray(adrDetails.getList("memosApply")) as memosApplyEnum[], + m145: adrDetails.getBoolean("m145"), additionalNotes, adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo"), adrCertificateNotes: adrDetails.getString("adrCertificateNotes"), From e8eb8275699e98fadf5fe68ddd3d7f7158926cc5 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 1 Feb 2024 16:00:33 +0000 Subject: [PATCH 05/44] feat: adr details added, test resource for technoical record added, unit test added --- src/models/adr-certificate-details.ts | 14 +- src/models/adr-details.ts | 46 +- src/models/tech-record.ts | 7 +- tests/resources/Dockerfile | 2 +- ...amodb-image-technical-record-with-adr.json | 847 ++++++++++++++++++ .../models/tech-record-document.unitTest.ts | 132 ++- tsconfig.json | 2 +- 7 files changed, 1013 insertions(+), 37 deletions(-) create mode 100644 tests/resources/dynamodb-image-technical-record-with-adr.json diff --git a/src/models/adr-certificate-details.ts b/src/models/adr-certificate-details.ts index b3ebca2..f4c8c56 100644 --- a/src/models/adr-certificate-details.ts +++ b/src/models/adr-certificate-details.ts @@ -7,9 +7,9 @@ export interface AdrCertificateDetails { } // define Enums -export type certificateIdEnum = "PASS" | "REPLACEMENT" +export type certificateIdEnum = "PASS" | "REPLACEMENT"; -// define AdrCertificateDetails' sub-attributes data types +// define AdrCertificateDetails' sub-attributes data types export type AdrPassCertificateDetails = AdrPassCertificateDetailsItems[]; export interface AdrPassCertificateDetailsItems { @@ -41,9 +41,7 @@ export const parseAdrCertificateDetails = ( certificateId: adrPassCertificateDetailsItemImage.getString("certificateId") as certificateIdEnum, }); } - - - return { - adrPassCertificateDetails - }; -}; \ No newline at end of file + return { + adrPassCertificateDetails + }; +}; diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index ba1a65d..f9dbde3 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -11,13 +11,13 @@ export interface AdrDetails { brakeDeclarationIssuer?: string; brakeEndurance?: boolean; weight?: number; - compatibilityGroupJ?: string; + compatibilityGroupJ?: compatibilityGroupJEnum; documents?: string[]; - permittedDangerousGoods?: string[]; + permittedDangerousGoods?: permittedDangerousGoodsEnum[]; additionalExaminerNotes?: AdditionalExaminerNotes; applicantDetails?: ApplicantDetails; dangerousGoods?: boolean; - memosApply?: string[]; + memosApply?: memosApplyEnum[]; m145?: boolean; additionalNotes?: AdditionalNotes; adrTypeApprovalNo?: string; @@ -26,33 +26,35 @@ export interface AdrDetails { } // define Enums -export type VehicleDetailsTypeEnum = "Artic tractor" | "Rigid box body" | "Rigid sheeted load" | "Rigid tank" | - "Rigid skeletal" | "Rigid battery" | "Full drawbar box body" | - "Full drawbar sheeted load" | "Full drawbar tank" | "Full drawbar skeletal" | - "Full drawbar battery" | "Centre axle box body" | "Centre axle sheeted load" | - "Centre axle tank" | "Centre axle skeletal" | "Centre axle battery" | - "Semi trailer box body" | "Semi trailer sheeted load" | "Semi trailer tank" | - "Semi trailer skeletal" | "Semi trailer battery Enum" +export type VehicleDetailsTypeEnum = "Artic tractor" | "Rigid box body" | "Rigid sheeted load" | "Rigid tank" | + "Rigid skeletal" | "Rigid battery" | "Full drawbar box body" | + "Full drawbar sheeted load" | "Full drawbar tank" | "Full drawbar skeletal" | + "Full drawbar battery" | "Centre axle box body" | "Centre axle sheeted load" | + "Centre axle tank" | "Centre axle skeletal" | "Centre axle battery" | + "Semi trailer box body" | "Semi trailer sheeted load" | "Semi trailer tank" | + "Semi trailer skeletal" | "Semi trailer battery Enum"; export type Tc2TypeEnum = "initial"; export type Tc3TypeEnum = "intermediate" | "periodic" | "exceptional"; export type permittedDangerousGoodsEnum = "FP <61 (FL)" | "AT" | "Class 5.1 Hydrogen Peroxide (OX)" | "MEMU" | - "Carbon Disulphide" | "Hydrogen" | "Explosives (type 2)" | "Explosives (type 3)" + "Carbon Disulphide" | "Hydrogen" | "Explosives (type 2)" | "Explosives (type 3)"; -export type compatibilityGroupJEnum = "I" | "E" +export type compatibilityGroupJEnum = "I" | "E"; -export type additionalNotesNumberEnum = "1" | "1A" | "2" | "3" | "V1B" | "T1B" +export type additionalNotesNumberEnum = "1" | "1A" | "2" | "3" | "V1B" | "T1B"; // export type additionalNotesguidanceNotesEnum = "New certificate requested" | "M145 Statement" export type substancesPermittedEnum = "Substances permitted under the tank code and any special provisions specified in 9 may be carried" | - "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried" + "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried"; -export type memosApplyEnum = "07/09 3mth leak ext" +export type memosApplyEnum = "07/09 3mth leak ext"; -// define AdrDetails' sub-attributes data types +export type tankStatementSelectEnum = "Statement" | "Product list"; + +// define AdrDetails' sub-attributes data types export interface VehicleDetails { type?: VehicleDetailsTypeEnum; approvalDate?: string; @@ -96,8 +98,8 @@ export interface TankDetails { } export interface TankStatement { - substancesPermitted?: string; - select?: string; + select?: tankStatementSelectEnum; + substancesPermitted?: substancesPermittedEnum; statement?: string; productListRefNo?: string; productListUnNo?: string[]; @@ -119,7 +121,7 @@ export interface Tc3DetailsItem { tc3PeriodicExpiryDate?: string; } -// function to parse AdrDetails' high-level and sub attributes + return AdrDetails object +// function to parse AdrDetails' high-level and sub attributes + return AdrDetails object export const parseAdrDetails = ( adrDetails?: DynamoDbImage ): Maybe => { @@ -203,7 +205,7 @@ export const parseAdrDetails = ( const tankStatementImage: DynamoDbImage = tankImage.getMap("tankStatement")!; const tankStatement: TankStatement = { substancesPermitted: tankStatementImage.getString("substancesPermitted") as substancesPermittedEnum, - select: tankStatementImage.getString("select"), + select: tankStatementImage.getString("select") as tankStatementSelectEnum, statement: tankStatementImage.getString("statement"), productListRefNo: tankStatementImage.getString("productListRefNo"), productListUnNo: parseStringArray( @@ -230,7 +232,7 @@ export const parseAdrDetails = ( createdAtDate: additionalExaminerNotesItemImage.getString("createdAtDate"), lastUpdatedBy: additionalExaminerNotesItemImage.getString("lastUpdatedBy"), }); - }; + } return { @@ -247,7 +249,7 @@ export const parseAdrDetails = ( permittedDangerousGoods: parseStringArray( adrDetails.getList("permittedDangerousGoods") ) as permittedDangerousGoodsEnum[], - additionalExaminerNotes: additionalExaminerNotes, + additionalExaminerNotes, applicantDetails, dangerousGoods: adrDetails.getBoolean("dangerousGoods"), memosApply: parseStringArray(adrDetails.getList("memosApply")) as memosApplyEnum[], diff --git a/src/models/tech-record.ts b/src/models/tech-record.ts index 29aa1c0..063b73f 100644 --- a/src/models/tech-record.ts +++ b/src/models/tech-record.ts @@ -14,7 +14,8 @@ import { Microfilm, parseMicrofilm } from "./microfilm"; import { parsePlates, Plates } from "./plates"; import { BodyType, parseBodyType } from "./body-type"; import { Dimensions, parseDimensions } from "./dimensions"; -import { AdrDetails } from "./adr-details"; +import { AdrDetails, parseAdrDetails } from "./adr-details"; +import { AdrCertificateDetails, parseAdrCertificateDetails } from "./adr-certificate-details"; import { parseVehicleClass, VehicleClass } from "./vehicle-class"; import { Brakes, parseBrakes } from "./brakes"; import { Axles, parseAxles } from "./axles"; @@ -114,6 +115,7 @@ export interface TechRecord { noOfAxles?: number; brakeCode?: string; adrDetails?: AdrDetails; + adrCertificateDetails?: AdrCertificateDetails; createdByName?: string; createdById?: string; lastUpdatedByName?: string; @@ -270,7 +272,8 @@ const parseTechRecord = (image: DynamoDbImage): TechRecord => { notes: image.getString("notes"), noOfAxles: image.getNumber("noOfAxles"), brakeCode: image.getString("brakeCode"), - adrDetails: undefined, // intentional - not implemented. parseAdrDetails(image.getMap("adrDetails")) + adrDetails: parseAdrDetails(image.getMap("adrDetails")), + adrCertificateDetails: parseAdrCertificateDetails(image.getMap("certificateDetails")), createdByName: image.getString("createdByName"), createdById: image.getString("createdById"), lastUpdatedByName: image.getString("lastUpdatedByName"), diff --git a/tests/resources/Dockerfile b/tests/resources/Dockerfile index b6d6a32..25ca559 100644 --- a/tests/resources/Dockerfile +++ b/tests/resources/Dockerfile @@ -1,5 +1,5 @@ # Match Aurora MySQL version as closely as possible -FROM mysql:5.7.12 +FROM mysql:8.2.0 ENV MYSQL_DATABASE=CVSBNOP \ MYSQL_ROOT_PASSWORD=12345 diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json new file mode 100644 index 0000000..48dceaf --- /dev/null +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -0,0 +1,847 @@ +{ + "systemNumber": { + "S": "SYSTEM-NUMBER-1" + }, + "partialVin": { + "S": "PARTIAL-VIN" + }, + "primaryVrm": { + "S": "VRM-1" + }, + "secondaryVrms": { + "L": [ + { + "S": "SECONDARY-VRM" + } + ] + }, + "vin": { + "S": "VIN-1" + }, + "trailerId": { + "S": "TRL-1" + }, + "techRecord": { + "L": [ + { + "M": { + "adrDetails": { + "M": { + "additionalExaminerNotes": { + "L": [ + { + "M": { + "note": { + "S": "additionalExaminerNotes_note_1" + }, + "createdAtDate": { + "S": "2023-05-30" + }, + "lastUpdatedBy": { + "S": "additionalExaminerNotes_lastUpdatedBy_1" + } + } + } + ] + }, + "additionalNotes": { + "M": { + "number": { + "L": [ + {"S": "1"}, + {"S": "T1B"} + ] + } + } + }, + "adrCertificateNotes": { + "S": "adrCertificateNotes_1" + }, + "adrTypeApprovalNo": { + "S": "adrTypeApprovalNo_1" + }, + "applicantDetails": { + "M": { + "name": { + "S": "adrDetails_applicantDetails_name_1" + }, + "street": { + "S": "adrDetails_applicantDetails_street_1" + }, + "town": { + "S": "adrDetails_applicantDetails_town_1" + }, + "city": { + "S": "adrDetails_applicantDetails_city_1" + }, + "postcode": { + "S": "adrDetails_applicantDetails_postcode_1" + } + } + }, + "batteryListNumber": { + "S": "batteryListNumber_1" + }, + "brakeDeclarationIssuer": { + "S": "brakeDeclarationIssuer_1" + }, + "brakeDeclarationsSeen": { + "BOOL": true + }, + "brakeEndurance": { + "BOOL": false + }, + "compatibilityGroupJ": { + "S": "I" + }, + "dangerousGoods": { + "BOOL": false + }, + "declarationsSeen": { + "BOOL": false + }, + "documents": { + "L": [ + { + "S": "documents_1" + }, + { + "S": "documents_2" + }, + { + "S": "documents_3" + } + ] + }, + "listStatementApplicable": { + "BOOL": true + }, + "m145": { + "BOOL": true + }, + "memosApply": { + "L": [ + { + "S": "07/09 3mth leak ext" + } + ] + }, + "permittedDangerousGoods": { + "L": [ + { + "S": "FP <61 (FL)" + }, + { + "S": "Carbon Disulphide" + }, + { + "S": "Hydrogen" + } + ] + }, + "tank": { + "M": { + "tankDetails": { + "M": { + "tankManufacturer": { + "S": "tankManufacturer_1" + }, + "yearOfManufacture": { + "N": "1234" + }, + "tankCode": { + "S": "tankCode_1" + }, + "specialProvisions": { + "S": "specialProvisions_1" + }, + "tankManufacturerSerialNo": { + "S": "1234" + }, + "tankTypeAppNo": { + "S": "9876" + }, + "tc2Details": { + "M": { + "tc2Type": { + "S": "initial" + }, + "tc2IntermediateApprovalNo": { + "S": "12345" + }, + "tc2IntermediateExpiryDate": { + "S": "2024-06-01" + } + } + }, + "tc3Details": { + "L": [ + { + "M": { + "tc3Type": { + "S": "intermediate" + }, + "tc3PeriodicNumber": { + "S": "98765" + }, + "tc3PeriodicExpiryDate": { + "S": "2024-06-01" + } + } + } + ] + } + } + }, + "tankStatement": { + "M": { + "select":{ + "S": "Product list" + }, + "substancesPermitted": { + "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" + }, + "statement": { + "S": "statement_1" + }, + "productListRefNo": { + "S": "123456" + }, + "productListUnNo": { + "L": [ + { + "S": "123123" + }, + { + "S": "987987" + }, + { + "S": "135790" + } + ] + }, + "productList": { + "S": "productList_1" + } + } + } + } + }, + "vehicleDetails": { + "M": { + "type": { + "S": "Artic tractor" + }, + "approvalDate": { + "S": "2023-06-12" + } + } + }, + "weight": { + "N": "6789" + } + } + }, + "recordCompleteness": { + "S": "88888888" + }, + "createdAt": { + "S": "2020-01-01T00:00:00.055Z" + }, + "lastUpdatedAt": { + "S": "2020-01-01T00:00:00.000000Z" + }, + "make": { + "S": "MAKE" + }, + "model": { + "S": "MODEL" + }, + "functionCode": { + "S": "1" + }, + "fuelPropulsionSystem": { + "S": "DieselPetrol" + }, + "offRoad": { + "BOOL": true + }, + "numberOfWheelsDriven": { + "N": "1" + }, + "euVehicleCategory": { + "S": "m1" + }, + "emissionsLimit": { + "N": "1" + }, + "departmentalVehicleMarker": { + "BOOL": true + }, + "authIntoService": { + "M": { + "cocIssueDate": { + "S": "2020-01-01" + }, + "dateAuthorised": { + "S": "2020-02-02" + }, + "datePending": { + "S": "2020-03-03" + }, + "dateReceived": { + "S": "2020-04-04" + }, + "dateRejected": { + "S": "2020-05-05" + } + } + }, + "lettersOfAuth": { + "M": { + "letterType": { + "S": "Trailer authorization" + }, + "letterDateRequested": { + "S": "2020-01-01" + }, + "letterContents": { + "S": "LETTER-CONTENTS" + } + } + }, + "alterationMarker": { + "BOOL": true + }, + "approvalType": { + "S": "NTA" + }, + "approvalTypeNumber": { + "S": "1" + }, + "variantNumber": { + "S": "1" + }, + "variantVersionNumber": { + "S": "1" + }, + "grossEecWeight": { + "N": "1" + }, + "trainEecWeight": { + "N": "1" + }, + "maxTrainEecWeight": { + "N": "1" + }, + "applicantDetails": { + "M": { + "name": { + "S": "NAME" + }, + "address1": { + "S": "ADDRESS-1" + }, + "address2": { + "S": "ADDRESS-2" + }, + "postTown": { + "S": "POST-TOWN" + }, + "address3": { + "S": "ADDRESS-3" + }, + "postCode": { + "S": "POST-CODE" + }, + "emailAddress": { + "S": "EMAIL-ADDRESS" + }, + "telephoneNumber": { + "S": "TELEPHONE-NUMBER" + } + } + }, + "purchaserDetails": { + "M": { + "name": { + "S": "NAME" + }, + "address1": { + "S": "ADDRESS-1" + }, + "address2": { + "S": "ADDRESS-2" + }, + "postTown": { + "S": "POST-TOWN" + }, + "address3": { + "S": "ADDRESS-3" + }, + "postCode": { + "S": "POST-CODE" + }, + "emailAddress": { + "S": "EMAIL-ADDRESS" + }, + "telephoneNumber": { + "S": "TELEPHONE-NUMBER" + }, + "faxNumber": { + "S": "FAX-NUMBER" + }, + "purchaserNotes": { + "S": "PURCHASER-NOTES" + } + } + }, + "manufacturerDetails": { + "M": { + "name": { + "S": "NAME" + }, + "address1": { + "S": "ADDRESS-1" + }, + "address2": { + "S": "ADDRESS-2" + }, + "postTown": { + "S": "POST-TOWN" + }, + "address3": { + "S": "ADDRESS-3" + }, + "postCode": { + "S": "POST-CODE" + }, + "emailAddress": { + "S": "EMAIL-ADDRESS" + }, + "telephoneNumber": { + "S": "TELEPHONE-NUMBER" + }, + "faxNumber": { + "S": "FAX-NUMBER" + }, + "manufacturerNotes": { + "S": "MANUFACTURER-NOTES" + } + } + }, + "microfilm": { + "M": { + "microfilmDocumentType": { + "S": "PSV Miscellaneous" + }, + "microfilmRollNumber": { + "S": "1" + }, + "microfilmSerialNumber": { + "S": "1" + } + } + }, + "plates": { + "L": [ + { + "M": { + "plateSerialNumber": { + "S": "1" + }, + "plateIssueDate": { + "S": "2020-01-01" + }, + "plateReasonForIssue": { + "S": "Free replacement" + }, + "plateIssuer": { + "S": "PLATE-ISSUER" + }, + "toEmailAddress": { + "S": "TO-EMAIL-ADDRESS" + } + } + } + ] + }, + "chassisMake": { + "S": "CHASSIS-MAKE" + }, + "chassisModel": { + "S": "CHASSIS-MODEL" + }, + "bodyMake": { + "S": "BODY-MAKE" + }, + "bodyModel": { + "S": "BODY-MODEL" + }, + "modelLiteral": { + "S": "MODEL-LITERAL" + }, + "bodyType": { + "M": { + "code": { + "S": "a" + }, + "description": { + "S": "articulated" + } + } + }, + "manufactureYear": { + "N": "2020" + }, + "regnDate": { + "S": "2020-01-01" + }, + "firstUseDate": { + "S": "2020-01-01" + }, + "coifDate": { + "S": "2020-01-01" + }, + "ntaNumber": { + "S": "NTA-NUMBER" + }, + "coifSerialNumber": { + "S": "88888888" + }, + "coifCertifierName": { + "S": "COIF-CERTIFIER-NAME" + }, + "conversionRefNo": { + "S": "1010101010" + }, + "seatsLowerDeck": { + "N": "1" + }, + "seatsUpperDeck": { + "N": "1" + }, + "standingCapacity": { + "N": "1" + }, + "speedRestriction": { + "N": "1" + }, + "speedLimiterMrk": { + "BOOL": true + }, + "tachoExemptMrk": { + "BOOL": true + }, + "dispensations": { + "S": "DISPENSATIONS" + }, + "remarks": { + "S": "REMARKS" + }, + "reasonForCreation": { + "S": "REASON-FOR-CREATION" + }, + "statusCode": { + "S": "STATUS-CODE" + }, + "unladenWeight": { + "N": "1" + }, + "grossKerbWeight": { + "N": "1" + }, + "grossLadenWeight": { + "N": "1" + }, + "grossGbWeight": { + "N": "1" + }, + "grossDesignWeight": { + "N": "1" + }, + "trainGbWeight": { + "N": "1" + }, + "trainDesignWeight": { + "N": "1" + }, + "maxTrainGbWeight": { + "N": "1" + }, + "maxTrainDesignWeight": { + "N": "1" + }, + "maxLoadOnCoupling": { + "N": "1" + }, + "frameDescription": { + "S": "Channel section" + }, + "tyreUseCode": { + "S": "22" + }, + "roadFriendly": { + "BOOL": true + }, + "drawbarCouplingFitted": { + "BOOL": true + }, + "euroStandard": { + "S": "euroStd" + }, + "suspensionType": { + "S": "1" + }, + "couplingType": { + "S": "1" + }, + "dimensions": { + "M": { + "axleSpacing": { + "L": [ + { + "M": { + "axles": { + "S": "1-2" + }, + "value": { + "N": "1" + } + } + } + ] + }, + "length": { + "N": "1" + }, + "height": { + "N": "1" + }, + "width": { + "N": "1" + } + } + }, + "frontAxleTo5thWheelMin": { + "N": "1" + }, + "frontAxleTo5thWheelMax": { + "N": "1" + }, + "frontVehicleTo5thWheelCouplingMin": { + "N": "1" + }, + "frontVehicleTo5thWheelCouplingMax": { + "N": "1" + }, + "frontAxleToRearAxle": { + "N": "1" + }, + "rearAxleToRearTrl": { + "N": "1" + }, + "couplingCenterToRearAxleMin": { + "N": "1" + }, + "couplingCenterToRearAxleMax": { + "N": "1" + }, + "couplingCenterToRearTrlMin": { + "N": "1" + }, + "couplingCenterToRearTrlMax": { + "N": "1" + }, + "centreOfRearmostAxleToRearOfTrl": { + "N": "1" + }, + "notes": { + "S": "NOTES" + }, + "noOfAxles": { + "N": "1" + }, + "brakeCode": { + "S": "1" + }, + "createdByName": { + "S": "CREATED-BY-NAME-2" + }, + "createdById": { + "S": "CREATED-BY-ID-2" + }, + "lastUpdatedByName": { + "S": "LAST-UPDATED-BY-NAME-2" + }, + "lastUpdatedById": { + "S": "LAST-UPDATED-BY-ID-2" + }, + "updateType": { + "S": "adrUpdate" + }, + "vehicleClass": { + "M": { + "code": { + "S": "2" + }, + "description": { + "S": "motorbikes over 200cc or with a sidecar" + } + } + }, + "vehicleSubclass": { + "L": [ + { + "S": "1" + } + ] + }, + "vehicleType": { + "S": "psv" + }, + "vehicleSize": { + "S": "small" + }, + "numberOfSeatbelts": { + "S": "NUMBER-OF-SEATBELTS" + }, + "seatbeltInstallationApprovalDate": { + "S": "2020-01-01" + }, + "vehicleConfiguration": { + "S": "rigid" + }, + "brakes": { + "M": { + "brakeCodeOriginal": { + "S": "333" + }, + "brakeCode": { + "S": "666666" + }, + "dataTrBrakeOne": { + "S": "DATA-TR-BRAKE-ONE" + }, + "dataTrBrakeTwo": { + "S": "DATA-TR-BRAKE-TWO" + }, + "dataTrBrakeThree": { + "S": "DATA-TR-BRAKE-THREE" + }, + "retarderBrakeOne": { + "S": "electric" + }, + "retarderBrakeTwo": { + "S": "electric" + }, + "dtpNumber": { + "S": "666666" + }, + "brakeForceWheelsNotLocked": { + "M": { + "serviceBrakeForceA": { + "N": "1" + }, + "secondaryBrakeForceA": { + "N": "1" + }, + "parkingBrakeForceA": { + "N": "1" + } + } + }, + "brakeForceWheelsUpToHalfLocked": { + "M": { + "serviceBrakeForceB": { + "N": "1" + }, + "secondaryBrakeForceB": { + "N": "1" + }, + "parkingBrakeForceB": { + "N": "1" + } + } + }, + "loadSensingValve": { + "BOOL": true + }, + "antilockBrakingSystem": { + "BOOL": true + } + } + }, + "axles": { + "L": [ + { + "M": { + "axleNumber": { + "N": "1" + }, + "parkingBrakeMrk": { + "BOOL": true + }, + "weights": { + "M": { + "kerbWeight": { + "N": "1" + }, + "ladenWeight": { + "N": "1" + }, + "gbWeight": { + "N": "1" + }, + "eecWeight": { + "N": "1" + }, + "designWeight": { + "N": "1" + } + } + }, + "tyres": { + "M": { + "tyreSize": { + "S": "TYRE-SIZE" + }, + "plyRating": { + "S": "22" + }, + "fitmentCode": { + "S": "double" + }, + "dataTrAxles": { + "N": "1" + }, + "speedCategorySymbol": { + "S": "a7" + }, + "tyreCode": { + "N": "1" + } + } + }, + "brakes": { + "M": { + "brakeActuator": { + "N": "1" + }, + "leverLength": { + "N": "1" + }, + "springBrakeParking": { + "BOOL": true + } + } + } + } + } + ] + } + } + } + ] + } +} diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index c6db6fd..526a491 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -3,11 +3,11 @@ import { TechRecordDocument, } from "../../../src/models/tech-record-document"; import { DynamoDbImage } from "../../../src/services/dynamodb-images"; -import { default as techRecordDocumentJson } from "../../resources/dynamodb-image-technical-record.json"; +import { default as techRecordDocumentJson } from "../../resources/dynamodb-image-technical-record-with-adr.json"; import { castToImageShape } from "../../utils"; describe("parseTechRecordDocument()", () => { - it("should successfully parse a DynamoDB image into a TechRecordDocument", () => { + it("should successfully parse a DynamoDB image with ADR into a TechRecordDocument", () => { const image = DynamoDbImage.parse(castToImageShape(techRecordDocumentJson)); const techRecordDocument: TechRecordDocument = parseTechRecordDocument( @@ -52,9 +52,72 @@ describe("parseTechRecordDocument()", () => { "333" ); expect(techRecordDocument.techRecord![0].axles![0].axleNumber).toEqual(1); + + // ADR Details attributes + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].note).toEqual("additionalExaminerNotes_note_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].createdAtDate).toEqual("2023-05-30"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].lastUpdatedBy).toEqual("additionalExaminerNotes_lastUpdatedBy_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![0]).toEqual("1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![1]).toEqual("T1B"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrCertificateNotes).toEqual("adrCertificateNotes_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails!.name).toEqual("adrDetails_applicantDetails_name_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("batteryListNumber_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationsSeen).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeEndurance).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.compatibilityGroupJ).toEqual("I"); + expect(techRecordDocument.techRecord![0].adrDetails?.dangerousGoods).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.declarationsSeen).toEqual(false); + + expect(techRecordDocument.techRecord![0].adrDetails?.documents![0]).toEqual("documents_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.documents![1]).toEqual("documents_2"); + + expect(techRecordDocument.techRecord![0].adrDetails?.listStatementApplicable).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.m145).toEqual(true); + + expect(techRecordDocument.techRecord![0].adrDetails?.memosApply![0]).toEqual("07/09 3mth leak ext"); + + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![0]).toEqual("FP <61 (FL)"); + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturer).toEqual("tankManufacturer_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.yearOfManufacture).toEqual(1234); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankCode).toEqual("tankCode_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.specialProvisions).toEqual("specialProvisions_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturerSerialNo).toEqual("1234"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankTypeAppNo).toEqual("9876"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2Type).toEqual("initial"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateApprovalNo).toEqual("12345"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3Type).toEqual("intermediate"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productList).toEqual("productList_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![1]).toEqual("987987"); + + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.type).toEqual("Artic tractor"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.approvalDate).toEqual("2023-06-12"); + + expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(6789); + }); - it("should successfully parse a DynamoDB image, with no authIntoService, into a TechRecordDocument", () => { + it("should successfully parse a DynamoDB image, with ADR, with no authIntoService, into a TechRecordDocument", () => { // @ts-ignore delete techRecordDocumentJson.techRecord.L[0].M.authIntoService; const image = DynamoDbImage.parse(castToImageShape(techRecordDocumentJson)); @@ -99,5 +162,68 @@ describe("parseTechRecordDocument()", () => { "333" ); expect(techRecordDocument.techRecord![0].axles![0].axleNumber).toEqual(1); + + // ADR Details attributes + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].note).toEqual("additionalExaminerNotes_note_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].createdAtDate).toEqual("2023-05-30"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].lastUpdatedBy).toEqual("additionalExaminerNotes_lastUpdatedBy_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![0]).toEqual("1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![1]).toEqual("T1B"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrCertificateNotes).toEqual("adrCertificateNotes_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails!.name).toEqual("adrDetails_applicantDetails_name_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("batteryListNumber_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationsSeen).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeEndurance).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.compatibilityGroupJ).toEqual("I"); + expect(techRecordDocument.techRecord![0].adrDetails?.dangerousGoods).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.declarationsSeen).toEqual(false); + + expect(techRecordDocument.techRecord![0].adrDetails?.documents![0]).toEqual("documents_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.documents![1]).toEqual("documents_2"); + + expect(techRecordDocument.techRecord![0].adrDetails?.listStatementApplicable).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.m145).toEqual(true); + + expect(techRecordDocument.techRecord![0].adrDetails?.memosApply![0]).toEqual("07/09 3mth leak ext"); + + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![0]).toEqual("FP <61 (FL)"); + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturer).toEqual("tankManufacturer_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.yearOfManufacture).toEqual(1234); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankCode).toEqual("tankCode_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.specialProvisions).toEqual("specialProvisions_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturerSerialNo).toEqual("1234"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankTypeAppNo).toEqual("9876"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2Type).toEqual("initial"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateApprovalNo).toEqual("12345"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3Type).toEqual("intermediate"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productList).toEqual("productList_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![1]).toEqual("987987"); + + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.type).toEqual("Artic tractor"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.approvalDate).toEqual("2023-06-12"); + + expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(6789); + }); }); diff --git a/tsconfig.json b/tsconfig.json index cf02692..b5af863 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,6 @@ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, - "types": [] + "types": ["jest", "node"] } } From a5488b48ba9f8575944aeb0fbfe6a3d4557188ca Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 2 Feb 2024 10:07:31 +0000 Subject: [PATCH 06/44] style: rearrange enums --- src/models/adr-certificate-details.ts | 4 +- src/models/adr-details.ts | 72 ++++++++++++++++++++------- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/models/adr-certificate-details.ts b/src/models/adr-certificate-details.ts index f4c8c56..bad6f37 100644 --- a/src/models/adr-certificate-details.ts +++ b/src/models/adr-certificate-details.ts @@ -7,7 +7,9 @@ export interface AdrCertificateDetails { } // define Enums -export type certificateIdEnum = "PASS" | "REPLACEMENT"; +export type certificateIdEnum = + | "PASS" + | "REPLACEMENT"; // define AdrCertificateDetails' sub-attributes data types export type AdrPassCertificateDetails = AdrPassCertificateDetailsItems[]; diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index f9dbde3..aca0ecf 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -26,33 +26,69 @@ export interface AdrDetails { } // define Enums -export type VehicleDetailsTypeEnum = "Artic tractor" | "Rigid box body" | "Rigid sheeted load" | "Rigid tank" | - "Rigid skeletal" | "Rigid battery" | "Full drawbar box body" | - "Full drawbar sheeted load" | "Full drawbar tank" | "Full drawbar skeletal" | - "Full drawbar battery" | "Centre axle box body" | "Centre axle sheeted load" | - "Centre axle tank" | "Centre axle skeletal" | "Centre axle battery" | - "Semi trailer box body" | "Semi trailer sheeted load" | "Semi trailer tank" | - "Semi trailer skeletal" | "Semi trailer battery Enum"; +export type VehicleDetailsTypeEnum = + | "Artic tractor" + | "Rigid box body" + | "Rigid sheeted load" + | "Rigid tank" + | "Rigid skeletal" + | "Rigid battery" + | "Full drawbar box body" + | "Full drawbar sheeted load" + | "Full drawbar tank" + | "Full drawbar skeletal" + | "Full drawbar battery" + | "Centre axle box body" + | "Centre axle sheeted load" + | "Centre axle tank" + | "Centre axle skeletal" + | "Centre axle battery" + | "Semi trailer box body" + | "Semi trailer sheeted load" + | "Semi trailer tank" + | "Semi trailer skeletal" + | "Semi trailer battery Enum"; export type Tc2TypeEnum = "initial"; -export type Tc3TypeEnum = "intermediate" | "periodic" | "exceptional"; - -export type permittedDangerousGoodsEnum = "FP <61 (FL)" | "AT" | "Class 5.1 Hydrogen Peroxide (OX)" | "MEMU" | - "Carbon Disulphide" | "Hydrogen" | "Explosives (type 2)" | "Explosives (type 3)"; - -export type compatibilityGroupJEnum = "I" | "E"; - -export type additionalNotesNumberEnum = "1" | "1A" | "2" | "3" | "V1B" | "T1B"; +export type Tc3TypeEnum = + | "intermediate" + | "periodic" + | "exceptional"; + +export type permittedDangerousGoodsEnum = + | "FP <61 (FL)" + | "AT" + | "Class 5.1 Hydrogen Peroxide (OX)" + | "MEMU" + | "Carbon Disulphide" + | "Hydrogen" + | "Explosives (type 2)" + | "Explosives (type 3)"; + +export type compatibilityGroupJEnum = + | "I" + | "E"; + +export type additionalNotesNumberEnum = + | "1" + | "1A" + | "2" + | "3" + | "V1B" + | "T1B"; // export type additionalNotesguidanceNotesEnum = "New certificate requested" | "M145 Statement" -export type substancesPermittedEnum = "Substances permitted under the tank code and any special provisions specified in 9 may be carried" | - "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried"; +export type substancesPermittedEnum = + | "Substances permitted under the tank code and any special provisions specified in 9 may be carried" + | "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried"; export type memosApplyEnum = "07/09 3mth leak ext"; -export type tankStatementSelectEnum = "Statement" | "Product list"; +export type tankStatementSelectEnum = + | "Statement" + | "Product list"; // define AdrDetails' sub-attributes data types export interface VehicleDetails { From e456415952da1a3167ec0ed5a1bd105acf05077d Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 2 Feb 2024 10:09:02 +0000 Subject: [PATCH 07/44] fix: replace ! with ? for optional attributes --- .../models/tech-record-document.unitTest.ts | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index 526a491..f15b332 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -65,7 +65,7 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails!.name).toEqual("adrDetails_applicantDetails_name_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("adrDetails_applicantDetails_name_1"); expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("batteryListNumber_1"); expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); @@ -87,31 +87,31 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![0]).toEqual("FP <61 (FL)"); expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturer).toEqual("tankManufacturer_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.yearOfManufacture).toEqual(1234); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankCode).toEqual("tankCode_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.specialProvisions).toEqual("specialProvisions_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturerSerialNo).toEqual("1234"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankTypeAppNo).toEqual("9876"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturer).toEqual("tankManufacturer_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(1234); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankCode).toEqual("tankCode_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.specialProvisions).toEqual("specialProvisions_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturerSerialNo).toEqual("1234"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankTypeAppNo).toEqual("9876"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2Type).toEqual("initial"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateApprovalNo).toEqual("12345"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateExpiryDate).toEqual("2024-06-01"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2Type).toEqual("initial"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateApprovalNo).toEqual("12345"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3Type).toEqual("intermediate"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3Type).toEqual("intermediate"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.select).toEqual("Product list"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.statement).toEqual("statement_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListRefNo).toEqual("123456"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productList).toEqual("productList_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![0]).toEqual("123123"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![1]).toEqual("987987"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); - expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.type).toEqual("Artic tractor"); - expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.approvalDate).toEqual("2023-06-12"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(6789); @@ -175,7 +175,7 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails!.name).toEqual("adrDetails_applicantDetails_name_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("adrDetails_applicantDetails_name_1"); expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("batteryListNumber_1"); expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); @@ -197,31 +197,31 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![0]).toEqual("FP <61 (FL)"); expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturer).toEqual("tankManufacturer_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.yearOfManufacture).toEqual(1234); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankCode).toEqual("tankCode_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.specialProvisions).toEqual("specialProvisions_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankManufacturerSerialNo).toEqual("1234"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tankTypeAppNo).toEqual("9876"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturer).toEqual("tankManufacturer_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(1234); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankCode).toEqual("tankCode_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.specialProvisions).toEqual("specialProvisions_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturerSerialNo).toEqual("1234"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankTypeAppNo).toEqual("9876"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2Type).toEqual("initial"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateApprovalNo).toEqual("12345"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc2Details!.tc2IntermediateExpiryDate).toEqual("2024-06-01"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2Type).toEqual("initial"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateApprovalNo).toEqual("12345"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3Type).toEqual("intermediate"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankDetails!.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3Type).toEqual("intermediate"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.select).toEqual("Product list"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.statement).toEqual("statement_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListRefNo).toEqual("123456"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productList).toEqual("productList_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![0]).toEqual("123123"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank!.tankStatement!.productListUnNo![1]).toEqual("987987"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); - expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.type).toEqual("Artic tractor"); - expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails!.approvalDate).toEqual("2023-06-12"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(6789); From c9025ce900993a8eb422d0adeda83da7ee85916a Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 2 Feb 2024 11:11:29 +0000 Subject: [PATCH 08/44] fix: memosApplyEnum value updated --- src/models/adr-details.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index aca0ecf..8f25de8 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -84,7 +84,7 @@ export type substancesPermittedEnum = | "Substances permitted under the tank code and any special provisions specified in 9 may be carried" | "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried"; -export type memosApplyEnum = "07/09 3mth leak ext"; +export type memosApplyEnum = "07/09 3mth leak ext "; export type tankStatementSelectEnum = | "Statement" From 43ed027a0b3861b704daad5f5f8c606a48314a70 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 2 Feb 2024 11:54:43 +0000 Subject: [PATCH 09/44] fix: 2 new attributes added to adrDetails, as per documentation --- src/models/adr-details.ts | 6 ++++-- .../resources/dynamodb-image-technical-record-with-adr.json | 6 +++++- tests/unit/models/tech-record-document.unitTest.ts | 6 ++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index 8f25de8..d685a91 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -11,6 +11,7 @@ export interface AdrDetails { brakeDeclarationIssuer?: string; brakeEndurance?: boolean; weight?: number; + newCertificateRequested?: boolean; compatibilityGroupJ?: compatibilityGroupJEnum; documents?: string[]; permittedDangerousGoods?: permittedDangerousGoodsEnum[]; @@ -18,7 +19,7 @@ export interface AdrDetails { applicantDetails?: ApplicantDetails; dangerousGoods?: boolean; memosApply?: memosApplyEnum[]; - m145?: boolean; + m145Statement?: boolean; additionalNotes?: AdditionalNotes; adrTypeApprovalNo?: string; adrCertificateNotes?: string; @@ -280,6 +281,7 @@ export const parseAdrDetails = ( brakeDeclarationIssuer: adrDetails.getString("brakeDeclarationIssuer"), brakeEndurance: adrDetails.getBoolean("brakeEndurance"), weight: adrDetails.getNumber("weight"), + newCertificateRequested: adrDetails.getBoolean("newCertificateRequested"), compatibilityGroupJ: adrDetails.getString("compatibilityGroupJ") as compatibilityGroupJEnum, documents: parseStringArray(adrDetails.getList("documents")), permittedDangerousGoods: parseStringArray( @@ -289,7 +291,7 @@ export const parseAdrDetails = ( applicantDetails, dangerousGoods: adrDetails.getBoolean("dangerousGoods"), memosApply: parseStringArray(adrDetails.getList("memosApply")) as memosApplyEnum[], - m145: adrDetails.getBoolean("m145"), + m145Statement: adrDetails.getBoolean("m145Statement"), additionalNotes, adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo"), adrCertificateNotes: adrDetails.getString("adrCertificateNotes"), diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json index 48dceaf..f1dcf71 100644 --- a/tests/resources/dynamodb-image-technical-record-with-adr.json +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -116,9 +116,13 @@ "listStatementApplicable": { "BOOL": true }, - "m145": { + "m145Statement": { "BOOL": true }, + "newCertificateRequested": { + "BOOL": false + }, + "memosApply": { "L": [ { diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index f15b332..d610b88 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -80,7 +80,8 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.documents![1]).toEqual("documents_2"); expect(techRecordDocument.techRecord![0].adrDetails?.listStatementApplicable).toEqual(true); - expect(techRecordDocument.techRecord![0].adrDetails?.m145).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.m145Statement).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.newCertificateRequested).toEqual(false); expect(techRecordDocument.techRecord![0].adrDetails?.memosApply![0]).toEqual("07/09 3mth leak ext"); @@ -190,7 +191,8 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.documents![1]).toEqual("documents_2"); expect(techRecordDocument.techRecord![0].adrDetails?.listStatementApplicable).toEqual(true); - expect(techRecordDocument.techRecord![0].adrDetails?.m145).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.m145Statement).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.newCertificateRequested).toEqual(false); expect(techRecordDocument.techRecord![0].adrDetails?.memosApply![0]).toEqual("07/09 3mth leak ext"); From d15b265ef5aaa9a32803b125cee65a345fba6d2e Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 2 Feb 2024 15:30:10 +0000 Subject: [PATCH 10/44] feat: tab le definition --- src/services/table-details.ts | 99 +++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/src/services/table-details.ts b/src/services/table-details.ts index c97e615..8a0b995 100644 --- a/src/services/table-details.ts +++ b/src/services/table-details.ts @@ -364,6 +364,95 @@ export const TEST_RESULT_TABLE: TableDetails = { ], }; +export const ADR_ADDITIONAL_EXAMINER_NOTES_TABLE: TableDetails = { + tableName: "adr_additional_examiner_notes", + columnNames: ["adr_details_id", "note", "createdAtDate", "lastUpdatedBy"], +}; + +export const ADR_ADDITIONAL_NOTES_GUIDANCE_TABLE: TableDetails = { + tableName: "adr_additional_notes_guidance", + columnNames: ["guidanceNotes", "adr_details_id"], +}; + +export const ADR_ADDITIONAL_NOTES_NUMBER_TABLE: TableDetails = { + tableName: "adr_additional_notes_number", + columnNames: ["number", "adr_details_id"], +}; + +export const ADR_DANGEROUS_GOODS_LIST_TABLE: TableDetails = { + tableName: "adr_dangerous_goods_list", + columnNames: ["name"], +}; + +export const ADR_DETAILS_TABLE: TableDetails = { + tableName: "adr_details", + columnNames: [ + "technical_record_id", + "type", + "approvalDate", + "listStatementApplicable", + "batteryListNumber", + "declarationsSeen", + "brakeDeclarationsSeen", + "brakeDeclarationIssuer", + "brakeEndurance", + "weight", + "compatibilityGroupJ", + "additionalExaminerNotes", + "applicantDetailsName", + "street", + "town", + "city", + "postcode", + "memosApply", + "adrTypeApprovalNo", + "adrCertificateNotes", + "tankManufacturer", + "yearOfManufacture", + "tankCode", + "specialProvisions", + "tankManufacturerSerialNo", + "tankTypeAppNo", + "tc2Type", + "tc2IntermediateApprovalNo", + "tc2IntermediateExpiryDate", + "substancesPermitted", + "statement", + "productListRefNo", + "productList", + ], +}; + +export const ADR_MEMOS_APPLY_TABLE: TableDetails = { + tableName: "adr_memos_apply", + columnNames: ["adr_details_id", "memo"], +}; + +export const ADR_PERMITTED_DANGEROUS_GOODS_TABLE: TableDetails = { + tableName: "adr_permitted_dangerous_goods", + columnNames: ["adr_details_id", "dangerous_goods_id"], +}; + +export const ADR_PRODUCTLISTUNNO_LIST_TABLE: TableDetails = { + tableName: "adr_productListUnNo_list", + columnNames: ["name"], +}; + +export const ADR_PRODUCTLISTUNNO_TABLE: TableDetails = { + tableName: "adr_productListUnNo", + columnNames: ["adr_details_id", "productListUnNo_id"], +}; + +export const ADR_TC3DETAILS_TABLE: TableDetails = { + tableName: "adr_tc3Details", + columnNames: [ + "adr_details_id", + "tc3Type", + "tc3PeriodicNumber", + "tc3PeriodicExpiryDate", + ], +}; + export const allTables = (): TableDetails[] => { return [ VEHICLE_TABLE, @@ -389,5 +478,15 @@ export const allTables = (): TableDetails[] => { TEST_DEFECT_TABLE, CUSTOM_DEFECT_TABLE, TEST_RESULT_TABLE, + ADR_ADDITIONAL_EXAMINER_NOTES_TABLE, + ADR_ADDITIONAL_NOTES_GUIDANCE_TABLE, + ADR_ADDITIONAL_NOTES_NUMBER_TABLE, + ADR_DANGEROUS_GOODS_LIST_TABLE, + ADR_DETAILS_TABLE, + ADR_MEMOS_APPLY_TABLE, + ADR_PERMITTED_DANGEROUS_GOODS_TABLE, + ADR_PRODUCTLISTUNNO_LIST_TABLE, + ADR_PRODUCTLISTUNNO_TABLE, + ADR_TC3DETAILS_TABLE, ]; }; From d3404d98f98eb394a7ac14664479eb154cdb6736 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 2 Feb 2024 15:30:39 +0000 Subject: [PATCH 11/44] fix: enum updated --- src/models/adr-details.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index d685a91..36db7db 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -48,7 +48,7 @@ export type VehicleDetailsTypeEnum = | "Semi trailer sheeted load" | "Semi trailer tank" | "Semi trailer skeletal" - | "Semi trailer battery Enum"; + | "Semi trailer battery"; export type Tc2TypeEnum = "initial"; From dcfac2af42a56f0e93341612b7720e95c8490f4b Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:08:42 +0000 Subject: [PATCH 12/44] feat: adr tables added to the tech record list of tables --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 11544e1..4218964 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,13 @@ For the full field-to-column mapping, see `tech-record-document-conversion.ts`. * `microfilm` * `plate` * `axle` + * `adr_details` + * `adr_memos_apply` + * `adr_permitted_dangerous_goods` + * `adr_productListUnNo` + * `adr_additional_examiner_notes` + * `adr_additional_notes_number` + ## Test Result conversion For the full field-to-column mapping, see `test-result-record-conversion.ts`. From 6feb0fc3ac0e930924e5c8aeeea849eabc102cb0 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:10:25 +0000 Subject: [PATCH 13/44] feat: new function added for partial upsert based on condition attribute --- src/services/sql-execution.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/services/sql-execution.ts b/src/services/sql-execution.ts index 45576ad..49aaf2b 100644 --- a/src/services/sql-execution.ts +++ b/src/services/sql-execution.ts @@ -116,3 +116,37 @@ export async function selectRecordIds( connection ); } + +/** + * Execute a "select or partial upsert" for a key value condition attribute: + * - if a matching record exists (run SELECT first), return the existing entity's ID + * - if a matching record does not exist, insert a new record and return its ID + * + * @param tableDetails + * @param conditionAttributes + * @param connection + */ +export const executePartialUpsertIfNotExistsWithCondition = async ( + tableDetails: TableDetails, + conditionAttributes: { [key: string]: any }, + connection: Connection +): Promise => { + // select record if exists + const selectResultSet = await executeSql( + generateSelectRecordIds(tableDetails.tableName, conditionAttributes), + Object.values(conditionAttributes), + connection + ); + + // insert into data base if record not exists + if (selectResultSet.rows.length === 0) { + return executePartialUpsert(tableDetails, + Object.values(conditionAttributes), + connection + ); + + } else { + selectResultSet.rows[0].insertId = selectResultSet.rows[0].id; + return { rows: selectResultSet.rows[0], fields: selectResultSet.fields }; + } +}; From 2a0a72151fce4071e6755ba7443bc599a88ebbb5 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:12:19 +0000 Subject: [PATCH 14/44] feat: some adr table detail updated --- src/services/table-details.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/services/table-details.ts b/src/services/table-details.ts index 8a0b995..e37619a 100644 --- a/src/services/table-details.ts +++ b/src/services/table-details.ts @@ -369,11 +369,6 @@ export const ADR_ADDITIONAL_EXAMINER_NOTES_TABLE: TableDetails = { columnNames: ["adr_details_id", "note", "createdAtDate", "lastUpdatedBy"], }; -export const ADR_ADDITIONAL_NOTES_GUIDANCE_TABLE: TableDetails = { - tableName: "adr_additional_notes_guidance", - columnNames: ["guidanceNotes", "adr_details_id"], -}; - export const ADR_ADDITIONAL_NOTES_NUMBER_TABLE: TableDetails = { tableName: "adr_additional_notes_number", columnNames: ["number", "adr_details_id"], @@ -398,13 +393,12 @@ export const ADR_DETAILS_TABLE: TableDetails = { "brakeEndurance", "weight", "compatibilityGroupJ", - "additionalExaminerNotes", + // dangerousGoods, "applicantDetailsName", "street", "town", "city", "postcode", - "memosApply", "adrTypeApprovalNo", "adrCertificateNotes", "tankManufacturer", @@ -417,9 +411,13 @@ export const ADR_DETAILS_TABLE: TableDetails = { "tc2IntermediateApprovalNo", "tc2IntermediateExpiryDate", "substancesPermitted", + // "select", "statement", "productListRefNo", "productList", + "m145Statement", + // "newCertificateRequested", + ], }; @@ -428,9 +426,14 @@ export const ADR_MEMOS_APPLY_TABLE: TableDetails = { columnNames: ["adr_details_id", "memo"], }; +export const ADR_TANK_DOCUMENTS_TABLE: TableDetails = { + tableName: "adr_documents", + columnNames: ["adr_details_id", "document"], +}; + export const ADR_PERMITTED_DANGEROUS_GOODS_TABLE: TableDetails = { tableName: "adr_permitted_dangerous_goods", - columnNames: ["adr_details_id", "dangerous_goods_id"], + columnNames: ["adr_details_id", "adr_dangerous_goods_list_id"], }; export const ADR_PRODUCTLISTUNNO_LIST_TABLE: TableDetails = { @@ -440,7 +443,7 @@ export const ADR_PRODUCTLISTUNNO_LIST_TABLE: TableDetails = { export const ADR_PRODUCTLISTUNNO_TABLE: TableDetails = { tableName: "adr_productListUnNo", - columnNames: ["adr_details_id", "productListUnNo_id"], + columnNames: ["adr_details_id", "adr_productListUnNo_list_id"], }; export const ADR_TC3DETAILS_TABLE: TableDetails = { @@ -479,11 +482,11 @@ export const allTables = (): TableDetails[] => { CUSTOM_DEFECT_TABLE, TEST_RESULT_TABLE, ADR_ADDITIONAL_EXAMINER_NOTES_TABLE, - ADR_ADDITIONAL_NOTES_GUIDANCE_TABLE, ADR_ADDITIONAL_NOTES_NUMBER_TABLE, ADR_DANGEROUS_GOODS_LIST_TABLE, ADR_DETAILS_TABLE, ADR_MEMOS_APPLY_TABLE, + ADR_TANK_DOCUMENTS_TABLE, ADR_PERMITTED_DANGEROUS_GOODS_TABLE, ADR_PRODUCTLISTUNNO_LIST_TABLE, ADR_PRODUCTLISTUNNO_TABLE, From 59ba45ad71ce73a30b79ead5478e696cd6b957ae Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:13:24 +0000 Subject: [PATCH 15/44] feat: upsert fun ctionality added for adr-details attributes in tech record --- .../tech-record-document-conversion.ts | 334 ++++++++++++++++++ 1 file changed, 334 insertions(+) diff --git a/src/services/tech-record-document-conversion.ts b/src/services/tech-record-document-conversion.ts index 3bc9293..f93e948 100644 --- a/src/services/tech-record-document-conversion.ts +++ b/src/services/tech-record-document-conversion.ts @@ -18,11 +18,22 @@ import { VEHICLE_SUBCLASS_TABLE, VEHICLE_TABLE, AUTH_INTO_SERVICE_TABLE, + ADR_ADDITIONAL_EXAMINER_NOTES_TABLE, + ADR_ADDITIONAL_NOTES_NUMBER_TABLE, + ADR_DANGEROUS_GOODS_LIST_TABLE, + ADR_DETAILS_TABLE, + ADR_MEMOS_APPLY_TABLE, + ADR_PERMITTED_DANGEROUS_GOODS_TABLE, + ADR_PRODUCTLISTUNNO_LIST_TABLE, + ADR_PRODUCTLISTUNNO_TABLE, + ADR_TC3DETAILS_TABLE, + ADR_TANK_DOCUMENTS_TABLE, } from "./table-details"; import { deleteBasedOnWhereIn, executeFullUpsert, executePartialUpsertIfNotExists, + executePartialUpsertIfNotExistsWithCondition, } from "./sql-execution"; import { getConnectionPool } from "./connection-pool"; import { Connection } from "mysql2/promise"; @@ -219,6 +230,91 @@ const upsertTechRecords = async ( techRecord ); + // upsert adr-details + if (techRecord.adrDetails) { + const adrResponse = await executeFullUpsert( + ADR_DETAILS_TABLE, + [ + techRecordId, + techRecord.adrDetails.vehicleDetails?.type, + techRecord.adrDetails.vehicleDetails?.approvalDate, + techRecord.adrDetails.listStatementApplicable, + techRecord.adrDetails.batteryListNumber, + techRecord.adrDetails.declarationsSeen, + techRecord.adrDetails.brakeDeclarationsSeen, + techRecord.adrDetails.brakeDeclarationIssuer, + techRecord.adrDetails.brakeEndurance, + techRecord.adrDetails.weight, + techRecord.adrDetails.compatibilityGroupJ, + // techRecord.adrDetails.dangerousGoods, + techRecord.adrDetails.applicantDetails?.name, + techRecord.adrDetails.applicantDetails?.street, + techRecord.adrDetails.applicantDetails?.town, + techRecord.adrDetails.applicantDetails?.city, + techRecord.adrDetails.applicantDetails?.postcode, + techRecord.adrDetails.adrTypeApprovalNo, + techRecord.adrDetails.adrCertificateNotes, + techRecord.adrDetails.tank?.tankDetails?.tankManufacturer, + techRecord.adrDetails.tank?.tankDetails?.yearOfManufacture, + techRecord.adrDetails.tank?.tankDetails?.tankCode, + techRecord.adrDetails.tank?.tankDetails?.specialProvisions, + techRecord.adrDetails.tank?.tankDetails?.tankManufacturerSerialNo, + techRecord.adrDetails.tank?.tankDetails?.tankTypeAppNo, + techRecord.adrDetails.tank?.tankDetails?.tc2Details?.tc2Type, + techRecord.adrDetails.tank?.tankDetails?.tc2Details + ?.tc2IntermediateApprovalNo, + techRecord.adrDetails.tank?.tankDetails?.tc2Details + ?.tc2IntermediateExpiryDate, + techRecord.adrDetails.tank?.tankStatement?.substancesPermitted, + // techRecord.adrDetails.tank?.tankStatement?.select, + techRecord.adrDetails.tank?.tankStatement?.statement, + techRecord.adrDetails.tank?.tankStatement?.productListRefNo, + techRecord.adrDetails.tank?.tankStatement?.productList, + techRecord.adrDetails.m145Statement, + // techRecord.adrDetails.newCertificateRequested, + ], + techRecordConnection + ); + + const adrDetailsId = adrResponse.rows.insertId; + + await upsertAdrMemosApply( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrPermittedDangerousGoods( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrProductListUnNo( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrTc3Details( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrAdditionalExaminerNotes( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrAdditionalNotesNumber( + techRecordConnection, + adrDetailsId, + techRecord + ); + // await upsertAdrTankDocuments( + // techRecordConnection, + // adrDetailsId, + // techRecord + // ); + } + await techRecordConnection.commit(); } catch (err) { console.error(err); @@ -634,3 +730,241 @@ const upsertAuthIntoService = async ( `upsertTechRecords: Upserted authIntoService (tech-record-id: ${techRecordId}, ID: ${response.rows.insertId})` ); }; + +const upsertAdrMemosApply = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.memosApply) { + debugLog( + `upsertTechRecords: Upserting ADR memos_apply (adr-details-id: ${adrDetailsId})...` + ); + + for (const memo of techRecord.adrDetails?.memosApply) { + const response = await executeFullUpsert( + ADR_MEMOS_APPLY_TABLE, + [adrDetailsId, memo], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR memos-apply (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrDangerousGoodsList = async ( + connection: Connection, + dangerousGoodsName: string +): Promise => { + debugLog(`upsertTechRecords: Selecting/Upserting adr_dangerous_goods_list...`); + + const response = await executePartialUpsertIfNotExistsWithCondition( + ADR_DANGEROUS_GOODS_LIST_TABLE, + {name: dangerousGoodsName}, + connection + ); + + debugLog( + `upsertTechRecords: Selected adr_dangerous_goods_list (ID ${response.rows.insertId})` + ); + + return response.rows.insertId; +}; + +const upsertAdrPermittedDangerousGoods = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.permittedDangerousGoods) { + debugLog( + `upsertTechRecords: Upserting ADR permitted_dangerous_goods (adr-details-id: ${adrDetailsId})...` + ); + + for (const permittedDangerousGoods of techRecord.adrDetails + ?.permittedDangerousGoods) { + const permittedDangerousGoodsId = await upsertAdrDangerousGoodsList( + connection, + permittedDangerousGoods + ); + + const response = await executeFullUpsert( + ADR_PERMITTED_DANGEROUS_GOODS_TABLE, + [adrDetailsId, permittedDangerousGoodsId], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR permitted_dangerous_goods (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrProductListUnNoList = async ( + connection: Connection, + productListUnNo: string +): Promise => { + debugLog(`upsertTechRecords: Upserting adr_productListUnNo_list...`); + + const response = await executePartialUpsertIfNotExistsWithCondition( + ADR_PRODUCTLISTUNNO_LIST_TABLE, + {name: productListUnNo}, + connection + ); + + debugLog( + `upsertTechRecords: Upserted adr_productListUnNo_list (ID ${response.rows.insertId})` + ); + + return response.rows.insertId; +}; + +const upsertAdrProductListUnNo = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.tank?.tankStatement?.productListUnNo) { + debugLog( + `upsertTechRecords: Upserting ADR tankStatement productListUnNo (adr-details-id: ${adrDetailsId})...` + ); + + for (const productListUnNo of techRecord.adrDetails?.tank?.tankStatement + ?.productListUnNo) { + const productListUnNoId = await upsertAdrProductListUnNoList( + connection, + productListUnNo + ); + + const response = await executeFullUpsert( + ADR_PRODUCTLISTUNNO_TABLE, + [adrDetailsId, productListUnNoId], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR tankStatement productListUnNo (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrTc3Details = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.tank?.tankDetails?.tc3Details) { + debugLog( + `upsertTechRecords: Upserting ADR tc3Details (adr-details-id: ${adrDetailsId})...` + ); + + for (const tc3Details of techRecord.adrDetails?.tank?.tankDetails + ?.tc3Details) { + const response = await executeFullUpsert( + ADR_TC3DETAILS_TABLE, + [ + adrDetailsId, + tc3Details.tc3Type, + tc3Details.tc3PeriodicNumber, + tc3Details.tc3PeriodicExpiryDate, + ], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR tc3Details (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrAdditionalExaminerNotes = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.additionalExaminerNotes) { + debugLog( + `upsertTechRecords: Upserting ADR additionalExaminerNotes (adr-details-id: ${adrDetailsId})...` + ); + + for (const additionalExaminerNotes of techRecord.adrDetails + ?.additionalExaminerNotes) { + const response = await executeFullUpsert( + ADR_ADDITIONAL_EXAMINER_NOTES_TABLE, + [ + adrDetailsId, + additionalExaminerNotes.note, + additionalExaminerNotes.createdAtDate, + additionalExaminerNotes.lastUpdatedBy, + ], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR additionalExaminerNotes (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrAdditionalNotesNumber = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.additionalNotes?.number) { + debugLog( + `upsertTechRecords: Upserting ADR additional_notes_number (adr-details-id: ${adrDetailsId})...` + ); + + for (const additionalNotesNumber of techRecord.adrDetails?.additionalNotes + ?.number) { + const response = await executeFullUpsert( + ADR_ADDITIONAL_NOTES_NUMBER_TABLE, + [additionalNotesNumber, adrDetailsId], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR additional_notes_number (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrTankDocuments = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.documents) { + debugLog( + `upsertTechRecords: Upserting ADR tank documents (adr-details-id: ${adrDetailsId})...` + ); + + for (const documents of techRecord.adrDetails?.documents) { + const response = await executeFullUpsert( + ADR_TANK_DOCUMENTS_TABLE, + [adrDetailsId, documents], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR tank documents (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; From c31cf13d2f0a5fb53b6d46651f1bba3ae564ea91 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:14:22 +0000 Subject: [PATCH 16/44] feat: adr parts added to tech record integration test --- ...tech-record-document-conversion.intTest.ts | 256 +++++++++++++++++- 1 file changed, 251 insertions(+), 5 deletions(-) diff --git a/tests/integration/tech-record-document-conversion.intTest.ts b/tests/integration/tech-record-document-conversion.intTest.ts index b070bf9..54654e9 100644 --- a/tests/integration/tech-record-document-conversion.intTest.ts +++ b/tests/integration/tech-record-document-conversion.intTest.ts @@ -4,7 +4,7 @@ import { executeSql, } from "../../src/services/connection-pool"; import { exampleContext, useLocalDb } from "../utils"; -import techRecordDocumentJson from "../resources/dynamodb-image-technical-record.json"; +import techRecordDocumentJsonWithADR from "../resources/dynamodb-image-technical-record-with-adr.json"; import { getContainerizedDatabase } from "./cvsbnop-container"; import { processStreamEvent } from "../../src/functions/process-stream-event"; import { getConnectionPoolOptions } from "../../src/services/connection-pool-options"; @@ -12,7 +12,7 @@ import { getConnectionPoolOptions } from "../../src/services/connection-pool-opt useLocalDb(); export const techRecordDocumentConversion = () => - describe("convertTechRecordDocument() integration tests", () => { + describe("convertTechRecordDocument() with ADR integration tests", () => { let container: StartedTestContainer; beforeAll(async () => { @@ -49,7 +49,7 @@ export const techRecordDocumentConversion = () => "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T00:00:00.000", eventName: "INSERT", dynamodb: { - NewImage: techRecordDocumentJson, + NewImage: techRecordDocumentJsonWithADR, }, }), }, @@ -590,13 +590,259 @@ export const techRecordDocumentConversion = () => expect( (authIntoServiceResultSet.rows[0].dateRejected as Date).toUTCString() ).toEqual("Tue, 05 May 2020 00:00:00 GMT"); + + // adr_details + const adrDetailsResultSet = await executeSql( + `SELECT \`id\`, + \`technical_record_id\`, + \`type\`, + \`approvalDate\`, + \`listStatementApplicable\`, + \`batteryListNumber\`, + \`declarationsSeen\`, + \`brakeDeclarationsSeen\`, + \`brakeDeclarationIssuer\`, + \`brakeEndurance\`, + \`weight\`, + \`compatibilityGroupJ\`, + \`applicantDetailsName\`, + \`street\`, + \`town\`, + \`city\`, + \`postcode\`, + \`adrTypeApprovalNo\`, + \`adrCertificateNotes\`, + \`tankManufacturer\`, + \`yearOfManufacture\`, + \`tankCode\`, + \`specialProvisions\`, + \`tankManufacturerSerialNo\`, + \`tankTypeAppNo\`, + \`tc2Type\`, + \`tc2IntermediateApprovalNo\`, + \`tc2IntermediateExpiryDate\`, + \`substancesPermitted\`, + \`statement\`, + \`productListRefNo\`, + \`productList\`, + \`m145Statement\` + FROM \`adr_details\` + WHERE \`adr_details\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + expect(adrDetailsResultSet.rows[0].technical_record_id).toEqual( + technicalRecordId + ); + expect(adrDetailsResultSet.rows[0].type).toEqual("Artic tractor"); + expect( + (adrDetailsResultSet.rows[0].approvalDate as Date).toUTCString() + ).toEqual("Mon, 12 Jun 2023 00:00:00 GMT"); + expect(adrDetailsResultSet.rows[0].listStatementApplicable).toEqual(1); + expect(adrDetailsResultSet.rows[0].batteryListNumber).toEqual("BATTERY1"); + expect(adrDetailsResultSet.rows[0].declarationsSeen).toEqual(0); + expect(adrDetailsResultSet.rows[0].brakeDeclarationsSeen).toEqual(1); + expect(adrDetailsResultSet.rows[0].brakeDeclarationIssuer).toEqual( + "brakeDeclarationIssuer_1" + ); + expect(adrDetailsResultSet.rows[0].brakeEndurance).toEqual(0); + expect(adrDetailsResultSet.rows[0].weight).toEqual(6789); + expect(adrDetailsResultSet.rows[0].compatibilityGroupJ).toEqual("I"); + expect(adrDetailsResultSet.rows[0].applicantDetailsName).toEqual( + "applicantDetails_Name" + ); + expect(adrDetailsResultSet.rows[0].street).toEqual( + "applicantDetailsSTREET" + ); + expect(adrDetailsResultSet.rows[0].town).toEqual("applicantDetailsTOWN"); + expect(adrDetailsResultSet.rows[0].city).toEqual("applicantDetailsCITY"); + expect(adrDetailsResultSet.rows[0].postcode).toEqual("POST-CODE"); + expect(adrDetailsResultSet.rows[0].adrTypeApprovalNo).toEqual( + "adrTypeApprovalNo_1" + ); + expect(adrDetailsResultSet.rows[0].adrCertificateNotes).toEqual( + "adrCertificateNotes_1" + ); + expect(adrDetailsResultSet.rows[0].tankManufacturer).toEqual( + "tankManufacturer_1" + ); + expect(adrDetailsResultSet.rows[0].yearOfManufacture).toEqual(2012); + expect(adrDetailsResultSet.rows[0].tankCode).toEqual("tankCode_1"); + expect(adrDetailsResultSet.rows[0].specialProvisions).toEqual( + "specialProvisions_1" + ); + expect(adrDetailsResultSet.rows[0].tankManufacturerSerialNo).toEqual( + "1234" + ); + expect(adrDetailsResultSet.rows[0].tankTypeAppNo).toEqual("9876"); + expect(adrDetailsResultSet.rows[0].tc2Type).toEqual("initial"); + expect(adrDetailsResultSet.rows[0].tc2IntermediateApprovalNo).toEqual( + "12345" + ); + expect( + (adrDetailsResultSet.rows[0] + .tc2IntermediateExpiryDate as Date).toUTCString() + ).toEqual("Sat, 01 Jun 2024 00:00:00 GMT"); + expect(adrDetailsResultSet.rows[0].substancesPermitted).toEqual( + "Substances permitted under the tank code and any special provisions specified in 9 may be carried" + ); + expect(adrDetailsResultSet.rows[0].statement).toEqual("statement_1"); + expect(adrDetailsResultSet.rows[0].productListRefNo).toEqual("123456"); + expect(adrDetailsResultSet.rows[0].productList).toEqual("productList_1"); + expect(adrDetailsResultSet.rows[0].m145Statement).toEqual(1); + + const adrDetailsId = adrDetailsResultSet.rows[0].id; + + // adr_memos_apply + const adrMemosApplyResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`memo\` + FROM \`adr_memos_apply\` + WHERE \`adr_memos_apply\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrMemosApplyResultSet.rows.length).toEqual(1); + expect(adrMemosApplyResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect(adrMemosApplyResultSet.rows[0].memo).toEqual( + "07/09 3mth leak ext" + ); + + // adr_dangerous_goods_list + const adrDangerousGoodsListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_dangerous_goods_list\` + ` + ); + expect(adrDangerousGoodsListResultSet.rows.length).toEqual(3); + + expect(adrDangerousGoodsListResultSet.rows[0].name).toEqual( + "FP <61 (FL)" + ); + expect(adrDangerousGoodsListResultSet.rows[1].name).toEqual( + "Carbon Disulphide" + ); + expect(adrDangerousGoodsListResultSet.rows[2].name).toEqual("Hydrogen"); + + // adr_permitted_dangerous_goods + const adrPermittedDangerousGoodsResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_dangerous_goods_list_id\` + FROM \`adr_permitted_dangerous_goods\` + WHERE \`adr_permitted_dangerous_goods\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrPermittedDangerousGoodsResultSet.rows.length).toEqual(3); + expect( + adrPermittedDangerousGoodsResultSet.rows[0].adr_details_id + ).toEqual(adrDetailsId); + expect( + adrPermittedDangerousGoodsResultSet.rows[0].adr_dangerous_goods_list_id + ).toEqual(1); + expect( + adrPermittedDangerousGoodsResultSet.rows[1].adr_dangerous_goods_list_id + ).toEqual(2); + expect( + adrPermittedDangerousGoodsResultSet.rows[2].adr_dangerous_goods_list_id + ).toEqual(3); + + // adr_productListUnNo_list + const adrProductListUnNoListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_productListUnNo_list\` + ` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + expect(adrProductListUnNoListResultSet.rows[0].name).toEqual("123123"); + expect(adrProductListUnNoListResultSet.rows[1].name).toEqual("987987"); + expect(adrProductListUnNoListResultSet.rows[2].name).toEqual("135790"); + + // adr_productListUnNo + const adrProductListUnNoResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_productListUnNo_list_id\` + FROM \`adr_productListUnNo\` + WHERE \`adr_productListUnNo\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(3); + expect(adrProductListUnNoResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect( + adrProductListUnNoResultSet.rows[0].adr_productListUnNo_list_id + ).toEqual(1); + expect( + adrProductListUnNoResultSet.rows[1].adr_productListUnNo_list_id + ).toEqual(2); + expect( + adrProductListUnNoResultSet.rows[2].adr_productListUnNo_list_id + ).toEqual(3); + + // adr_tc3Details + const adrTc3DetailsResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`tc3Type\`, + \`tc3PeriodicNumber\`, + \`tc3PeriodicExpiryDate\` + FROM \`adr_tc3Details\` + WHERE \`adr_tc3Details\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrTc3DetailsResultSet.rows.length).toEqual(1); + expect(adrTc3DetailsResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect(adrTc3DetailsResultSet.rows[0].tc3Type).toEqual("intermediate"); + expect(adrTc3DetailsResultSet.rows[0].tc3PeriodicNumber).toEqual("98765"); + expect( + (adrTc3DetailsResultSet.rows[0] + .tc3PeriodicExpiryDate as Date).toUTCString() + ).toEqual("Sat, 01 Jun 2024 00:00:00 GMT"); + + // adr_additional_examiner_notes + const adrAdditionalExaminerNotesResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`note\`, + \`createdAtDate\`, + \`lastUpdatedBy\` + FROM \`adr_additional_examiner_notes\` + WHERE \`adr_additional_examiner_notes\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrAdditionalExaminerNotesResultSet.rows.length).toEqual(1); + expect( + adrAdditionalExaminerNotesResultSet.rows[0].adr_details_id + ).toEqual(adrDetailsId); + expect(adrAdditionalExaminerNotesResultSet.rows[0].note).toEqual( + "additionalExaminerNotes_note_1" + ); + expect( + (adrAdditionalExaminerNotesResultSet.rows[0] + .createdAtDate as Date).toUTCString() + ).toEqual("Tue, 30 May 2023 00:00:00 GMT"); + expect(adrAdditionalExaminerNotesResultSet.rows[0].lastUpdatedBy).toEqual( + "additionalExaminerNotes_lastUpdatedBy_1" + ); + + // adr_additional_notes_number + const adrAdditionalNotesNumberResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`number\` + FROM \`adr_additional_notes_number\` + WHERE \`adr_additional_notes_number\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrAdditionalNotesNumberResultSet.rows.length).toEqual(2); + expect(adrAdditionalNotesNumberResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect(adrAdditionalNotesNumberResultSet.rows[0].number).toEqual("1"); + expect(adrAdditionalNotesNumberResultSet.rows[1].number).toEqual("T1B"); }); describe("when adding a new vehicle and changing VRM to a new value, VRM should change on existing vehicle.", () => { it("A new vehicle is present", async () => { // arrange - create a record so we can later query for it and assert for is existence const techRecordDocumentJsonNew = JSON.parse( - JSON.stringify(techRecordDocumentJson) + JSON.stringify(techRecordDocumentJsonWithADR) ); techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-2" }; techRecordDocumentJsonNew.vin = { S: "VIN2" }; @@ -642,7 +888,7 @@ export const techRecordDocumentConversion = () => it("VRM has changed", async () => { // arrange - create a record with existing pair of (SystemNumber, VIN) and new VRM so we can later query for it and assert its value const techRecordDocumentJsonNew = JSON.parse( - JSON.stringify(techRecordDocumentJson) + JSON.stringify(techRecordDocumentJsonWithADR) ); techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-2" }; techRecordDocumentJsonNew.vin = { S: "VIN2" }; From 01fdc81d310103c1b4e01237b3da7513aa9bf860 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:16:46 +0000 Subject: [PATCH 17/44] feat: docker's mysql image updated to version 8 - consistent with recent RDS engine upgarde for NOP --- tests/resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/resources/Dockerfile b/tests/resources/Dockerfile index 25ca559..a655315 100644 --- a/tests/resources/Dockerfile +++ b/tests/resources/Dockerfile @@ -1,5 +1,5 @@ # Match Aurora MySQL version as closely as possible -FROM mysql:8.2.0 +FROM mysql:8.0.32 ENV MYSQL_DATABASE=CVSBNOP \ MYSQL_ROOT_PASSWORD=12345 From 957c9b4ed5628f968b4a39f2d979f737fdbfdbb6 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:17:53 +0000 Subject: [PATCH 18/44] feat: adr attribute values updated --- ...amodb-image-technical-record-with-adr.json | 380 +++++++++--------- 1 file changed, 190 insertions(+), 190 deletions(-) diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json index f1dcf71..a1922e2 100644 --- a/tests/resources/dynamodb-image-technical-record-with-adr.json +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -25,227 +25,227 @@ "L": [ { "M": { - "adrDetails": { - "M": { - "additionalExaminerNotes": { - "L": [ - { - "M": { - "note": { - "S": "additionalExaminerNotes_note_1" - }, - "createdAtDate": { - "S": "2023-05-30" - }, - "lastUpdatedBy": { - "S": "additionalExaminerNotes_lastUpdatedBy_1" - } - } - } - ] - }, - "additionalNotes": { - "M": { - "number": { - "L": [ - {"S": "1"}, - {"S": "T1B"} - ] - } - } - }, - "adrCertificateNotes": { - "S": "adrCertificateNotes_1" - }, - "adrTypeApprovalNo": { - "S": "adrTypeApprovalNo_1" - }, - "applicantDetails": { + "adrDetails": { + "M": { + "additionalExaminerNotes": { + "L": [ + { "M": { - "name": { - "S": "adrDetails_applicantDetails_name_1" - }, - "street": { - "S": "adrDetails_applicantDetails_street_1" - }, - "town": { - "S": "adrDetails_applicantDetails_town_1" - }, - "city": { - "S": "adrDetails_applicantDetails_city_1" - }, - "postcode": { - "S": "adrDetails_applicantDetails_postcode_1" - } - } - }, - "batteryListNumber": { - "S": "batteryListNumber_1" - }, - "brakeDeclarationIssuer": { - "S": "brakeDeclarationIssuer_1" - }, - "brakeDeclarationsSeen": { - "BOOL": true - }, - "brakeEndurance": { - "BOOL": false - }, - "compatibilityGroupJ": { - "S": "I" - }, - "dangerousGoods": { - "BOOL": false - }, - "declarationsSeen": { - "BOOL": false - }, - "documents": { - "L": [ - { - "S": "documents_1" + "note": { + "S": "additionalExaminerNotes_note_1" + }, + "createdAtDate": { + "S": "2023-05-30" }, - { - "S": "documents_2" - }, - { - "S": "documents_3" + "lastUpdatedBy": { + "S": "additionalExaminerNotes_lastUpdatedBy_1" } + } + } + ] + }, + "additionalNotes": { + "M": { + "number": { + "L": [ + {"S": "1"}, + {"S": "T1B"} ] + } + } + }, + "adrCertificateNotes": { + "S": "adrCertificateNotes_1" + }, + "adrTypeApprovalNo": { + "S": "adrTypeApprovalNo_1" + }, + "applicantDetails": { + "M": { + "name": { + "S": "applicantDetails_Name" }, - "listStatementApplicable": { - "BOOL": true + "street": { + "S": "applicantDetailsSTREET" }, - "m145Statement": { - "BOOL": true + "town": { + "S": "applicantDetailsTOWN" }, - "newCertificateRequested": { - "BOOL": false + "city": { + "S": "applicantDetailsCITY" }, - - "memosApply": { - "L": [ - { - "S": "07/09 3mth leak ext" - } - ] + "postcode": { + "S": "POST-CODE" + } + } + }, + "batteryListNumber": { + "S": "BATTERY1" + }, + "brakeDeclarationIssuer": { + "S": "brakeDeclarationIssuer_1" + }, + "brakeDeclarationsSeen": { + "BOOL": true + }, + "brakeEndurance": { + "BOOL": false + }, + "compatibilityGroupJ": { + "S": "I" + }, + "dangerousGoods": { + "BOOL": false + }, + "declarationsSeen": { + "BOOL": false + }, + "documents": { + "L": [ + { + "S": "documents_1" }, - "permittedDangerousGoods": { - "L": [ - { - "S": "FP <61 (FL)" - }, - { - "S": "Carbon Disulphide" - }, - { - "S": "Hydrogen" - } - ] + { + "S": "documents_2" + }, + { + "S": "documents_3" + } + ] + }, + "listStatementApplicable": { + "BOOL": true + }, + "m145Statement": { + "BOOL": true + }, + "newCertificateRequested": { + "BOOL": false + }, + + "memosApply": { + "L": [ + { + "S": "07/09 3mth leak ext" + } + ] + }, + "permittedDangerousGoods": { + "L": [ + { + "S": "FP <61 (FL)" }, - "tank": { + { + "S": "Carbon Disulphide" + }, + { + "S": "Hydrogen" + } + ] + }, + "tank": { + "M": { + "tankDetails": { "M": { - "tankDetails": { + "tankManufacturer": { + "S": "tankManufacturer_1" + }, + "yearOfManufacture": { + "N": "2012" + }, + "tankCode": { + "S": "tankCode_1" + }, + "specialProvisions": { + "S": "specialProvisions_1" + }, + "tankManufacturerSerialNo": { + "S": "1234" + }, + "tankTypeAppNo": { + "S": "9876" + }, + "tc2Details": { "M": { - "tankManufacturer": { - "S": "tankManufacturer_1" - }, - "yearOfManufacture": { - "N": "1234" + "tc2Type": { + "S": "initial" }, - "tankCode": { - "S": "tankCode_1" + "tc2IntermediateApprovalNo": { + "S": "12345" }, - "specialProvisions": { - "S": "specialProvisions_1" - }, - "tankManufacturerSerialNo": { - "S": "1234" - }, - "tankTypeAppNo": { - "S": "9876" - }, - "tc2Details": { + "tc2IntermediateExpiryDate": { + "S": "2024-06-01" + } + } + }, + "tc3Details": { + "L": [ + { "M": { - "tc2Type": { - "S": "initial" + "tc3Type": { + "S": "intermediate" }, - "tc2IntermediateApprovalNo": { - "S": "12345" + "tc3PeriodicNumber": { + "S": "98765" }, - "tc2IntermediateExpiryDate": { + "tc3PeriodicExpiryDate": { "S": "2024-06-01" } } - }, - "tc3Details": { - "L": [ - { - "M": { - "tc3Type": { - "S": "intermediate" - }, - "tc3PeriodicNumber": { - "S": "98765" - }, - "tc3PeriodicExpiryDate": { - "S": "2024-06-01" - } - } - } - ] } - } + ] + } + } + }, + "tankStatement": { + "M": { + "select":{ + "S": "Product list" }, - "tankStatement": { - "M": { - "select":{ - "S": "Product list" - }, - "substancesPermitted": { - "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" - }, - "statement": { - "S": "statement_1" - }, - "productListRefNo": { - "S": "123456" + "substancesPermitted": { + "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" + }, + "statement": { + "S": "statement_1" + }, + "productListRefNo": { + "S": "123456" + }, + "productListUnNo": { + "L": [ + { + "S": "123123" }, - "productListUnNo": { - "L": [ - { - "S": "123123" - }, - { - "S": "987987" - }, - { - "S": "135790" - } - ] + { + "S": "987987" }, - "productList": { - "S": "productList_1" + { + "S": "135790" } - } - } - } - }, - "vehicleDetails": { - "M": { - "type": { - "S": "Artic tractor" + ] }, - "approvalDate": { - "S": "2023-06-12" + "productList": { + "S": "productList_1" } } + } + } + }, + "vehicleDetails": { + "M": { + "type": { + "S": "Artic tractor" }, - "weight": { - "N": "6789" + "approvalDate": { + "S": "2023-06-12" } } - }, + }, + "weight": { + "N": "6789" + } + } + }, "recordCompleteness": { "S": "88888888" }, From f0e39d5585896c74413d93a39849b6b3e80973d3 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:18:48 +0000 Subject: [PATCH 19/44] feat: test updated as adr attribute values updated in json file --- tests/unit/models/tech-record-document.unitTest.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index d610b88..97c4fbb 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -65,9 +65,9 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("adrDetails_applicantDetails_name_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("applicantDetails_Name"); - expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("batteryListNumber_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("BATTERY1"); expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationsSeen).toEqual(true); @@ -89,7 +89,7 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturer).toEqual("tankManufacturer_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(1234); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(2012); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankCode).toEqual("tankCode_1"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.specialProvisions).toEqual("specialProvisions_1"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturerSerialNo).toEqual("1234"); @@ -176,9 +176,9 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("adrDetails_applicantDetails_name_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("applicantDetails_Name"); - expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("batteryListNumber_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("BATTERY1"); expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationsSeen).toEqual(true); @@ -200,7 +200,7 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturer).toEqual("tankManufacturer_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(1234); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(2012); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankCode).toEqual("tankCode_1"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.specialProvisions).toEqual("specialProvisions_1"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturerSerialNo).toEqual("1234"); From 01f08d9f619f3245e91883a2c757cb19c8777b40 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 8 Feb 2024 12:56:10 +0000 Subject: [PATCH 20/44] fix: changes reverted back to original --- tests/resources/Dockerfile | 2 +- tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/resources/Dockerfile b/tests/resources/Dockerfile index a655315..b6d6a32 100644 --- a/tests/resources/Dockerfile +++ b/tests/resources/Dockerfile @@ -1,5 +1,5 @@ # Match Aurora MySQL version as closely as possible -FROM mysql:8.0.32 +FROM mysql:5.7.12 ENV MYSQL_DATABASE=CVSBNOP \ MYSQL_ROOT_PASSWORD=12345 diff --git a/tsconfig.json b/tsconfig.json index b5af863..cf02692 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,6 @@ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, - "types": ["jest", "node"] + "types": [] } } From 37f24903e5e3accec176ef6263ae6bd046d948d0 Mon Sep 17 00:00:00 2001 From: meys-bjss <140601718+meys-bjss@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:58:59 +0000 Subject: [PATCH 21/44] fix: changes reverted back to original --- tests/resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/resources/Dockerfile b/tests/resources/Dockerfile index a655315..b6d6a32 100644 --- a/tests/resources/Dockerfile +++ b/tests/resources/Dockerfile @@ -1,5 +1,5 @@ # Match Aurora MySQL version as closely as possible -FROM mysql:8.0.32 +FROM mysql:5.7.12 ENV MYSQL_DATABASE=CVSBNOP \ MYSQL_ROOT_PASSWORD=12345 From deff3e34e15a93648770059e5cc82b82c8c985ef Mon Sep 17 00:00:00 2001 From: meys-bjss <140601718+meys-bjss@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:59:52 +0000 Subject: [PATCH 22/44] fix: changes reverted back to original --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index b5af863..cf02692 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,6 @@ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, - "types": ["jest", "node"] + "types": [] } } From 847fd26805e4e9fce8f26680bc2b951a93a56fc7 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 9 Feb 2024 09:20:38 +0000 Subject: [PATCH 23/44] feat: cleaning and bringing in adr pass certificate --- src/models/adr-certificate-details.ts | 68 +++++++++++++-------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/models/adr-certificate-details.ts b/src/models/adr-certificate-details.ts index bad6f37..89a88d5 100644 --- a/src/models/adr-certificate-details.ts +++ b/src/models/adr-certificate-details.ts @@ -1,49 +1,45 @@ import { DynamoDbImage } from "../services/dynamodb-images"; import { Maybe } from "./optionals"; -// define AdrCertificateDetails' high-level attributes data types -export interface AdrCertificateDetails { - adrPassCertificateDetails?: AdrPassCertificateDetails; -} - // define Enums -export type certificateIdEnum = - | "PASS" - | "REPLACEMENT"; +export type AdrPassCertificateTypeEnum = "PASS" | "REPLACEMENT"; -// define AdrCertificateDetails' sub-attributes data types export type AdrPassCertificateDetails = AdrPassCertificateDetailsItems[]; export interface AdrPassCertificateDetailsItems { - createdByName?: string; - certificateType?: string; - generatedTimestamp?: string; - certificateId?: string; - } + createdByName?: string; + certificateType?: AdrPassCertificateTypeEnum; + generatedTimestamp?: string; + certificateId?: string; +} -// function to parse AdrCertificateDetails' high-level and sub attributes + return AdrCertificateDetails object export const parseAdrCertificateDetails = ( - certificateDetails?: DynamoDbImage - ): Maybe => { - if (!certificateDetails) { - return undefined; - } + adrPassCertificateDetailsImage?: DynamoDbImage +): Maybe => { + if (!adrPassCertificateDetailsImage) { + return undefined; + } - const adrPassCertificateDetailsImage: DynamoDbImage = certificateDetails.getList( - "adrPassCertificateDetails" - )!; - const adrPassCertificateDetails: AdrPassCertificateDetails = []; + const adrPassCertificateDetails: AdrPassCertificateDetails = []; - for (const key of adrPassCertificateDetailsImage.getKeys()) { - const adrPassCertificateDetailsItemImage = adrPassCertificateDetailsImage.getMap(key)!; - adrPassCertificateDetails.push({ - createdByName: adrPassCertificateDetailsItemImage.getString("createdByName"), - certificateType: adrPassCertificateDetailsItemImage.getString("certificateType"), - generatedTimestamp: adrPassCertificateDetailsItemImage.getString("generatedTimestamp"), - certificateId: adrPassCertificateDetailsItemImage.getString("certificateId") as certificateIdEnum, - }); - } - return { - adrPassCertificateDetails - }; + for (const key of adrPassCertificateDetailsImage.getKeys()) { + const adrPassCertificateDetailsItemImage = adrPassCertificateDetailsImage.getMap( + key + )!; + adrPassCertificateDetails.push({ + createdByName: adrPassCertificateDetailsItemImage.getString( + "createdByName" + ), + certificateType: adrPassCertificateDetailsItemImage.getString( + "certificateType" + ) as AdrPassCertificateTypeEnum, + generatedTimestamp: adrPassCertificateDetailsItemImage.getString( + "generatedTimestamp" + ), + certificateId: adrPassCertificateDetailsItemImage.getString( + "certificateId" + ), + }); + } + return adrPassCertificateDetails; }; From e00b5647e1b5ccb6652bac9216a7f4d370777a19 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 9 Feb 2024 09:53:27 +0000 Subject: [PATCH 24/44] feat: cleaning and bringing in adr pass certificate --- src/models/tech-record.ts | 11 ++-- src/services/table-details.ts | 13 ++++- .../tech-record-document-conversion.ts | 52 +++++++++++++++++-- ...amodb-image-technical-record-with-adr.json | 2 +- .../models/tech-record-document.unitTest.ts | 8 +-- 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/models/tech-record.ts b/src/models/tech-record.ts index 063b73f..ace894b 100644 --- a/src/models/tech-record.ts +++ b/src/models/tech-record.ts @@ -15,7 +15,10 @@ import { parsePlates, Plates } from "./plates"; import { BodyType, parseBodyType } from "./body-type"; import { Dimensions, parseDimensions } from "./dimensions"; import { AdrDetails, parseAdrDetails } from "./adr-details"; -import { AdrCertificateDetails, parseAdrCertificateDetails } from "./adr-certificate-details"; +import { + AdrPassCertificateDetails, + parseAdrCertificateDetails, +} from "./adr-certificate-details"; import { parseVehicleClass, VehicleClass } from "./vehicle-class"; import { Brakes, parseBrakes } from "./brakes"; import { Axles, parseAxles } from "./axles"; @@ -115,7 +118,7 @@ export interface TechRecord { noOfAxles?: number; brakeCode?: string; adrDetails?: AdrDetails; - adrCertificateDetails?: AdrCertificateDetails; + adrCertificateDetails?: AdrPassCertificateDetails; createdByName?: string; createdById?: string; lastUpdatedByName?: string; @@ -273,7 +276,9 @@ const parseTechRecord = (image: DynamoDbImage): TechRecord => { noOfAxles: image.getNumber("noOfAxles"), brakeCode: image.getString("brakeCode"), adrDetails: parseAdrDetails(image.getMap("adrDetails")), - adrCertificateDetails: parseAdrCertificateDetails(image.getMap("certificateDetails")), + adrCertificateDetails: parseAdrCertificateDetails( + image.getList("adrPassCertificateDetails") + ), createdByName: image.getString("createdByName"), createdById: image.getString("createdById"), lastUpdatedByName: image.getString("lastUpdatedByName"), diff --git a/src/services/table-details.ts b/src/services/table-details.ts index e37619a..d085dbc 100644 --- a/src/services/table-details.ts +++ b/src/services/table-details.ts @@ -364,6 +364,17 @@ export const TEST_RESULT_TABLE: TableDetails = { ], }; +export const ADR_PASS_CERTIFICATE_DETAILS: TableDetails = { + tableName: "adr_PassCertificateDetails", + columnNames: [ + "technical_record_id", + "createdByName", + "certificateType", + "generatedTimestamp", + "certificateId", + ], +}; + export const ADR_ADDITIONAL_EXAMINER_NOTES_TABLE: TableDetails = { tableName: "adr_additional_examiner_notes", columnNames: ["adr_details_id", "note", "createdAtDate", "lastUpdatedBy"], @@ -417,7 +428,6 @@ export const ADR_DETAILS_TABLE: TableDetails = { "productList", "m145Statement", // "newCertificateRequested", - ], }; @@ -491,5 +501,6 @@ export const allTables = (): TableDetails[] => { ADR_PRODUCTLISTUNNO_LIST_TABLE, ADR_PRODUCTLISTUNNO_TABLE, ADR_TC3DETAILS_TABLE, + ADR_PASS_CERTIFICATE_DETAILS, ]; }; diff --git a/src/services/tech-record-document-conversion.ts b/src/services/tech-record-document-conversion.ts index f93e948..56bbefb 100644 --- a/src/services/tech-record-document-conversion.ts +++ b/src/services/tech-record-document-conversion.ts @@ -28,6 +28,7 @@ import { ADR_PRODUCTLISTUNNO_TABLE, ADR_TC3DETAILS_TABLE, ADR_TANK_DOCUMENTS_TABLE, + ADR_PASS_CERTIFICATE_DETAILS, } from "./table-details"; import { deleteBasedOnWhereIn, @@ -229,9 +230,15 @@ const upsertTechRecords = async ( techRecordId, techRecord ); + await upsertAdrPassCertificateDetails( + techRecordConnection, + techRecordId, + techRecord + ); // upsert adr-details if (techRecord.adrDetails) { + debugLog(`upsertTechRecords: Upserting ADR Details...`); const adrResponse = await executeFullUpsert( ADR_DETAILS_TABLE, [ @@ -278,6 +285,10 @@ const upsertTechRecords = async ( const adrDetailsId = adrResponse.rows.insertId; + debugLog( + `upsertTechRecords: Upserted ADR Details (ID: ${adrDetailsId})` + ); + await upsertAdrMemosApply( techRecordConnection, adrDetailsId, @@ -313,6 +324,8 @@ const upsertTechRecords = async ( // adrDetailsId, // techRecord // ); + + debugLog(`upsertTechRecords: Upsert ADR Details END`); } await techRecordConnection.commit(); @@ -760,11 +773,13 @@ const upsertAdrDangerousGoodsList = async ( connection: Connection, dangerousGoodsName: string ): Promise => { - debugLog(`upsertTechRecords: Selecting/Upserting adr_dangerous_goods_list...`); + debugLog( + `upsertTechRecords: Selecting/Upserting adr_dangerous_goods_list...` + ); const response = await executePartialUpsertIfNotExistsWithCondition( ADR_DANGEROUS_GOODS_LIST_TABLE, - {name: dangerousGoodsName}, + { name: dangerousGoodsName }, connection ); @@ -814,7 +829,7 @@ const upsertAdrProductListUnNoList = async ( const response = await executePartialUpsertIfNotExistsWithCondition( ADR_PRODUCTLISTUNNO_LIST_TABLE, - {name: productListUnNo}, + { name: productListUnNo }, connection ); @@ -968,3 +983,34 @@ const upsertAdrTankDocuments = async ( } return; }; + +const upsertAdrPassCertificateDetails = async ( + connection: Connection, + techRecordId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrCertificateDetails) { + debugLog( + `upsertTechRecords: Upserting ADR Pass Certificate Details (tech-record-id: ${techRecordId})...` + ); + + for (const adrCertificateDetails of techRecord.adrCertificateDetails) { + const response = await executeFullUpsert( + ADR_PASS_CERTIFICATE_DETAILS, + [ + techRecordId, + adrCertificateDetails.createdByName, + adrCertificateDetails.certificateType, + adrCertificateDetails.generatedTimestamp, + adrCertificateDetails.certificateId, + ], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR Pass Certificate Details (tech-record-id: ${techRecordId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json index a1922e2..e22e5bb 100644 --- a/tests/resources/dynamodb-image-technical-record-with-adr.json +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -242,7 +242,7 @@ } }, "weight": { - "N": "6789" + "N": "7.50" } } }, diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index 97c4fbb..6680e12 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -7,7 +7,7 @@ import { default as techRecordDocumentJson } from "../../resources/dynamodb-imag import { castToImageShape } from "../../utils"; describe("parseTechRecordDocument()", () => { - it("should successfully parse a DynamoDB image with ADR into a TechRecordDocument", () => { + it("should successfully parse a DynamoDB image with ADR into a TechRecordDocument", async () => { const image = DynamoDbImage.parse(castToImageShape(techRecordDocumentJson)); const techRecordDocument: TechRecordDocument = parseTechRecordDocument( @@ -114,11 +114,11 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); - expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(6789); + expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(7.50); }); - it("should successfully parse a DynamoDB image, with ADR, with no authIntoService, into a TechRecordDocument", () => { + it("should successfully parse a DynamoDB image, with ADR, with no authIntoService, into a TechRecordDocument", async () => { // @ts-ignore delete techRecordDocumentJson.techRecord.L[0].M.authIntoService; const image = DynamoDbImage.parse(castToImageShape(techRecordDocumentJson)); @@ -225,7 +225,7 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); - expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(6789); + expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(7.50); }); }); From 7803cc3c7d1e9b7dce506f309d133a529530a5cd Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 9 Feb 2024 09:54:13 +0000 Subject: [PATCH 25/44] feat: cleaning and bringing in adr pass certificate --- tests/integration/tech-record-document-conversion.intTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/tech-record-document-conversion.intTest.ts b/tests/integration/tech-record-document-conversion.intTest.ts index 54654e9..10e75ac 100644 --- a/tests/integration/tech-record-document-conversion.intTest.ts +++ b/tests/integration/tech-record-document-conversion.intTest.ts @@ -645,7 +645,7 @@ export const techRecordDocumentConversion = () => "brakeDeclarationIssuer_1" ); expect(adrDetailsResultSet.rows[0].brakeEndurance).toEqual(0); - expect(adrDetailsResultSet.rows[0].weight).toEqual(6789); + expect(adrDetailsResultSet.rows[0].weight).toEqual("7.50"); expect(adrDetailsResultSet.rows[0].compatibilityGroupJ).toEqual("I"); expect(adrDetailsResultSet.rows[0].applicantDetailsName).toEqual( "applicantDetails_Name" From 11d4cb39ae720085653fcd2d2a9c4f4c5cac4361 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 9 Feb 2024 09:55:09 +0000 Subject: [PATCH 26/44] fix: removed async keyword to avoid error when running the test --- .../integration/test-results-conversion-with-delete.intTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test-results-conversion-with-delete.intTest.ts b/tests/integration/test-results-conversion-with-delete.intTest.ts index 2956024..516b3db 100644 --- a/tests/integration/test-results-conversion-with-delete.intTest.ts +++ b/tests/integration/test-results-conversion-with-delete.intTest.ts @@ -12,7 +12,7 @@ import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; useLocalDb(); export const testResultsConversionWithDelete = () => - describe("convertTestResults() integration tests with delete", async () => { + describe("convertTestResults() integration tests with delete", () => { let container: StartedTestContainer; const testResultsJson = JSON.parse( JSON.stringify(require("../resources/dynamodb-image-test-results.json")) From a4efb62b3650575cece48b293690c0df02eb7485 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 9 Feb 2024 09:56:26 +0000 Subject: [PATCH 27/44] fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo --- tests/resources/Dockerfile | 2 +- tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/resources/Dockerfile b/tests/resources/Dockerfile index b6d6a32..a655315 100644 --- a/tests/resources/Dockerfile +++ b/tests/resources/Dockerfile @@ -1,5 +1,5 @@ # Match Aurora MySQL version as closely as possible -FROM mysql:5.7.12 +FROM mysql:8.0.32 ENV MYSQL_DATABASE=CVSBNOP \ MYSQL_ROOT_PASSWORD=12345 diff --git a/tsconfig.json b/tsconfig.json index cf02692..40e85ba 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,6 @@ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, - "types": [] + "types": ["zest", "node"] } } From c6047516a1771a6395f4d3461d9dbb7a4aad4fa7 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 9 Feb 2024 09:58:52 +0000 Subject: [PATCH 28/44] fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 40e85ba..b5af863 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,6 @@ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, - "types": ["zest", "node"] + "types": ["jest", "node"] } } From d433a3c932473289b5feb03c26977d106f614628 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Fri, 9 Feb 2024 10:03:25 +0000 Subject: [PATCH 29/44] fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo --- tests/resources/Dockerfile | 2 +- tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/resources/Dockerfile b/tests/resources/Dockerfile index b6d6a32..a655315 100644 --- a/tests/resources/Dockerfile +++ b/tests/resources/Dockerfile @@ -1,5 +1,5 @@ # Match Aurora MySQL version as closely as possible -FROM mysql:5.7.12 +FROM mysql:8.0.32 ENV MYSQL_DATABASE=CVSBNOP \ MYSQL_ROOT_PASSWORD=12345 diff --git a/tsconfig.json b/tsconfig.json index cf02692..b5af863 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,6 @@ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, - "types": [] + "types": ["jest", "node"] } } From 7c9f140f021722ef1db1eccbcc248d6f8f10b3d0 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 12 Feb 2024 14:22:23 +0000 Subject: [PATCH 30/44] fix: updating adr pass certificate function --- src/models/adr-certificate-details.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/adr-certificate-details.ts b/src/models/adr-certificate-details.ts index 89a88d5..804ca51 100644 --- a/src/models/adr-certificate-details.ts +++ b/src/models/adr-certificate-details.ts @@ -33,7 +33,7 @@ export const parseAdrCertificateDetails = ( certificateType: adrPassCertificateDetailsItemImage.getString( "certificateType" ) as AdrPassCertificateTypeEnum, - generatedTimestamp: adrPassCertificateDetailsItemImage.getString( + generatedTimestamp: adrPassCertificateDetailsItemImage.getDate( "generatedTimestamp" ), certificateId: adrPassCertificateDetailsItemImage.getString( From cbf62ab877334abe6e62817e961d77ec7bb46ac3 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 12 Feb 2024 14:23:16 +0000 Subject: [PATCH 31/44] fix: updating adr pass certificate field name --- src/models/tech-record.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/tech-record.ts b/src/models/tech-record.ts index ace894b..a4aa00a 100644 --- a/src/models/tech-record.ts +++ b/src/models/tech-record.ts @@ -118,7 +118,7 @@ export interface TechRecord { noOfAxles?: number; brakeCode?: string; adrDetails?: AdrDetails; - adrCertificateDetails?: AdrPassCertificateDetails; + adrPassCertificateDetails?: AdrPassCertificateDetails; createdByName?: string; createdById?: string; lastUpdatedByName?: string; @@ -276,7 +276,7 @@ const parseTechRecord = (image: DynamoDbImage): TechRecord => { noOfAxles: image.getNumber("noOfAxles"), brakeCode: image.getString("brakeCode"), adrDetails: parseAdrDetails(image.getMap("adrDetails")), - adrCertificateDetails: parseAdrCertificateDetails( + adrPassCertificateDetails: parseAdrCertificateDetails( image.getList("adrPassCertificateDetails") ), createdByName: image.getString("createdByName"), From 9a1ca1c29e5523a0814f1498aa27a28dfd4fb150 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 12 Feb 2024 14:24:56 +0000 Subject: [PATCH 32/44] fix: updating adr pass certificate var name --- src/services/tech-record-document-conversion.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/services/tech-record-document-conversion.ts b/src/services/tech-record-document-conversion.ts index 56bbefb..da021c4 100644 --- a/src/services/tech-record-document-conversion.ts +++ b/src/services/tech-record-document-conversion.ts @@ -989,20 +989,20 @@ const upsertAdrPassCertificateDetails = async ( techRecordId: string, techRecord: TechRecord ): Promise => { - if (techRecord.adrCertificateDetails) { + if (techRecord.adrPassCertificateDetails) { debugLog( `upsertTechRecords: Upserting ADR Pass Certificate Details (tech-record-id: ${techRecordId})...` ); - for (const adrCertificateDetails of techRecord.adrCertificateDetails) { + for (const adrPassCertificateDetails of techRecord.adrPassCertificateDetails) { const response = await executeFullUpsert( ADR_PASS_CERTIFICATE_DETAILS, [ techRecordId, - adrCertificateDetails.createdByName, - adrCertificateDetails.certificateType, - adrCertificateDetails.generatedTimestamp, - adrCertificateDetails.certificateId, + adrPassCertificateDetails.createdByName, + adrPassCertificateDetails.certificateType, + adrPassCertificateDetails.generatedTimestamp, + adrPassCertificateDetails.certificateId, ], connection ); From 0514dc3bda3986c6ba4f980832170309e55bd626 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 12 Feb 2024 14:26:12 +0000 Subject: [PATCH 33/44] feat: adding integration tests for additional test scenarios --- ...tech-record-document-conversion.intTest.ts | 381 ++++++++++++++++++ 1 file changed, 381 insertions(+) diff --git a/tests/integration/tech-record-document-conversion.intTest.ts b/tests/integration/tech-record-document-conversion.intTest.ts index 10e75ac..d661582 100644 --- a/tests/integration/tech-record-document-conversion.intTest.ts +++ b/tests/integration/tech-record-document-conversion.intTest.ts @@ -591,6 +591,33 @@ export const techRecordDocumentConversion = () => (authIntoServiceResultSet.rows[0].dateRejected as Date).toUTCString() ).toEqual("Tue, 05 May 2020 00:00:00 GMT"); + const adrPassCertificateDetailsResultSet = await executeSql( + `SELECT \`technical_record_id\`, + \`createdByName\`, + \`certificateType\`, + \`generatedTimestamp\`, + \`certificateId\` + FROM \`adr_PassCertificateDetails\` + WHERE \`adr_PassCertificateDetails\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrPassCertificateDetailsResultSet.rows.length).toEqual(1); + expect( + adrPassCertificateDetailsResultSet.rows[0].technical_record_id + ).toEqual(technicalRecordId); + expect(adrPassCertificateDetailsResultSet.rows[0].createdByName).toEqual( + "CREATED-BY-NAME-01" + ); + expect( + adrPassCertificateDetailsResultSet.rows[0].certificateType + ).toEqual("PASS"); + expect( + (adrPassCertificateDetailsResultSet.rows[0].generatedTimestamp as Date) + .toISOString() + ).toEqual("2023-04-01T01:49:00.000Z"); + expect(adrPassCertificateDetailsResultSet.rows[0].certificateId).toEqual( + "CERTIFICATE-ID-1" + ); + // adr_details const adrDetailsResultSet = await executeSql( `SELECT \`id\`, @@ -838,6 +865,141 @@ export const techRecordDocumentConversion = () => expect(adrAdditionalNotesNumberResultSet.rows[1].number).toEqual("T1B"); }); + it("should reject to insert same tech-record record into database", async () => { + const event = { + Records: [ + { + body: JSON.stringify({ + eventSourceARN: + "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T01:00:00.000", + eventName: "INSERT", + dynamodb: { + NewImage: techRecordDocumentJsonWithADR, + }, + }), + }, + ], + }; + + // array of arrays: event contains array of records, each with array of tech record entities + await processStreamEvent(event, exampleContext(), () => { + return; + }); + + const vehicleResultSet = await executeSql(`SELECT * FROM \`vehicle\``); + expect(vehicleResultSet.rows.length).toEqual(1); + + const technicalRecordSet = await executeSql( + `SELECT * FROM \`technical_record\`` + ); + expect(technicalRecordSet.rows.length).toEqual(1); + + const makeModelResultSet = await executeSql( + `SELECT * FROM \`make_model\`` + ); + expect(makeModelResultSet.rows.length).toEqual(1); + + const vehicleClassResultSet = await executeSql( + `SELECT * FROM \`vehicle_class\`` + ); + expect(vehicleClassResultSet.rows.length).toEqual(1); + + const { + make_model_id, + vehicle_class_id, + createdBy_Id, + lastUpdatedBy_Id, + applicant_detail_id, + purchaser_detail_id, + manufacturer_detail_id, + } = technicalRecordSet.rows[0]; + + const createdByResultSet = await executeSql( + `SELECT * FROM \`identity\` + WHERE \`identity\`.\`id\` IN (${lastUpdatedBy_Id}, ${createdBy_Id})` + ); + expect(createdByResultSet.rows.length).toEqual(2); + + const contactDetailsResultSet = await executeSql( + `SELECT * FROM \`contact_details\`` + ); + expect(contactDetailsResultSet.rows.length).toEqual(1); + + const techRecordResultSet = await executeSql( + `SELECT * FROM \`technical_record\`` + ); + expect(techRecordResultSet.rows.length).toEqual(1); + + const brakesResultSet = await executeSql(`SELECT * FROM \`psv_brakes\``); + expect(brakesResultSet.rows.length).toEqual(1); + + const axleSpacingResultSet = await executeSql( + `SELECT * FROM \`axle_spacing\`` + ); + expect(axleSpacingResultSet.rows.length).toEqual(1); + + const microfilmResultSet = await executeSql( + `SELECT * FROM \`microfilm\`` + ); + expect(microfilmResultSet.rows.length).toEqual(1); + + const platesResultSet = await executeSql(`SELECT * FROM \`plate\``); + expect(platesResultSet.rows.length).toEqual(1); + + const axlesResultSet = await executeSql(`SELECT * FROM \`axles\``); + expect(axlesResultSet.rows.length).toEqual(1); + + const authIntoServiceResultSet = await executeSql( + `SELECT * FROM \`auth_into_service\`` + ); + expect(authIntoServiceResultSet.rows.length).toEqual(1); + + const adrDetailsResultSet = await executeSql( + `SELECT * FROM \`adr_details\`` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + + const adrMemosApplyResultSet = await executeSql( + `SELECT * FROM \`adr_memos_apply\`` + ); + expect(adrMemosApplyResultSet.rows.length).toEqual(2); // With current logic, this gets duplicated + + const adrDangerousGoodsListResultSet = await executeSql( + `SELECT * FROM \`adr_dangerous_goods_list\`` + ); + expect(adrDangerousGoodsListResultSet.rows.length).toEqual(3); + + const adrPermittedDangerousGoodsResultSet = await executeSql( + `SELECT * FROM \`adr_permitted_dangerous_goods\`` + ); + expect(adrPermittedDangerousGoodsResultSet.rows.length).toEqual(6); // With current logic, this gets duplicated + + const adrProductListUnNoListResultSet = await executeSql( + `SELECT * FROM \`adr_productListUnNo_list\`` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + const adrProductListUnNoResultSet = await executeSql( + `SELECT * FROM \`adr_productListUnNo\`` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(6); // With current logic, this gets duplicated + + const adrTc3DetailsResultSet = await executeSql( + `SELECT * FROM \`adr_tc3Details\`` + ); + expect(adrTc3DetailsResultSet.rows.length).toEqual(2); // With current logic, this gets duplicated + + const adrAdditionalExaminerNotesResultSet = await executeSql( + `SELECT * FROM \`adr_additional_examiner_notes\`` + ); + expect(adrAdditionalExaminerNotesResultSet.rows.length).toEqual(2); // With current logic, this gets duplicated + + const adrAdditionalNotesNumberResultSet = await executeSql( + `SELECT * FROM \`adr_additional_notes_number\`` + ); + expect(adrAdditionalNotesNumberResultSet.rows.length).toEqual(4); + }); + describe("when adding a new vehicle and changing VRM to a new value, VRM should change on existing vehicle.", () => { it("A new vehicle is present", async () => { // arrange - create a record so we can later query for it and assert for is existence @@ -931,4 +1093,223 @@ export const techRecordDocumentConversion = () => ).not.toBeNull(); // todo This returns null }); }); + + describe("when adding a new vehicle and changing some ADR attributes to a new values, those fields are changed on ADR tables.", () => { + it("A new vehicle is created", async () => { + // arrange - create a record so we can later query for it and assert for is existence + const techRecordDocumentJsonNew = JSON.parse( + JSON.stringify(techRecordDocumentJsonWithADR) + ); + techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-3" }; + techRecordDocumentJsonNew.vin = { S: "VIN3" }; + techRecordDocumentJsonNew.primaryVrm = { S: "VRM3" }; + + // productListUnNo removed from payload + delete techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M + .tank.M.tankStatement.M.productListUnNo; + + const event = { + Records: [ + { + body: JSON.stringify({ + eventSourceARN: + "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T00:00:00.000", + eventName: "INSERT", + dynamodb: { + NewImage: techRecordDocumentJsonNew, + }, + }), + }, + ], + }; + // array of arrays: event contains array of records, each with array of tech record entities + await processStreamEvent(event, exampleContext(), () => { + return; + }); + + const vehicleResultSet = await executeSql( + `SELECT \`system_number\`, \`vin\`, \`vrm_trm\`, \`trailer_id\`, \`createdAt\`, \`id\` + FROM \`vehicle\` + WHERE \`system_number\` = "SYSTEM-NUMBER-3"` + ); + + expect(vehicleResultSet.rows.length).toEqual(1); + expect(vehicleResultSet.rows[0].system_number).toEqual( + "SYSTEM-NUMBER-3" + ); + expect(vehicleResultSet.rows[0].vin).toEqual("VIN3"); + expect(vehicleResultSet.rows[0].vrm_trm).toEqual("VRM3"); + expect(vehicleResultSet.rows[0].trailer_id).toEqual("TRL-1"); + expect( + (vehicleResultSet.rows[0].createdAt as Date).toUTCString() + ).not.toBeNull(); // todo This returns null + + const vehicleId = vehicleResultSet.rows[0].id; + + const technicalRecordSet = await executeSql( + `SELECT * + FROM \`technical_record\` + WHERE \`technical_record\`.\`vehicle_id\` = ${vehicleId}` + ); + + expect(technicalRecordSet.rows.length).toEqual(1); + + const technicalRecordId = technicalRecordSet.rows[0].id; + + // check data in adr_details is updated and get adrDetailsId + const adrDetailsResultSet = await executeSql( + `SELECT * + FROM \`adr_details\` + WHERE \`adr_details\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + expect(adrDetailsResultSet.rows[0].technical_record_id).toEqual( + technicalRecordId + ); + + const adrDetailsId = adrDetailsResultSet.rows[0].id; + + // adr_productListUnNo_list + const adrProductListUnNoListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_productListUnNo_list\`` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + // adr_productListUnNo (There shouldn't be any record for this) + const adrProductListUnNoResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_productListUnNo_list_id\` + FROM \`adr_productListUnNo\` + WHERE \`adr_productListUnNo\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(0); + }); + + it("Some ADR attributes have been changed", async () => { + const techRecordDocumentJsonNew = JSON.parse( + JSON.stringify(techRecordDocumentJsonWithADR) + ); + techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-3" }; + techRecordDocumentJsonNew.vin = { S: "VIN3" }; + techRecordDocumentJsonNew.primaryVrm = { S: "VRM3" }; + + // update an already existing list into a different list + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.additionalNotes.M.number = { + L: [{ S: "1" }, { S: "V1B" }], + }; + // update an already existing string to a NULL value + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.adrCertificateNotes = { NULL: true }; + // update an already existing string to a different string + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankDetails.M.tankManufacturer = { + S: "different_tankManufacturer", + }; + // update missing attribute to NULL + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetailsM.tank.M.tankStatement.M.productListUnNo = { NULL: true }; + + const event = { + Records: [ + { + body: JSON.stringify({ + eventSourceARN: + "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T02:00:00.000", + eventName: "INSERT", + dynamodb: { + NewImage: techRecordDocumentJsonNew, + }, + }), + }, + ], + }; + // array of arrays: event contains array of records, each with array of tech record entities + await processStreamEvent(event, exampleContext(), () => { + return; + }); + + // check if vehicle table is intact and get vehicleId + const vehicleResultSet = await executeSql( + `SELECT \`system_number\`, \`vin\`, \`vrm_trm\`, \`trailer_id\`, \`createdAt\`, \`id\` + FROM \`vehicle\` + WHERE \`vehicle\`.\`system_number\` = "SYSTEM-NUMBER-3"` + ); + + expect(vehicleResultSet.rows.length).toEqual(1); + expect(vehicleResultSet.rows[0].system_number).toEqual( + "SYSTEM-NUMBER-3" + ); + expect(vehicleResultSet.rows[0].vin).toEqual("VIN3"); + expect(vehicleResultSet.rows[0].vrm_trm).toEqual("VRM3"); + expect(vehicleResultSet.rows[0].trailer_id).toEqual("TRL-1"); + expect( + (vehicleResultSet.rows[0].createdAt as Date).toUTCString() + ).not.toBeNull(); // todo This returns null + + const vehicleId = vehicleResultSet.rows[0].id; + + // check if technical_record table is intact and get technicalRecordId + const technicalRecordSet = await executeSql( + `SELECT \`make_model_id\`, \`vehicle_class_id\`, \`createdBy_Id\`, \`lastUpdatedBy_Id\`, \`applicant_detail_id\`, \`purchaser_detail_id\`, \`manufacturer_detail_id\`, \`id\`, \`createdAt\` + FROM \`technical_record\` + WHERE \`technical_record\`.\`vehicle_id\` = ${vehicleId}` + ); + + expect(technicalRecordSet.rows.length).toEqual(1); + expect( + (technicalRecordSet.rows[0].createdAt as Date).toISOString() + ).toEqual("2020-01-01T00:00:00.055Z"); + + const technicalRecordId = technicalRecordSet.rows[0].id; + + // check data in adr_details is updated and get adrDetailsId + const adrDetailsResultSet = await executeSql( + `SELECT * FROM \`adr_details\` + WHERE \`adr_details\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + expect(adrDetailsResultSet.rows[0].technical_record_id).toEqual( + technicalRecordId + ); + expect(adrDetailsResultSet.rows[0].adrCertificateNotes).toBeNull(); + expect(adrDetailsResultSet.rows[0].tankManufacturer).toEqual( + "different_tankManufacturer" + ); // is this gonna create an orphaned row? + + const adrDetailsId = adrDetailsResultSet.rows[0].id; + + // check data in adr_additional_notes_number is updated + const adrAdditionalNotesNumberResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`number\` + FROM \`adr_additional_notes_number\` + WHERE \`adr_additional_notes_number\`.\`adr_details_id\` = ${adrDetailsId}` + ); + // With current logic, this will create orphan rows + expect(adrAdditionalNotesNumberResultSet.rows.length).toEqual(4); + expect( + adrAdditionalNotesNumberResultSet.rows[0].adr_details_id + ).toEqual(adrDetailsId); + expect(adrAdditionalNotesNumberResultSet.rows[0].number).toEqual("1"); // orphaned row + expect(adrAdditionalNotesNumberResultSet.rows[1].number).toEqual("T1B"); // orphaned row + expect(adrAdditionalNotesNumberResultSet.rows[2].number).toEqual("1"); + expect(adrAdditionalNotesNumberResultSet.rows[3].number).toEqual("V1B"); + + // adr_productListUnNo_list + const adrProductListUnNoListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_productListUnNo_list\`` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + // adr_productListUnNo (There still shouldn't be any record for this) + const adrProductListUnNoResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_productListUnNo_list_id\` + FROM \`adr_productListUnNo\` + WHERE \`adr_productListUnNo\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(0); + }); + }); }); From f833b02fb2ba66f2b8eae01c8d54e74f378df18b Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 12 Feb 2024 14:27:07 +0000 Subject: [PATCH 34/44] feat: adding adr pass certificate attribute --- ...amodb-image-technical-record-with-adr.json | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json index e22e5bb..0341ca3 100644 --- a/tests/resources/dynamodb-image-technical-record-with-adr.json +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -25,6 +25,26 @@ "L": [ { "M": { + "adrPassCertificateDetails": { + "L": [ + { + "M": { + "certificateId": { + "S": "CERTIFICATE-ID-1" + }, + "createdByName": { + "S": "CREATED-BY-NAME-01" + }, + "certificateType": { + "S": "PASS" + }, + "generatedTimestamp": { + "S": "2023-04-01T01:49:00.055Z" + } + } + } + ] + }, "adrDetails": { "M": { "additionalExaminerNotes": { From 64f8c638b4a95ef234d2702b4d2face9d88d37d6 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 12 Feb 2024 14:29:09 +0000 Subject: [PATCH 35/44] feat: adding adr pass certificate attribute test to unit test --- tests/unit/models/tech-record-document.unitTest.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index 6680e12..1ee94fc 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -53,6 +53,11 @@ describe("parseTechRecordDocument()", () => { ); expect(techRecordDocument.techRecord![0].axles![0].axleNumber).toEqual(1); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateId).toEqual("CERTIFICATE-ID-1"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].createdByName).toEqual("CREATED-BY-NAME-01"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateType).toEqual("PASS"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].generatedTimestamp).toEqual("2023-04-01 01:49:00.055"); + // ADR Details attributes expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].note).toEqual("additionalExaminerNotes_note_1"); expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].createdAtDate).toEqual("2023-05-30"); @@ -164,6 +169,11 @@ describe("parseTechRecordDocument()", () => { ); expect(techRecordDocument.techRecord![0].axles![0].axleNumber).toEqual(1); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateId).toEqual("CERTIFICATE-ID-1"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].createdByName).toEqual("CREATED-BY-NAME-01"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateType).toEqual("PASS"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].generatedTimestamp).toEqual("2023-04-01 01:49:00.055"); + // ADR Details attributes expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].note).toEqual("additionalExaminerNotes_note_1"); expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].createdAtDate).toEqual("2023-05-30"); From fb74bdcf74f6be8500580d8b3ac85f50b6c3257e Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Mon, 12 Feb 2024 14:32:33 +0000 Subject: [PATCH 36/44] fix: syntax fixed --- tests/integration/tech-record-document-conversion.intTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/tech-record-document-conversion.intTest.ts b/tests/integration/tech-record-document-conversion.intTest.ts index d661582..cbc4b7a 100644 --- a/tests/integration/tech-record-document-conversion.intTest.ts +++ b/tests/integration/tech-record-document-conversion.intTest.ts @@ -1206,7 +1206,7 @@ export const techRecordDocumentConversion = () => S: "different_tankManufacturer", }; // update missing attribute to NULL - techRecordDocumentJsonNew.techRecord.L[0].M.adrDetailsM.tank.M.tankStatement.M.productListUnNo = { NULL: true }; + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankStatement.M.productListUnNo = { NULL: true }; const event = { Records: [ From 577351f60c3891a5148661b268b3d408288abc16 Mon Sep 17 00:00:00 2001 From: DanielFry-bjss <135820353+DanielFry-bjss@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:20:40 +0000 Subject: [PATCH 37/44] Feature/cb2 10594 (#80) * rectifying data type mismatches, add un-defined Enums and attributes, adding in-line comments * add AdrCertificateDetails interface and parsing function * adding guidanceNotes Enum * adding m145 attribute as per documentation change * feat: adr details added, test resource for technoical record added, unit test added * style: rearrange enums * fix: replace ! with ? for optional attributes * fix: memosApplyEnum value updated * fix: 2 new attributes added to adrDetails, as per documentation * feat: tab le definition * fix: enum updated * feat: adr tables added to the tech record list of tables * feat: new function added for partial upsert based on condition attribute * feat: some adr table detail updated * feat: upsert fun ctionality added for adr-details attributes in tech record * feat: adr parts added to tech record integration test * feat: docker's mysql image updated to version 8 - consistent with recent RDS engine upgarde for NOP * feat: adr attribute values updated * feat: test updated as adr attribute values updated in json file * fix: changes reverted back to original * fix: changes reverted back to original * fix: changes reverted back to original * feat: cleaning and bringing in adr pass certificate * feat: cleaning and bringing in adr pass certificate * feat: cleaning and bringing in adr pass certificate * fix: removed async keyword to avoid error when running the test * fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo * fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo * fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo * fix: updating adr pass certificate function * fix: updating adr pass certificate field name * fix: updating adr pass certificate var name * feat: adding integration tests for additional test scenarios * feat: adding adr pass certificate attribute * feat: adding adr pass certificate attribute test to unit test * fix: syntax fixed --------- Co-authored-by: Meys Torkaman Co-authored-by: meys-bjss <140601718+meys-bjss@users.noreply.github.com> --- README.md | 7 + src/models/adr-certificate-details.ts | 45 + src/models/adr-details.ts | 153 ++- src/models/tech-record.ts | 12 +- src/services/sql-execution.ts | 34 + src/services/table-details.ts | 113 +++ .../tech-record-document-conversion.ts | 380 ++++++++ ...tech-record-document-conversion.intTest.ts | 637 ++++++++++++- ...-results-conversion-with-delete.intTest.ts | 2 +- tests/resources/Dockerfile | 2 +- ...amodb-image-technical-record-with-adr.json | 871 ++++++++++++++++++ .../models/tech-record-document.unitTest.ts | 144 ++- tsconfig.json | 2 +- 13 files changed, 2361 insertions(+), 41 deletions(-) create mode 100644 src/models/adr-certificate-details.ts create mode 100644 tests/resources/dynamodb-image-technical-record-with-adr.json diff --git a/README.md b/README.md index 11544e1..4218964 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,13 @@ For the full field-to-column mapping, see `tech-record-document-conversion.ts`. * `microfilm` * `plate` * `axle` + * `adr_details` + * `adr_memos_apply` + * `adr_permitted_dangerous_goods` + * `adr_productListUnNo` + * `adr_additional_examiner_notes` + * `adr_additional_notes_number` + ## Test Result conversion For the full field-to-column mapping, see `test-result-record-conversion.ts`. diff --git a/src/models/adr-certificate-details.ts b/src/models/adr-certificate-details.ts new file mode 100644 index 0000000..804ca51 --- /dev/null +++ b/src/models/adr-certificate-details.ts @@ -0,0 +1,45 @@ +import { DynamoDbImage } from "../services/dynamodb-images"; +import { Maybe } from "./optionals"; + +// define Enums +export type AdrPassCertificateTypeEnum = "PASS" | "REPLACEMENT"; + +export type AdrPassCertificateDetails = AdrPassCertificateDetailsItems[]; + +export interface AdrPassCertificateDetailsItems { + createdByName?: string; + certificateType?: AdrPassCertificateTypeEnum; + generatedTimestamp?: string; + certificateId?: string; +} + +export const parseAdrCertificateDetails = ( + adrPassCertificateDetailsImage?: DynamoDbImage +): Maybe => { + if (!adrPassCertificateDetailsImage) { + return undefined; + } + + const adrPassCertificateDetails: AdrPassCertificateDetails = []; + + for (const key of adrPassCertificateDetailsImage.getKeys()) { + const adrPassCertificateDetailsItemImage = adrPassCertificateDetailsImage.getMap( + key + )!; + adrPassCertificateDetails.push({ + createdByName: adrPassCertificateDetailsItemImage.getString( + "createdByName" + ), + certificateType: adrPassCertificateDetailsItemImage.getString( + "certificateType" + ) as AdrPassCertificateTypeEnum, + generatedTimestamp: adrPassCertificateDetailsItemImage.getDate( + "generatedTimestamp" + ), + certificateId: adrPassCertificateDetailsItemImage.getString( + "certificateId" + ), + }); + } + return adrPassCertificateDetails; +}; diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index 7767fee..36db7db 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -1,6 +1,7 @@ import { DynamoDbImage, parseStringArray } from "../services/dynamodb-images"; import { Maybe } from "./optionals"; +// define AdrDetails' high-level attributes data types export interface AdrDetails { vehicleDetails?: VehicleDetails; listStatementApplicable?: boolean; @@ -9,24 +10,101 @@ export interface AdrDetails { brakeDeclarationsSeen?: boolean; brakeDeclarationIssuer?: string; brakeEndurance?: boolean; - weight?: string; - compatibilityGroupJ?: boolean; + weight?: number; + newCertificateRequested?: boolean; + compatibilityGroupJ?: compatibilityGroupJEnum; documents?: string[]; - permittedDangerousGoods?: string[]; - additionalExaminerNotes?: string; + permittedDangerousGoods?: permittedDangerousGoodsEnum[]; + additionalExaminerNotes?: AdditionalExaminerNotes; applicantDetails?: ApplicantDetails; - memosApply?: string[]; + dangerousGoods?: boolean; + memosApply?: memosApplyEnum[]; + m145Statement?: boolean; additionalNotes?: AdditionalNotes; adrTypeApprovalNo?: string; adrCertificateNotes?: string; tank?: Tank; } +// define Enums +export type VehicleDetailsTypeEnum = + | "Artic tractor" + | "Rigid box body" + | "Rigid sheeted load" + | "Rigid tank" + | "Rigid skeletal" + | "Rigid battery" + | "Full drawbar box body" + | "Full drawbar sheeted load" + | "Full drawbar tank" + | "Full drawbar skeletal" + | "Full drawbar battery" + | "Centre axle box body" + | "Centre axle sheeted load" + | "Centre axle tank" + | "Centre axle skeletal" + | "Centre axle battery" + | "Semi trailer box body" + | "Semi trailer sheeted load" + | "Semi trailer tank" + | "Semi trailer skeletal" + | "Semi trailer battery"; + +export type Tc2TypeEnum = "initial"; + +export type Tc3TypeEnum = + | "intermediate" + | "periodic" + | "exceptional"; + +export type permittedDangerousGoodsEnum = + | "FP <61 (FL)" + | "AT" + | "Class 5.1 Hydrogen Peroxide (OX)" + | "MEMU" + | "Carbon Disulphide" + | "Hydrogen" + | "Explosives (type 2)" + | "Explosives (type 3)"; + +export type compatibilityGroupJEnum = + | "I" + | "E"; + +export type additionalNotesNumberEnum = + | "1" + | "1A" + | "2" + | "3" + | "V1B" + | "T1B"; + +// export type additionalNotesguidanceNotesEnum = "New certificate requested" | "M145 Statement" + +export type substancesPermittedEnum = + | "Substances permitted under the tank code and any special provisions specified in 9 may be carried" + | "Substances (Class UN number and if necessary packing group and proper shipping name) may be carried"; + +export type memosApplyEnum = "07/09 3mth leak ext "; + +export type tankStatementSelectEnum = + | "Statement" + | "Product list"; + +// define AdrDetails' sub-attributes data types export interface VehicleDetails { - type?: string; + type?: VehicleDetailsTypeEnum; approvalDate?: string; } +export type AdditionalExaminerNotes = AdditionalExaminerNotesItems[]; + +export interface AdditionalExaminerNotesItems { + note?: string; + createdAtDate?: string; + lastUpdatedBy?: string; +} + export interface ApplicantDetails { name?: string; street?: string; @@ -36,8 +114,8 @@ export interface ApplicantDetails { } export interface AdditionalNotes { - number?: string[]; - guidanceNotes?: string[]; + number?: additionalNotesNumberEnum[]; + // guidanceNotes?: additionalNotesguidanceNotesEnum[]; } export interface Tank { @@ -57,7 +135,8 @@ export interface TankDetails { } export interface TankStatement { - substancesPermitted?: string; + select?: tankStatementSelectEnum; + substancesPermitted?: substancesPermittedEnum; statement?: string; productListRefNo?: string; productListUnNo?: string[]; @@ -65,23 +144,21 @@ export interface TankStatement { } export interface Tc2Details { - tc2Type?: Tc2Type; + tc2Type?: Tc2TypeEnum; tc2IntermediateApprovalNo?: string; tc2IntermediateExpiryDate?: string; } -export type Tc2Type = "initial"; export type Tc3Details = Tc3DetailsItem[]; export interface Tc3DetailsItem { - tc3Type?: Tc3Type; + tc3Type?: Tc3TypeEnum; tc3PeriodicNumber?: string; tc3PeriodicExpiryDate?: string; } -export type Tc3Type = "intermediate" | "periodic" | "exceptional"; - +// function to parse AdrDetails' high-level and sub attributes + return AdrDetails object export const parseAdrDetails = ( adrDetails?: DynamoDbImage ): Maybe => { @@ -93,10 +170,10 @@ export const parseAdrDetails = ( "additionalNotes" )!; const additionalNotes: AdditionalNotes = { - number: parseStringArray(additionalNotesImage.getList("number")), - guidanceNotes: parseStringArray( - additionalNotesImage.getList("guidanceNotes") - ), + number: parseStringArray(additionalNotesImage.getList("number")) as additionalNotesNumberEnum[], + // guidanceNotes: parseStringArray( + // additionalNotesImage.getList("guidanceNotes") + // ) as additionalNotesguidanceNotesEnum[], }; const applicantDetailsImage: DynamoDbImage = adrDetails.getMap( @@ -114,7 +191,7 @@ export const parseAdrDetails = ( "vehicleDetails" )!; const vehicleDetails: VehicleDetails = { - type: vehicleDetailsImage.getString("type"), + type: vehicleDetailsImage.getString("type") as VehicleDetailsTypeEnum, approvalDate: vehicleDetailsImage.getString("approvalDate"), }; @@ -124,7 +201,7 @@ export const parseAdrDetails = ( const tc2DetailsImage: DynamoDbImage = tankDetailsImage.getMap("tc2Details")!; const tc2Details: Tc2Details = { - tc2Type: tc2DetailsImage.getString("tc2Type") as Tc2Type, + tc2Type: tc2DetailsImage.getString("tc2Type") as Tc2TypeEnum, tc2IntermediateApprovalNo: tc2DetailsImage.getString( "tc2IntermediateApprovalNo" ), @@ -141,7 +218,7 @@ export const parseAdrDetails = ( for (const key of tc3DetailsImage.getKeys()) { const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; tc3Details.push({ - tc3Type: tc3DetailsItemImage.getString("tc3Type") as Tc3Type, + tc3Type: tc3DetailsItemImage.getString("tc3Type") as Tc3TypeEnum, tc3PeriodicNumber: tc3DetailsItemImage.getString("tc3PeriodicNumber"), tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( "tc3PeriodicExpiryDate" @@ -151,7 +228,7 @@ export const parseAdrDetails = ( const tankDetails: TankDetails = { tankManufacturer: tankDetailsImage.getString("tankManufacturer"), - yearOfManufacture: 0, + yearOfManufacture: tankDetailsImage.getNumber("yearOfManufacture"), tankCode: tankDetailsImage.getString("tankCode"), specialProvisions: tankDetailsImage.getString("specialProvisions"), tankManufacturerSerialNo: tankDetailsImage.getString( @@ -164,7 +241,8 @@ export const parseAdrDetails = ( const tankStatementImage: DynamoDbImage = tankImage.getMap("tankStatement")!; const tankStatement: TankStatement = { - substancesPermitted: tankStatementImage.getString("substancesPermitted"), + substancesPermitted: tankStatementImage.getString("substancesPermitted") as substancesPermittedEnum, + select: tankStatementImage.getString("select") as tankStatementSelectEnum, statement: tankStatementImage.getString("statement"), productListRefNo: tankStatementImage.getString("productListRefNo"), productListUnNo: parseStringArray( @@ -178,6 +256,22 @@ export const parseAdrDetails = ( tankStatement, }; + + const additionalExaminerNotesImage: DynamoDbImage = adrDetails.getList( + "additionalExaminerNotes" + )!; + const additionalExaminerNotes: AdditionalExaminerNotes = []; + + for (const key of additionalExaminerNotesImage.getKeys()) { + const additionalExaminerNotesItemImage = additionalExaminerNotesImage.getMap(key)!; + additionalExaminerNotes.push({ + note: additionalExaminerNotesItemImage.getString("note"), + createdAtDate: additionalExaminerNotesItemImage.getString("createdAtDate"), + lastUpdatedBy: additionalExaminerNotesItemImage.getString("lastUpdatedBy"), + }); + } + + return { vehicleDetails, listStatementApplicable: adrDetails.getBoolean("listStatementApplicable"), @@ -186,15 +280,18 @@ export const parseAdrDetails = ( brakeDeclarationsSeen: adrDetails.getBoolean("brakeDeclarationsSeen"), brakeDeclarationIssuer: adrDetails.getString("brakeDeclarationIssuer"), brakeEndurance: adrDetails.getBoolean("brakeEndurance"), - weight: adrDetails.getString("weight"), - compatibilityGroupJ: adrDetails.getBoolean("compatibilityGroupJ"), + weight: adrDetails.getNumber("weight"), + newCertificateRequested: adrDetails.getBoolean("newCertificateRequested"), + compatibilityGroupJ: adrDetails.getString("compatibilityGroupJ") as compatibilityGroupJEnum, documents: parseStringArray(adrDetails.getList("documents")), permittedDangerousGoods: parseStringArray( adrDetails.getList("permittedDangerousGoods") - ), - additionalExaminerNotes: adrDetails.getString("additionalExaminerNotes"), + ) as permittedDangerousGoodsEnum[], + additionalExaminerNotes, applicantDetails, - memosApply: parseStringArray(adrDetails.getList("memosApply")), + dangerousGoods: adrDetails.getBoolean("dangerousGoods"), + memosApply: parseStringArray(adrDetails.getList("memosApply")) as memosApplyEnum[], + m145Statement: adrDetails.getBoolean("m145Statement"), additionalNotes, adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo"), adrCertificateNotes: adrDetails.getString("adrCertificateNotes"), diff --git a/src/models/tech-record.ts b/src/models/tech-record.ts index 29aa1c0..a4aa00a 100644 --- a/src/models/tech-record.ts +++ b/src/models/tech-record.ts @@ -14,7 +14,11 @@ import { Microfilm, parseMicrofilm } from "./microfilm"; import { parsePlates, Plates } from "./plates"; import { BodyType, parseBodyType } from "./body-type"; import { Dimensions, parseDimensions } from "./dimensions"; -import { AdrDetails } from "./adr-details"; +import { AdrDetails, parseAdrDetails } from "./adr-details"; +import { + AdrPassCertificateDetails, + parseAdrCertificateDetails, +} from "./adr-certificate-details"; import { parseVehicleClass, VehicleClass } from "./vehicle-class"; import { Brakes, parseBrakes } from "./brakes"; import { Axles, parseAxles } from "./axles"; @@ -114,6 +118,7 @@ export interface TechRecord { noOfAxles?: number; brakeCode?: string; adrDetails?: AdrDetails; + adrPassCertificateDetails?: AdrPassCertificateDetails; createdByName?: string; createdById?: string; lastUpdatedByName?: string; @@ -270,7 +275,10 @@ const parseTechRecord = (image: DynamoDbImage): TechRecord => { notes: image.getString("notes"), noOfAxles: image.getNumber("noOfAxles"), brakeCode: image.getString("brakeCode"), - adrDetails: undefined, // intentional - not implemented. parseAdrDetails(image.getMap("adrDetails")) + adrDetails: parseAdrDetails(image.getMap("adrDetails")), + adrPassCertificateDetails: parseAdrCertificateDetails( + image.getList("adrPassCertificateDetails") + ), createdByName: image.getString("createdByName"), createdById: image.getString("createdById"), lastUpdatedByName: image.getString("lastUpdatedByName"), diff --git a/src/services/sql-execution.ts b/src/services/sql-execution.ts index 45576ad..49aaf2b 100644 --- a/src/services/sql-execution.ts +++ b/src/services/sql-execution.ts @@ -116,3 +116,37 @@ export async function selectRecordIds( connection ); } + +/** + * Execute a "select or partial upsert" for a key value condition attribute: + * - if a matching record exists (run SELECT first), return the existing entity's ID + * - if a matching record does not exist, insert a new record and return its ID + * + * @param tableDetails + * @param conditionAttributes + * @param connection + */ +export const executePartialUpsertIfNotExistsWithCondition = async ( + tableDetails: TableDetails, + conditionAttributes: { [key: string]: any }, + connection: Connection +): Promise => { + // select record if exists + const selectResultSet = await executeSql( + generateSelectRecordIds(tableDetails.tableName, conditionAttributes), + Object.values(conditionAttributes), + connection + ); + + // insert into data base if record not exists + if (selectResultSet.rows.length === 0) { + return executePartialUpsert(tableDetails, + Object.values(conditionAttributes), + connection + ); + + } else { + selectResultSet.rows[0].insertId = selectResultSet.rows[0].id; + return { rows: selectResultSet.rows[0], fields: selectResultSet.fields }; + } +}; diff --git a/src/services/table-details.ts b/src/services/table-details.ts index c97e615..d085dbc 100644 --- a/src/services/table-details.ts +++ b/src/services/table-details.ts @@ -364,6 +364,108 @@ export const TEST_RESULT_TABLE: TableDetails = { ], }; +export const ADR_PASS_CERTIFICATE_DETAILS: TableDetails = { + tableName: "adr_PassCertificateDetails", + columnNames: [ + "technical_record_id", + "createdByName", + "certificateType", + "generatedTimestamp", + "certificateId", + ], +}; + +export const ADR_ADDITIONAL_EXAMINER_NOTES_TABLE: TableDetails = { + tableName: "adr_additional_examiner_notes", + columnNames: ["adr_details_id", "note", "createdAtDate", "lastUpdatedBy"], +}; + +export const ADR_ADDITIONAL_NOTES_NUMBER_TABLE: TableDetails = { + tableName: "adr_additional_notes_number", + columnNames: ["number", "adr_details_id"], +}; + +export const ADR_DANGEROUS_GOODS_LIST_TABLE: TableDetails = { + tableName: "adr_dangerous_goods_list", + columnNames: ["name"], +}; + +export const ADR_DETAILS_TABLE: TableDetails = { + tableName: "adr_details", + columnNames: [ + "technical_record_id", + "type", + "approvalDate", + "listStatementApplicable", + "batteryListNumber", + "declarationsSeen", + "brakeDeclarationsSeen", + "brakeDeclarationIssuer", + "brakeEndurance", + "weight", + "compatibilityGroupJ", + // dangerousGoods, + "applicantDetailsName", + "street", + "town", + "city", + "postcode", + "adrTypeApprovalNo", + "adrCertificateNotes", + "tankManufacturer", + "yearOfManufacture", + "tankCode", + "specialProvisions", + "tankManufacturerSerialNo", + "tankTypeAppNo", + "tc2Type", + "tc2IntermediateApprovalNo", + "tc2IntermediateExpiryDate", + "substancesPermitted", + // "select", + "statement", + "productListRefNo", + "productList", + "m145Statement", + // "newCertificateRequested", + ], +}; + +export const ADR_MEMOS_APPLY_TABLE: TableDetails = { + tableName: "adr_memos_apply", + columnNames: ["adr_details_id", "memo"], +}; + +export const ADR_TANK_DOCUMENTS_TABLE: TableDetails = { + tableName: "adr_documents", + columnNames: ["adr_details_id", "document"], +}; + +export const ADR_PERMITTED_DANGEROUS_GOODS_TABLE: TableDetails = { + tableName: "adr_permitted_dangerous_goods", + columnNames: ["adr_details_id", "adr_dangerous_goods_list_id"], +}; + +export const ADR_PRODUCTLISTUNNO_LIST_TABLE: TableDetails = { + tableName: "adr_productListUnNo_list", + columnNames: ["name"], +}; + +export const ADR_PRODUCTLISTUNNO_TABLE: TableDetails = { + tableName: "adr_productListUnNo", + columnNames: ["adr_details_id", "adr_productListUnNo_list_id"], +}; + +export const ADR_TC3DETAILS_TABLE: TableDetails = { + tableName: "adr_tc3Details", + columnNames: [ + "adr_details_id", + "tc3Type", + "tc3PeriodicNumber", + "tc3PeriodicExpiryDate", + ], +}; + export const allTables = (): TableDetails[] => { return [ VEHICLE_TABLE, @@ -389,5 +491,16 @@ export const allTables = (): TableDetails[] => { TEST_DEFECT_TABLE, CUSTOM_DEFECT_TABLE, TEST_RESULT_TABLE, + ADR_ADDITIONAL_EXAMINER_NOTES_TABLE, + ADR_ADDITIONAL_NOTES_NUMBER_TABLE, + ADR_DANGEROUS_GOODS_LIST_TABLE, + ADR_DETAILS_TABLE, + ADR_MEMOS_APPLY_TABLE, + ADR_TANK_DOCUMENTS_TABLE, + ADR_PERMITTED_DANGEROUS_GOODS_TABLE, + ADR_PRODUCTLISTUNNO_LIST_TABLE, + ADR_PRODUCTLISTUNNO_TABLE, + ADR_TC3DETAILS_TABLE, + ADR_PASS_CERTIFICATE_DETAILS, ]; }; diff --git a/src/services/tech-record-document-conversion.ts b/src/services/tech-record-document-conversion.ts index 3bc9293..da021c4 100644 --- a/src/services/tech-record-document-conversion.ts +++ b/src/services/tech-record-document-conversion.ts @@ -18,11 +18,23 @@ import { VEHICLE_SUBCLASS_TABLE, VEHICLE_TABLE, AUTH_INTO_SERVICE_TABLE, + ADR_ADDITIONAL_EXAMINER_NOTES_TABLE, + ADR_ADDITIONAL_NOTES_NUMBER_TABLE, + ADR_DANGEROUS_GOODS_LIST_TABLE, + ADR_DETAILS_TABLE, + ADR_MEMOS_APPLY_TABLE, + ADR_PERMITTED_DANGEROUS_GOODS_TABLE, + ADR_PRODUCTLISTUNNO_LIST_TABLE, + ADR_PRODUCTLISTUNNO_TABLE, + ADR_TC3DETAILS_TABLE, + ADR_TANK_DOCUMENTS_TABLE, + ADR_PASS_CERTIFICATE_DETAILS, } from "./table-details"; import { deleteBasedOnWhereIn, executeFullUpsert, executePartialUpsertIfNotExists, + executePartialUpsertIfNotExistsWithCondition, } from "./sql-execution"; import { getConnectionPool } from "./connection-pool"; import { Connection } from "mysql2/promise"; @@ -218,6 +230,103 @@ const upsertTechRecords = async ( techRecordId, techRecord ); + await upsertAdrPassCertificateDetails( + techRecordConnection, + techRecordId, + techRecord + ); + + // upsert adr-details + if (techRecord.adrDetails) { + debugLog(`upsertTechRecords: Upserting ADR Details...`); + const adrResponse = await executeFullUpsert( + ADR_DETAILS_TABLE, + [ + techRecordId, + techRecord.adrDetails.vehicleDetails?.type, + techRecord.adrDetails.vehicleDetails?.approvalDate, + techRecord.adrDetails.listStatementApplicable, + techRecord.adrDetails.batteryListNumber, + techRecord.adrDetails.declarationsSeen, + techRecord.adrDetails.brakeDeclarationsSeen, + techRecord.adrDetails.brakeDeclarationIssuer, + techRecord.adrDetails.brakeEndurance, + techRecord.adrDetails.weight, + techRecord.adrDetails.compatibilityGroupJ, + // techRecord.adrDetails.dangerousGoods, + techRecord.adrDetails.applicantDetails?.name, + techRecord.adrDetails.applicantDetails?.street, + techRecord.adrDetails.applicantDetails?.town, + techRecord.adrDetails.applicantDetails?.city, + techRecord.adrDetails.applicantDetails?.postcode, + techRecord.adrDetails.adrTypeApprovalNo, + techRecord.adrDetails.adrCertificateNotes, + techRecord.adrDetails.tank?.tankDetails?.tankManufacturer, + techRecord.adrDetails.tank?.tankDetails?.yearOfManufacture, + techRecord.adrDetails.tank?.tankDetails?.tankCode, + techRecord.adrDetails.tank?.tankDetails?.specialProvisions, + techRecord.adrDetails.tank?.tankDetails?.tankManufacturerSerialNo, + techRecord.adrDetails.tank?.tankDetails?.tankTypeAppNo, + techRecord.adrDetails.tank?.tankDetails?.tc2Details?.tc2Type, + techRecord.adrDetails.tank?.tankDetails?.tc2Details + ?.tc2IntermediateApprovalNo, + techRecord.adrDetails.tank?.tankDetails?.tc2Details + ?.tc2IntermediateExpiryDate, + techRecord.adrDetails.tank?.tankStatement?.substancesPermitted, + // techRecord.adrDetails.tank?.tankStatement?.select, + techRecord.adrDetails.tank?.tankStatement?.statement, + techRecord.adrDetails.tank?.tankStatement?.productListRefNo, + techRecord.adrDetails.tank?.tankStatement?.productList, + techRecord.adrDetails.m145Statement, + // techRecord.adrDetails.newCertificateRequested, + ], + techRecordConnection + ); + + const adrDetailsId = adrResponse.rows.insertId; + + debugLog( + `upsertTechRecords: Upserted ADR Details (ID: ${adrDetailsId})` + ); + + await upsertAdrMemosApply( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrPermittedDangerousGoods( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrProductListUnNo( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrTc3Details( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrAdditionalExaminerNotes( + techRecordConnection, + adrDetailsId, + techRecord + ); + await upsertAdrAdditionalNotesNumber( + techRecordConnection, + adrDetailsId, + techRecord + ); + // await upsertAdrTankDocuments( + // techRecordConnection, + // adrDetailsId, + // techRecord + // ); + + debugLog(`upsertTechRecords: Upsert ADR Details END`); + } await techRecordConnection.commit(); } catch (err) { @@ -634,3 +743,274 @@ const upsertAuthIntoService = async ( `upsertTechRecords: Upserted authIntoService (tech-record-id: ${techRecordId}, ID: ${response.rows.insertId})` ); }; + +const upsertAdrMemosApply = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.memosApply) { + debugLog( + `upsertTechRecords: Upserting ADR memos_apply (adr-details-id: ${adrDetailsId})...` + ); + + for (const memo of techRecord.adrDetails?.memosApply) { + const response = await executeFullUpsert( + ADR_MEMOS_APPLY_TABLE, + [adrDetailsId, memo], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR memos-apply (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrDangerousGoodsList = async ( + connection: Connection, + dangerousGoodsName: string +): Promise => { + debugLog( + `upsertTechRecords: Selecting/Upserting adr_dangerous_goods_list...` + ); + + const response = await executePartialUpsertIfNotExistsWithCondition( + ADR_DANGEROUS_GOODS_LIST_TABLE, + { name: dangerousGoodsName }, + connection + ); + + debugLog( + `upsertTechRecords: Selected adr_dangerous_goods_list (ID ${response.rows.insertId})` + ); + + return response.rows.insertId; +}; + +const upsertAdrPermittedDangerousGoods = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.permittedDangerousGoods) { + debugLog( + `upsertTechRecords: Upserting ADR permitted_dangerous_goods (adr-details-id: ${adrDetailsId})...` + ); + + for (const permittedDangerousGoods of techRecord.adrDetails + ?.permittedDangerousGoods) { + const permittedDangerousGoodsId = await upsertAdrDangerousGoodsList( + connection, + permittedDangerousGoods + ); + + const response = await executeFullUpsert( + ADR_PERMITTED_DANGEROUS_GOODS_TABLE, + [adrDetailsId, permittedDangerousGoodsId], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR permitted_dangerous_goods (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrProductListUnNoList = async ( + connection: Connection, + productListUnNo: string +): Promise => { + debugLog(`upsertTechRecords: Upserting adr_productListUnNo_list...`); + + const response = await executePartialUpsertIfNotExistsWithCondition( + ADR_PRODUCTLISTUNNO_LIST_TABLE, + { name: productListUnNo }, + connection + ); + + debugLog( + `upsertTechRecords: Upserted adr_productListUnNo_list (ID ${response.rows.insertId})` + ); + + return response.rows.insertId; +}; + +const upsertAdrProductListUnNo = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.tank?.tankStatement?.productListUnNo) { + debugLog( + `upsertTechRecords: Upserting ADR tankStatement productListUnNo (adr-details-id: ${adrDetailsId})...` + ); + + for (const productListUnNo of techRecord.adrDetails?.tank?.tankStatement + ?.productListUnNo) { + const productListUnNoId = await upsertAdrProductListUnNoList( + connection, + productListUnNo + ); + + const response = await executeFullUpsert( + ADR_PRODUCTLISTUNNO_TABLE, + [adrDetailsId, productListUnNoId], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR tankStatement productListUnNo (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrTc3Details = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.tank?.tankDetails?.tc3Details) { + debugLog( + `upsertTechRecords: Upserting ADR tc3Details (adr-details-id: ${adrDetailsId})...` + ); + + for (const tc3Details of techRecord.adrDetails?.tank?.tankDetails + ?.tc3Details) { + const response = await executeFullUpsert( + ADR_TC3DETAILS_TABLE, + [ + adrDetailsId, + tc3Details.tc3Type, + tc3Details.tc3PeriodicNumber, + tc3Details.tc3PeriodicExpiryDate, + ], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR tc3Details (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrAdditionalExaminerNotes = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.additionalExaminerNotes) { + debugLog( + `upsertTechRecords: Upserting ADR additionalExaminerNotes (adr-details-id: ${adrDetailsId})...` + ); + + for (const additionalExaminerNotes of techRecord.adrDetails + ?.additionalExaminerNotes) { + const response = await executeFullUpsert( + ADR_ADDITIONAL_EXAMINER_NOTES_TABLE, + [ + adrDetailsId, + additionalExaminerNotes.note, + additionalExaminerNotes.createdAtDate, + additionalExaminerNotes.lastUpdatedBy, + ], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR additionalExaminerNotes (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrAdditionalNotesNumber = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.additionalNotes?.number) { + debugLog( + `upsertTechRecords: Upserting ADR additional_notes_number (adr-details-id: ${adrDetailsId})...` + ); + + for (const additionalNotesNumber of techRecord.adrDetails?.additionalNotes + ?.number) { + const response = await executeFullUpsert( + ADR_ADDITIONAL_NOTES_NUMBER_TABLE, + [additionalNotesNumber, adrDetailsId], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR additional_notes_number (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrTankDocuments = async ( + connection: Connection, + adrDetailsId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrDetails?.documents) { + debugLog( + `upsertTechRecords: Upserting ADR tank documents (adr-details-id: ${adrDetailsId})...` + ); + + for (const documents of techRecord.adrDetails?.documents) { + const response = await executeFullUpsert( + ADR_TANK_DOCUMENTS_TABLE, + [adrDetailsId, documents], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR tank documents (adr-details-id: ${adrDetailsId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; + +const upsertAdrPassCertificateDetails = async ( + connection: Connection, + techRecordId: string, + techRecord: TechRecord +): Promise => { + if (techRecord.adrPassCertificateDetails) { + debugLog( + `upsertTechRecords: Upserting ADR Pass Certificate Details (tech-record-id: ${techRecordId})...` + ); + + for (const adrPassCertificateDetails of techRecord.adrPassCertificateDetails) { + const response = await executeFullUpsert( + ADR_PASS_CERTIFICATE_DETAILS, + [ + techRecordId, + adrPassCertificateDetails.createdByName, + adrPassCertificateDetails.certificateType, + adrPassCertificateDetails.generatedTimestamp, + adrPassCertificateDetails.certificateId, + ], + connection + ); + + debugLog( + `upsertTechRecords: Upserted ADR Pass Certificate Details (tech-record-id: ${techRecordId}, ID: ${response.rows.insertId})` + ); + } + } + return; +}; diff --git a/tests/integration/tech-record-document-conversion.intTest.ts b/tests/integration/tech-record-document-conversion.intTest.ts index b070bf9..cbc4b7a 100644 --- a/tests/integration/tech-record-document-conversion.intTest.ts +++ b/tests/integration/tech-record-document-conversion.intTest.ts @@ -4,7 +4,7 @@ import { executeSql, } from "../../src/services/connection-pool"; import { exampleContext, useLocalDb } from "../utils"; -import techRecordDocumentJson from "../resources/dynamodb-image-technical-record.json"; +import techRecordDocumentJsonWithADR from "../resources/dynamodb-image-technical-record-with-adr.json"; import { getContainerizedDatabase } from "./cvsbnop-container"; import { processStreamEvent } from "../../src/functions/process-stream-event"; import { getConnectionPoolOptions } from "../../src/services/connection-pool-options"; @@ -12,7 +12,7 @@ import { getConnectionPoolOptions } from "../../src/services/connection-pool-opt useLocalDb(); export const techRecordDocumentConversion = () => - describe("convertTechRecordDocument() integration tests", () => { + describe("convertTechRecordDocument() with ADR integration tests", () => { let container: StartedTestContainer; beforeAll(async () => { @@ -49,7 +49,7 @@ export const techRecordDocumentConversion = () => "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T00:00:00.000", eventName: "INSERT", dynamodb: { - NewImage: techRecordDocumentJson, + NewImage: techRecordDocumentJsonWithADR, }, }), }, @@ -590,13 +590,421 @@ export const techRecordDocumentConversion = () => expect( (authIntoServiceResultSet.rows[0].dateRejected as Date).toUTCString() ).toEqual("Tue, 05 May 2020 00:00:00 GMT"); + + const adrPassCertificateDetailsResultSet = await executeSql( + `SELECT \`technical_record_id\`, + \`createdByName\`, + \`certificateType\`, + \`generatedTimestamp\`, + \`certificateId\` + FROM \`adr_PassCertificateDetails\` + WHERE \`adr_PassCertificateDetails\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrPassCertificateDetailsResultSet.rows.length).toEqual(1); + expect( + adrPassCertificateDetailsResultSet.rows[0].technical_record_id + ).toEqual(technicalRecordId); + expect(adrPassCertificateDetailsResultSet.rows[0].createdByName).toEqual( + "CREATED-BY-NAME-01" + ); + expect( + adrPassCertificateDetailsResultSet.rows[0].certificateType + ).toEqual("PASS"); + expect( + (adrPassCertificateDetailsResultSet.rows[0].generatedTimestamp as Date) + .toISOString() + ).toEqual("2023-04-01T01:49:00.000Z"); + expect(adrPassCertificateDetailsResultSet.rows[0].certificateId).toEqual( + "CERTIFICATE-ID-1" + ); + + // adr_details + const adrDetailsResultSet = await executeSql( + `SELECT \`id\`, + \`technical_record_id\`, + \`type\`, + \`approvalDate\`, + \`listStatementApplicable\`, + \`batteryListNumber\`, + \`declarationsSeen\`, + \`brakeDeclarationsSeen\`, + \`brakeDeclarationIssuer\`, + \`brakeEndurance\`, + \`weight\`, + \`compatibilityGroupJ\`, + \`applicantDetailsName\`, + \`street\`, + \`town\`, + \`city\`, + \`postcode\`, + \`adrTypeApprovalNo\`, + \`adrCertificateNotes\`, + \`tankManufacturer\`, + \`yearOfManufacture\`, + \`tankCode\`, + \`specialProvisions\`, + \`tankManufacturerSerialNo\`, + \`tankTypeAppNo\`, + \`tc2Type\`, + \`tc2IntermediateApprovalNo\`, + \`tc2IntermediateExpiryDate\`, + \`substancesPermitted\`, + \`statement\`, + \`productListRefNo\`, + \`productList\`, + \`m145Statement\` + FROM \`adr_details\` + WHERE \`adr_details\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + expect(adrDetailsResultSet.rows[0].technical_record_id).toEqual( + technicalRecordId + ); + expect(adrDetailsResultSet.rows[0].type).toEqual("Artic tractor"); + expect( + (adrDetailsResultSet.rows[0].approvalDate as Date).toUTCString() + ).toEqual("Mon, 12 Jun 2023 00:00:00 GMT"); + expect(adrDetailsResultSet.rows[0].listStatementApplicable).toEqual(1); + expect(adrDetailsResultSet.rows[0].batteryListNumber).toEqual("BATTERY1"); + expect(adrDetailsResultSet.rows[0].declarationsSeen).toEqual(0); + expect(adrDetailsResultSet.rows[0].brakeDeclarationsSeen).toEqual(1); + expect(adrDetailsResultSet.rows[0].brakeDeclarationIssuer).toEqual( + "brakeDeclarationIssuer_1" + ); + expect(adrDetailsResultSet.rows[0].brakeEndurance).toEqual(0); + expect(adrDetailsResultSet.rows[0].weight).toEqual("7.50"); + expect(adrDetailsResultSet.rows[0].compatibilityGroupJ).toEqual("I"); + expect(adrDetailsResultSet.rows[0].applicantDetailsName).toEqual( + "applicantDetails_Name" + ); + expect(adrDetailsResultSet.rows[0].street).toEqual( + "applicantDetailsSTREET" + ); + expect(adrDetailsResultSet.rows[0].town).toEqual("applicantDetailsTOWN"); + expect(adrDetailsResultSet.rows[0].city).toEqual("applicantDetailsCITY"); + expect(adrDetailsResultSet.rows[0].postcode).toEqual("POST-CODE"); + expect(adrDetailsResultSet.rows[0].adrTypeApprovalNo).toEqual( + "adrTypeApprovalNo_1" + ); + expect(adrDetailsResultSet.rows[0].adrCertificateNotes).toEqual( + "adrCertificateNotes_1" + ); + expect(adrDetailsResultSet.rows[0].tankManufacturer).toEqual( + "tankManufacturer_1" + ); + expect(adrDetailsResultSet.rows[0].yearOfManufacture).toEqual(2012); + expect(adrDetailsResultSet.rows[0].tankCode).toEqual("tankCode_1"); + expect(adrDetailsResultSet.rows[0].specialProvisions).toEqual( + "specialProvisions_1" + ); + expect(adrDetailsResultSet.rows[0].tankManufacturerSerialNo).toEqual( + "1234" + ); + expect(adrDetailsResultSet.rows[0].tankTypeAppNo).toEqual("9876"); + expect(adrDetailsResultSet.rows[0].tc2Type).toEqual("initial"); + expect(adrDetailsResultSet.rows[0].tc2IntermediateApprovalNo).toEqual( + "12345" + ); + expect( + (adrDetailsResultSet.rows[0] + .tc2IntermediateExpiryDate as Date).toUTCString() + ).toEqual("Sat, 01 Jun 2024 00:00:00 GMT"); + expect(adrDetailsResultSet.rows[0].substancesPermitted).toEqual( + "Substances permitted under the tank code and any special provisions specified in 9 may be carried" + ); + expect(adrDetailsResultSet.rows[0].statement).toEqual("statement_1"); + expect(adrDetailsResultSet.rows[0].productListRefNo).toEqual("123456"); + expect(adrDetailsResultSet.rows[0].productList).toEqual("productList_1"); + expect(adrDetailsResultSet.rows[0].m145Statement).toEqual(1); + + const adrDetailsId = adrDetailsResultSet.rows[0].id; + + // adr_memos_apply + const adrMemosApplyResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`memo\` + FROM \`adr_memos_apply\` + WHERE \`adr_memos_apply\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrMemosApplyResultSet.rows.length).toEqual(1); + expect(adrMemosApplyResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect(adrMemosApplyResultSet.rows[0].memo).toEqual( + "07/09 3mth leak ext" + ); + + // adr_dangerous_goods_list + const adrDangerousGoodsListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_dangerous_goods_list\` + ` + ); + expect(adrDangerousGoodsListResultSet.rows.length).toEqual(3); + + expect(adrDangerousGoodsListResultSet.rows[0].name).toEqual( + "FP <61 (FL)" + ); + expect(adrDangerousGoodsListResultSet.rows[1].name).toEqual( + "Carbon Disulphide" + ); + expect(adrDangerousGoodsListResultSet.rows[2].name).toEqual("Hydrogen"); + + // adr_permitted_dangerous_goods + const adrPermittedDangerousGoodsResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_dangerous_goods_list_id\` + FROM \`adr_permitted_dangerous_goods\` + WHERE \`adr_permitted_dangerous_goods\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrPermittedDangerousGoodsResultSet.rows.length).toEqual(3); + expect( + adrPermittedDangerousGoodsResultSet.rows[0].adr_details_id + ).toEqual(adrDetailsId); + expect( + adrPermittedDangerousGoodsResultSet.rows[0].adr_dangerous_goods_list_id + ).toEqual(1); + expect( + adrPermittedDangerousGoodsResultSet.rows[1].adr_dangerous_goods_list_id + ).toEqual(2); + expect( + adrPermittedDangerousGoodsResultSet.rows[2].adr_dangerous_goods_list_id + ).toEqual(3); + + // adr_productListUnNo_list + const adrProductListUnNoListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_productListUnNo_list\` + ` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + expect(adrProductListUnNoListResultSet.rows[0].name).toEqual("123123"); + expect(adrProductListUnNoListResultSet.rows[1].name).toEqual("987987"); + expect(adrProductListUnNoListResultSet.rows[2].name).toEqual("135790"); + + // adr_productListUnNo + const adrProductListUnNoResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_productListUnNo_list_id\` + FROM \`adr_productListUnNo\` + WHERE \`adr_productListUnNo\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(3); + expect(adrProductListUnNoResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect( + adrProductListUnNoResultSet.rows[0].adr_productListUnNo_list_id + ).toEqual(1); + expect( + adrProductListUnNoResultSet.rows[1].adr_productListUnNo_list_id + ).toEqual(2); + expect( + adrProductListUnNoResultSet.rows[2].adr_productListUnNo_list_id + ).toEqual(3); + + // adr_tc3Details + const adrTc3DetailsResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`tc3Type\`, + \`tc3PeriodicNumber\`, + \`tc3PeriodicExpiryDate\` + FROM \`adr_tc3Details\` + WHERE \`adr_tc3Details\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrTc3DetailsResultSet.rows.length).toEqual(1); + expect(adrTc3DetailsResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect(adrTc3DetailsResultSet.rows[0].tc3Type).toEqual("intermediate"); + expect(adrTc3DetailsResultSet.rows[0].tc3PeriodicNumber).toEqual("98765"); + expect( + (adrTc3DetailsResultSet.rows[0] + .tc3PeriodicExpiryDate as Date).toUTCString() + ).toEqual("Sat, 01 Jun 2024 00:00:00 GMT"); + + // adr_additional_examiner_notes + const adrAdditionalExaminerNotesResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`note\`, + \`createdAtDate\`, + \`lastUpdatedBy\` + FROM \`adr_additional_examiner_notes\` + WHERE \`adr_additional_examiner_notes\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrAdditionalExaminerNotesResultSet.rows.length).toEqual(1); + expect( + adrAdditionalExaminerNotesResultSet.rows[0].adr_details_id + ).toEqual(adrDetailsId); + expect(adrAdditionalExaminerNotesResultSet.rows[0].note).toEqual( + "additionalExaminerNotes_note_1" + ); + expect( + (adrAdditionalExaminerNotesResultSet.rows[0] + .createdAtDate as Date).toUTCString() + ).toEqual("Tue, 30 May 2023 00:00:00 GMT"); + expect(adrAdditionalExaminerNotesResultSet.rows[0].lastUpdatedBy).toEqual( + "additionalExaminerNotes_lastUpdatedBy_1" + ); + + // adr_additional_notes_number + const adrAdditionalNotesNumberResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`number\` + FROM \`adr_additional_notes_number\` + WHERE \`adr_additional_notes_number\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrAdditionalNotesNumberResultSet.rows.length).toEqual(2); + expect(adrAdditionalNotesNumberResultSet.rows[0].adr_details_id).toEqual( + adrDetailsId + ); + expect(adrAdditionalNotesNumberResultSet.rows[0].number).toEqual("1"); + expect(adrAdditionalNotesNumberResultSet.rows[1].number).toEqual("T1B"); + }); + + it("should reject to insert same tech-record record into database", async () => { + const event = { + Records: [ + { + body: JSON.stringify({ + eventSourceARN: + "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T01:00:00.000", + eventName: "INSERT", + dynamodb: { + NewImage: techRecordDocumentJsonWithADR, + }, + }), + }, + ], + }; + + // array of arrays: event contains array of records, each with array of tech record entities + await processStreamEvent(event, exampleContext(), () => { + return; + }); + + const vehicleResultSet = await executeSql(`SELECT * FROM \`vehicle\``); + expect(vehicleResultSet.rows.length).toEqual(1); + + const technicalRecordSet = await executeSql( + `SELECT * FROM \`technical_record\`` + ); + expect(technicalRecordSet.rows.length).toEqual(1); + + const makeModelResultSet = await executeSql( + `SELECT * FROM \`make_model\`` + ); + expect(makeModelResultSet.rows.length).toEqual(1); + + const vehicleClassResultSet = await executeSql( + `SELECT * FROM \`vehicle_class\`` + ); + expect(vehicleClassResultSet.rows.length).toEqual(1); + + const { + make_model_id, + vehicle_class_id, + createdBy_Id, + lastUpdatedBy_Id, + applicant_detail_id, + purchaser_detail_id, + manufacturer_detail_id, + } = technicalRecordSet.rows[0]; + + const createdByResultSet = await executeSql( + `SELECT * FROM \`identity\` + WHERE \`identity\`.\`id\` IN (${lastUpdatedBy_Id}, ${createdBy_Id})` + ); + expect(createdByResultSet.rows.length).toEqual(2); + + const contactDetailsResultSet = await executeSql( + `SELECT * FROM \`contact_details\`` + ); + expect(contactDetailsResultSet.rows.length).toEqual(1); + + const techRecordResultSet = await executeSql( + `SELECT * FROM \`technical_record\`` + ); + expect(techRecordResultSet.rows.length).toEqual(1); + + const brakesResultSet = await executeSql(`SELECT * FROM \`psv_brakes\``); + expect(brakesResultSet.rows.length).toEqual(1); + + const axleSpacingResultSet = await executeSql( + `SELECT * FROM \`axle_spacing\`` + ); + expect(axleSpacingResultSet.rows.length).toEqual(1); + + const microfilmResultSet = await executeSql( + `SELECT * FROM \`microfilm\`` + ); + expect(microfilmResultSet.rows.length).toEqual(1); + + const platesResultSet = await executeSql(`SELECT * FROM \`plate\``); + expect(platesResultSet.rows.length).toEqual(1); + + const axlesResultSet = await executeSql(`SELECT * FROM \`axles\``); + expect(axlesResultSet.rows.length).toEqual(1); + + const authIntoServiceResultSet = await executeSql( + `SELECT * FROM \`auth_into_service\`` + ); + expect(authIntoServiceResultSet.rows.length).toEqual(1); + + const adrDetailsResultSet = await executeSql( + `SELECT * FROM \`adr_details\`` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + + const adrMemosApplyResultSet = await executeSql( + `SELECT * FROM \`adr_memos_apply\`` + ); + expect(adrMemosApplyResultSet.rows.length).toEqual(2); // With current logic, this gets duplicated + + const adrDangerousGoodsListResultSet = await executeSql( + `SELECT * FROM \`adr_dangerous_goods_list\`` + ); + expect(adrDangerousGoodsListResultSet.rows.length).toEqual(3); + + const adrPermittedDangerousGoodsResultSet = await executeSql( + `SELECT * FROM \`adr_permitted_dangerous_goods\`` + ); + expect(adrPermittedDangerousGoodsResultSet.rows.length).toEqual(6); // With current logic, this gets duplicated + + const adrProductListUnNoListResultSet = await executeSql( + `SELECT * FROM \`adr_productListUnNo_list\`` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + const adrProductListUnNoResultSet = await executeSql( + `SELECT * FROM \`adr_productListUnNo\`` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(6); // With current logic, this gets duplicated + + const adrTc3DetailsResultSet = await executeSql( + `SELECT * FROM \`adr_tc3Details\`` + ); + expect(adrTc3DetailsResultSet.rows.length).toEqual(2); // With current logic, this gets duplicated + + const adrAdditionalExaminerNotesResultSet = await executeSql( + `SELECT * FROM \`adr_additional_examiner_notes\`` + ); + expect(adrAdditionalExaminerNotesResultSet.rows.length).toEqual(2); // With current logic, this gets duplicated + + const adrAdditionalNotesNumberResultSet = await executeSql( + `SELECT * FROM \`adr_additional_notes_number\`` + ); + expect(adrAdditionalNotesNumberResultSet.rows.length).toEqual(4); }); describe("when adding a new vehicle and changing VRM to a new value, VRM should change on existing vehicle.", () => { it("A new vehicle is present", async () => { // arrange - create a record so we can later query for it and assert for is existence const techRecordDocumentJsonNew = JSON.parse( - JSON.stringify(techRecordDocumentJson) + JSON.stringify(techRecordDocumentJsonWithADR) ); techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-2" }; techRecordDocumentJsonNew.vin = { S: "VIN2" }; @@ -642,7 +1050,7 @@ export const techRecordDocumentConversion = () => it("VRM has changed", async () => { // arrange - create a record with existing pair of (SystemNumber, VIN) and new VRM so we can later query for it and assert its value const techRecordDocumentJsonNew = JSON.parse( - JSON.stringify(techRecordDocumentJson) + JSON.stringify(techRecordDocumentJsonWithADR) ); techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-2" }; techRecordDocumentJsonNew.vin = { S: "VIN2" }; @@ -685,4 +1093,223 @@ export const techRecordDocumentConversion = () => ).not.toBeNull(); // todo This returns null }); }); + + describe("when adding a new vehicle and changing some ADR attributes to a new values, those fields are changed on ADR tables.", () => { + it("A new vehicle is created", async () => { + // arrange - create a record so we can later query for it and assert for is existence + const techRecordDocumentJsonNew = JSON.parse( + JSON.stringify(techRecordDocumentJsonWithADR) + ); + techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-3" }; + techRecordDocumentJsonNew.vin = { S: "VIN3" }; + techRecordDocumentJsonNew.primaryVrm = { S: "VRM3" }; + + // productListUnNo removed from payload + delete techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M + .tank.M.tankStatement.M.productListUnNo; + + const event = { + Records: [ + { + body: JSON.stringify({ + eventSourceARN: + "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T00:00:00.000", + eventName: "INSERT", + dynamodb: { + NewImage: techRecordDocumentJsonNew, + }, + }), + }, + ], + }; + // array of arrays: event contains array of records, each with array of tech record entities + await processStreamEvent(event, exampleContext(), () => { + return; + }); + + const vehicleResultSet = await executeSql( + `SELECT \`system_number\`, \`vin\`, \`vrm_trm\`, \`trailer_id\`, \`createdAt\`, \`id\` + FROM \`vehicle\` + WHERE \`system_number\` = "SYSTEM-NUMBER-3"` + ); + + expect(vehicleResultSet.rows.length).toEqual(1); + expect(vehicleResultSet.rows[0].system_number).toEqual( + "SYSTEM-NUMBER-3" + ); + expect(vehicleResultSet.rows[0].vin).toEqual("VIN3"); + expect(vehicleResultSet.rows[0].vrm_trm).toEqual("VRM3"); + expect(vehicleResultSet.rows[0].trailer_id).toEqual("TRL-1"); + expect( + (vehicleResultSet.rows[0].createdAt as Date).toUTCString() + ).not.toBeNull(); // todo This returns null + + const vehicleId = vehicleResultSet.rows[0].id; + + const technicalRecordSet = await executeSql( + `SELECT * + FROM \`technical_record\` + WHERE \`technical_record\`.\`vehicle_id\` = ${vehicleId}` + ); + + expect(technicalRecordSet.rows.length).toEqual(1); + + const technicalRecordId = technicalRecordSet.rows[0].id; + + // check data in adr_details is updated and get adrDetailsId + const adrDetailsResultSet = await executeSql( + `SELECT * + FROM \`adr_details\` + WHERE \`adr_details\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + expect(adrDetailsResultSet.rows[0].technical_record_id).toEqual( + technicalRecordId + ); + + const adrDetailsId = adrDetailsResultSet.rows[0].id; + + // adr_productListUnNo_list + const adrProductListUnNoListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_productListUnNo_list\`` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + // adr_productListUnNo (There shouldn't be any record for this) + const adrProductListUnNoResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_productListUnNo_list_id\` + FROM \`adr_productListUnNo\` + WHERE \`adr_productListUnNo\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(0); + }); + + it("Some ADR attributes have been changed", async () => { + const techRecordDocumentJsonNew = JSON.parse( + JSON.stringify(techRecordDocumentJsonWithADR) + ); + techRecordDocumentJsonNew.systemNumber = { S: "SYSTEM-NUMBER-3" }; + techRecordDocumentJsonNew.vin = { S: "VIN3" }; + techRecordDocumentJsonNew.primaryVrm = { S: "VRM3" }; + + // update an already existing list into a different list + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.additionalNotes.M.number = { + L: [{ S: "1" }, { S: "V1B" }], + }; + // update an already existing string to a NULL value + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.adrCertificateNotes = { NULL: true }; + // update an already existing string to a different string + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankDetails.M.tankManufacturer = { + S: "different_tankManufacturer", + }; + // update missing attribute to NULL + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankStatement.M.productListUnNo = { NULL: true }; + + const event = { + Records: [ + { + body: JSON.stringify({ + eventSourceARN: + "arn:aws:dynamodb:eu-west-1:1:table/technical-records/stream/2020-01-01T02:00:00.000", + eventName: "INSERT", + dynamodb: { + NewImage: techRecordDocumentJsonNew, + }, + }), + }, + ], + }; + // array of arrays: event contains array of records, each with array of tech record entities + await processStreamEvent(event, exampleContext(), () => { + return; + }); + + // check if vehicle table is intact and get vehicleId + const vehicleResultSet = await executeSql( + `SELECT \`system_number\`, \`vin\`, \`vrm_trm\`, \`trailer_id\`, \`createdAt\`, \`id\` + FROM \`vehicle\` + WHERE \`vehicle\`.\`system_number\` = "SYSTEM-NUMBER-3"` + ); + + expect(vehicleResultSet.rows.length).toEqual(1); + expect(vehicleResultSet.rows[0].system_number).toEqual( + "SYSTEM-NUMBER-3" + ); + expect(vehicleResultSet.rows[0].vin).toEqual("VIN3"); + expect(vehicleResultSet.rows[0].vrm_trm).toEqual("VRM3"); + expect(vehicleResultSet.rows[0].trailer_id).toEqual("TRL-1"); + expect( + (vehicleResultSet.rows[0].createdAt as Date).toUTCString() + ).not.toBeNull(); // todo This returns null + + const vehicleId = vehicleResultSet.rows[0].id; + + // check if technical_record table is intact and get technicalRecordId + const technicalRecordSet = await executeSql( + `SELECT \`make_model_id\`, \`vehicle_class_id\`, \`createdBy_Id\`, \`lastUpdatedBy_Id\`, \`applicant_detail_id\`, \`purchaser_detail_id\`, \`manufacturer_detail_id\`, \`id\`, \`createdAt\` + FROM \`technical_record\` + WHERE \`technical_record\`.\`vehicle_id\` = ${vehicleId}` + ); + + expect(technicalRecordSet.rows.length).toEqual(1); + expect( + (technicalRecordSet.rows[0].createdAt as Date).toISOString() + ).toEqual("2020-01-01T00:00:00.055Z"); + + const technicalRecordId = technicalRecordSet.rows[0].id; + + // check data in adr_details is updated and get adrDetailsId + const adrDetailsResultSet = await executeSql( + `SELECT * FROM \`adr_details\` + WHERE \`adr_details\`.\`technical_record_id\` = ${technicalRecordId}` + ); + expect(adrDetailsResultSet.rows.length).toEqual(1); + expect(adrDetailsResultSet.rows[0].technical_record_id).toEqual( + technicalRecordId + ); + expect(adrDetailsResultSet.rows[0].adrCertificateNotes).toBeNull(); + expect(adrDetailsResultSet.rows[0].tankManufacturer).toEqual( + "different_tankManufacturer" + ); // is this gonna create an orphaned row? + + const adrDetailsId = adrDetailsResultSet.rows[0].id; + + // check data in adr_additional_notes_number is updated + const adrAdditionalNotesNumberResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`number\` + FROM \`adr_additional_notes_number\` + WHERE \`adr_additional_notes_number\`.\`adr_details_id\` = ${adrDetailsId}` + ); + // With current logic, this will create orphan rows + expect(adrAdditionalNotesNumberResultSet.rows.length).toEqual(4); + expect( + adrAdditionalNotesNumberResultSet.rows[0].adr_details_id + ).toEqual(adrDetailsId); + expect(adrAdditionalNotesNumberResultSet.rows[0].number).toEqual("1"); // orphaned row + expect(adrAdditionalNotesNumberResultSet.rows[1].number).toEqual("T1B"); // orphaned row + expect(adrAdditionalNotesNumberResultSet.rows[2].number).toEqual("1"); + expect(adrAdditionalNotesNumberResultSet.rows[3].number).toEqual("V1B"); + + // adr_productListUnNo_list + const adrProductListUnNoListResultSet = await executeSql( + `SELECT \`id\`, + \`name\` + FROM \`adr_productListUnNo_list\`` + ); + expect(adrProductListUnNoListResultSet.rows.length).toEqual(3); + + // adr_productListUnNo (There still shouldn't be any record for this) + const adrProductListUnNoResultSet = await executeSql( + `SELECT \`adr_details_id\`, + \`adr_productListUnNo_list_id\` + FROM \`adr_productListUnNo\` + WHERE \`adr_productListUnNo\`.\`adr_details_id\` = ${adrDetailsId}` + ); + expect(adrProductListUnNoResultSet.rows.length).toEqual(0); + }); + }); }); diff --git a/tests/integration/test-results-conversion-with-delete.intTest.ts b/tests/integration/test-results-conversion-with-delete.intTest.ts index 2956024..516b3db 100644 --- a/tests/integration/test-results-conversion-with-delete.intTest.ts +++ b/tests/integration/test-results-conversion-with-delete.intTest.ts @@ -12,7 +12,7 @@ import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; useLocalDb(); export const testResultsConversionWithDelete = () => - describe("convertTestResults() integration tests with delete", async () => { + describe("convertTestResults() integration tests with delete", () => { let container: StartedTestContainer; const testResultsJson = JSON.parse( JSON.stringify(require("../resources/dynamodb-image-test-results.json")) diff --git a/tests/resources/Dockerfile b/tests/resources/Dockerfile index b6d6a32..a655315 100644 --- a/tests/resources/Dockerfile +++ b/tests/resources/Dockerfile @@ -1,5 +1,5 @@ # Match Aurora MySQL version as closely as possible -FROM mysql:5.7.12 +FROM mysql:8.0.32 ENV MYSQL_DATABASE=CVSBNOP \ MYSQL_ROOT_PASSWORD=12345 diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json new file mode 100644 index 0000000..0341ca3 --- /dev/null +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -0,0 +1,871 @@ +{ + "systemNumber": { + "S": "SYSTEM-NUMBER-1" + }, + "partialVin": { + "S": "PARTIAL-VIN" + }, + "primaryVrm": { + "S": "VRM-1" + }, + "secondaryVrms": { + "L": [ + { + "S": "SECONDARY-VRM" + } + ] + }, + "vin": { + "S": "VIN-1" + }, + "trailerId": { + "S": "TRL-1" + }, + "techRecord": { + "L": [ + { + "M": { + "adrPassCertificateDetails": { + "L": [ + { + "M": { + "certificateId": { + "S": "CERTIFICATE-ID-1" + }, + "createdByName": { + "S": "CREATED-BY-NAME-01" + }, + "certificateType": { + "S": "PASS" + }, + "generatedTimestamp": { + "S": "2023-04-01T01:49:00.055Z" + } + } + } + ] + }, + "adrDetails": { + "M": { + "additionalExaminerNotes": { + "L": [ + { + "M": { + "note": { + "S": "additionalExaminerNotes_note_1" + }, + "createdAtDate": { + "S": "2023-05-30" + }, + "lastUpdatedBy": { + "S": "additionalExaminerNotes_lastUpdatedBy_1" + } + } + } + ] + }, + "additionalNotes": { + "M": { + "number": { + "L": [ + {"S": "1"}, + {"S": "T1B"} + ] + } + } + }, + "adrCertificateNotes": { + "S": "adrCertificateNotes_1" + }, + "adrTypeApprovalNo": { + "S": "adrTypeApprovalNo_1" + }, + "applicantDetails": { + "M": { + "name": { + "S": "applicantDetails_Name" + }, + "street": { + "S": "applicantDetailsSTREET" + }, + "town": { + "S": "applicantDetailsTOWN" + }, + "city": { + "S": "applicantDetailsCITY" + }, + "postcode": { + "S": "POST-CODE" + } + } + }, + "batteryListNumber": { + "S": "BATTERY1" + }, + "brakeDeclarationIssuer": { + "S": "brakeDeclarationIssuer_1" + }, + "brakeDeclarationsSeen": { + "BOOL": true + }, + "brakeEndurance": { + "BOOL": false + }, + "compatibilityGroupJ": { + "S": "I" + }, + "dangerousGoods": { + "BOOL": false + }, + "declarationsSeen": { + "BOOL": false + }, + "documents": { + "L": [ + { + "S": "documents_1" + }, + { + "S": "documents_2" + }, + { + "S": "documents_3" + } + ] + }, + "listStatementApplicable": { + "BOOL": true + }, + "m145Statement": { + "BOOL": true + }, + "newCertificateRequested": { + "BOOL": false + }, + + "memosApply": { + "L": [ + { + "S": "07/09 3mth leak ext" + } + ] + }, + "permittedDangerousGoods": { + "L": [ + { + "S": "FP <61 (FL)" + }, + { + "S": "Carbon Disulphide" + }, + { + "S": "Hydrogen" + } + ] + }, + "tank": { + "M": { + "tankDetails": { + "M": { + "tankManufacturer": { + "S": "tankManufacturer_1" + }, + "yearOfManufacture": { + "N": "2012" + }, + "tankCode": { + "S": "tankCode_1" + }, + "specialProvisions": { + "S": "specialProvisions_1" + }, + "tankManufacturerSerialNo": { + "S": "1234" + }, + "tankTypeAppNo": { + "S": "9876" + }, + "tc2Details": { + "M": { + "tc2Type": { + "S": "initial" + }, + "tc2IntermediateApprovalNo": { + "S": "12345" + }, + "tc2IntermediateExpiryDate": { + "S": "2024-06-01" + } + } + }, + "tc3Details": { + "L": [ + { + "M": { + "tc3Type": { + "S": "intermediate" + }, + "tc3PeriodicNumber": { + "S": "98765" + }, + "tc3PeriodicExpiryDate": { + "S": "2024-06-01" + } + } + } + ] + } + } + }, + "tankStatement": { + "M": { + "select":{ + "S": "Product list" + }, + "substancesPermitted": { + "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" + }, + "statement": { + "S": "statement_1" + }, + "productListRefNo": { + "S": "123456" + }, + "productListUnNo": { + "L": [ + { + "S": "123123" + }, + { + "S": "987987" + }, + { + "S": "135790" + } + ] + }, + "productList": { + "S": "productList_1" + } + } + } + } + }, + "vehicleDetails": { + "M": { + "type": { + "S": "Artic tractor" + }, + "approvalDate": { + "S": "2023-06-12" + } + } + }, + "weight": { + "N": "7.50" + } + } + }, + "recordCompleteness": { + "S": "88888888" + }, + "createdAt": { + "S": "2020-01-01T00:00:00.055Z" + }, + "lastUpdatedAt": { + "S": "2020-01-01T00:00:00.000000Z" + }, + "make": { + "S": "MAKE" + }, + "model": { + "S": "MODEL" + }, + "functionCode": { + "S": "1" + }, + "fuelPropulsionSystem": { + "S": "DieselPetrol" + }, + "offRoad": { + "BOOL": true + }, + "numberOfWheelsDriven": { + "N": "1" + }, + "euVehicleCategory": { + "S": "m1" + }, + "emissionsLimit": { + "N": "1" + }, + "departmentalVehicleMarker": { + "BOOL": true + }, + "authIntoService": { + "M": { + "cocIssueDate": { + "S": "2020-01-01" + }, + "dateAuthorised": { + "S": "2020-02-02" + }, + "datePending": { + "S": "2020-03-03" + }, + "dateReceived": { + "S": "2020-04-04" + }, + "dateRejected": { + "S": "2020-05-05" + } + } + }, + "lettersOfAuth": { + "M": { + "letterType": { + "S": "Trailer authorization" + }, + "letterDateRequested": { + "S": "2020-01-01" + }, + "letterContents": { + "S": "LETTER-CONTENTS" + } + } + }, + "alterationMarker": { + "BOOL": true + }, + "approvalType": { + "S": "NTA" + }, + "approvalTypeNumber": { + "S": "1" + }, + "variantNumber": { + "S": "1" + }, + "variantVersionNumber": { + "S": "1" + }, + "grossEecWeight": { + "N": "1" + }, + "trainEecWeight": { + "N": "1" + }, + "maxTrainEecWeight": { + "N": "1" + }, + "applicantDetails": { + "M": { + "name": { + "S": "NAME" + }, + "address1": { + "S": "ADDRESS-1" + }, + "address2": { + "S": "ADDRESS-2" + }, + "postTown": { + "S": "POST-TOWN" + }, + "address3": { + "S": "ADDRESS-3" + }, + "postCode": { + "S": "POST-CODE" + }, + "emailAddress": { + "S": "EMAIL-ADDRESS" + }, + "telephoneNumber": { + "S": "TELEPHONE-NUMBER" + } + } + }, + "purchaserDetails": { + "M": { + "name": { + "S": "NAME" + }, + "address1": { + "S": "ADDRESS-1" + }, + "address2": { + "S": "ADDRESS-2" + }, + "postTown": { + "S": "POST-TOWN" + }, + "address3": { + "S": "ADDRESS-3" + }, + "postCode": { + "S": "POST-CODE" + }, + "emailAddress": { + "S": "EMAIL-ADDRESS" + }, + "telephoneNumber": { + "S": "TELEPHONE-NUMBER" + }, + "faxNumber": { + "S": "FAX-NUMBER" + }, + "purchaserNotes": { + "S": "PURCHASER-NOTES" + } + } + }, + "manufacturerDetails": { + "M": { + "name": { + "S": "NAME" + }, + "address1": { + "S": "ADDRESS-1" + }, + "address2": { + "S": "ADDRESS-2" + }, + "postTown": { + "S": "POST-TOWN" + }, + "address3": { + "S": "ADDRESS-3" + }, + "postCode": { + "S": "POST-CODE" + }, + "emailAddress": { + "S": "EMAIL-ADDRESS" + }, + "telephoneNumber": { + "S": "TELEPHONE-NUMBER" + }, + "faxNumber": { + "S": "FAX-NUMBER" + }, + "manufacturerNotes": { + "S": "MANUFACTURER-NOTES" + } + } + }, + "microfilm": { + "M": { + "microfilmDocumentType": { + "S": "PSV Miscellaneous" + }, + "microfilmRollNumber": { + "S": "1" + }, + "microfilmSerialNumber": { + "S": "1" + } + } + }, + "plates": { + "L": [ + { + "M": { + "plateSerialNumber": { + "S": "1" + }, + "plateIssueDate": { + "S": "2020-01-01" + }, + "plateReasonForIssue": { + "S": "Free replacement" + }, + "plateIssuer": { + "S": "PLATE-ISSUER" + }, + "toEmailAddress": { + "S": "TO-EMAIL-ADDRESS" + } + } + } + ] + }, + "chassisMake": { + "S": "CHASSIS-MAKE" + }, + "chassisModel": { + "S": "CHASSIS-MODEL" + }, + "bodyMake": { + "S": "BODY-MAKE" + }, + "bodyModel": { + "S": "BODY-MODEL" + }, + "modelLiteral": { + "S": "MODEL-LITERAL" + }, + "bodyType": { + "M": { + "code": { + "S": "a" + }, + "description": { + "S": "articulated" + } + } + }, + "manufactureYear": { + "N": "2020" + }, + "regnDate": { + "S": "2020-01-01" + }, + "firstUseDate": { + "S": "2020-01-01" + }, + "coifDate": { + "S": "2020-01-01" + }, + "ntaNumber": { + "S": "NTA-NUMBER" + }, + "coifSerialNumber": { + "S": "88888888" + }, + "coifCertifierName": { + "S": "COIF-CERTIFIER-NAME" + }, + "conversionRefNo": { + "S": "1010101010" + }, + "seatsLowerDeck": { + "N": "1" + }, + "seatsUpperDeck": { + "N": "1" + }, + "standingCapacity": { + "N": "1" + }, + "speedRestriction": { + "N": "1" + }, + "speedLimiterMrk": { + "BOOL": true + }, + "tachoExemptMrk": { + "BOOL": true + }, + "dispensations": { + "S": "DISPENSATIONS" + }, + "remarks": { + "S": "REMARKS" + }, + "reasonForCreation": { + "S": "REASON-FOR-CREATION" + }, + "statusCode": { + "S": "STATUS-CODE" + }, + "unladenWeight": { + "N": "1" + }, + "grossKerbWeight": { + "N": "1" + }, + "grossLadenWeight": { + "N": "1" + }, + "grossGbWeight": { + "N": "1" + }, + "grossDesignWeight": { + "N": "1" + }, + "trainGbWeight": { + "N": "1" + }, + "trainDesignWeight": { + "N": "1" + }, + "maxTrainGbWeight": { + "N": "1" + }, + "maxTrainDesignWeight": { + "N": "1" + }, + "maxLoadOnCoupling": { + "N": "1" + }, + "frameDescription": { + "S": "Channel section" + }, + "tyreUseCode": { + "S": "22" + }, + "roadFriendly": { + "BOOL": true + }, + "drawbarCouplingFitted": { + "BOOL": true + }, + "euroStandard": { + "S": "euroStd" + }, + "suspensionType": { + "S": "1" + }, + "couplingType": { + "S": "1" + }, + "dimensions": { + "M": { + "axleSpacing": { + "L": [ + { + "M": { + "axles": { + "S": "1-2" + }, + "value": { + "N": "1" + } + } + } + ] + }, + "length": { + "N": "1" + }, + "height": { + "N": "1" + }, + "width": { + "N": "1" + } + } + }, + "frontAxleTo5thWheelMin": { + "N": "1" + }, + "frontAxleTo5thWheelMax": { + "N": "1" + }, + "frontVehicleTo5thWheelCouplingMin": { + "N": "1" + }, + "frontVehicleTo5thWheelCouplingMax": { + "N": "1" + }, + "frontAxleToRearAxle": { + "N": "1" + }, + "rearAxleToRearTrl": { + "N": "1" + }, + "couplingCenterToRearAxleMin": { + "N": "1" + }, + "couplingCenterToRearAxleMax": { + "N": "1" + }, + "couplingCenterToRearTrlMin": { + "N": "1" + }, + "couplingCenterToRearTrlMax": { + "N": "1" + }, + "centreOfRearmostAxleToRearOfTrl": { + "N": "1" + }, + "notes": { + "S": "NOTES" + }, + "noOfAxles": { + "N": "1" + }, + "brakeCode": { + "S": "1" + }, + "createdByName": { + "S": "CREATED-BY-NAME-2" + }, + "createdById": { + "S": "CREATED-BY-ID-2" + }, + "lastUpdatedByName": { + "S": "LAST-UPDATED-BY-NAME-2" + }, + "lastUpdatedById": { + "S": "LAST-UPDATED-BY-ID-2" + }, + "updateType": { + "S": "adrUpdate" + }, + "vehicleClass": { + "M": { + "code": { + "S": "2" + }, + "description": { + "S": "motorbikes over 200cc or with a sidecar" + } + } + }, + "vehicleSubclass": { + "L": [ + { + "S": "1" + } + ] + }, + "vehicleType": { + "S": "psv" + }, + "vehicleSize": { + "S": "small" + }, + "numberOfSeatbelts": { + "S": "NUMBER-OF-SEATBELTS" + }, + "seatbeltInstallationApprovalDate": { + "S": "2020-01-01" + }, + "vehicleConfiguration": { + "S": "rigid" + }, + "brakes": { + "M": { + "brakeCodeOriginal": { + "S": "333" + }, + "brakeCode": { + "S": "666666" + }, + "dataTrBrakeOne": { + "S": "DATA-TR-BRAKE-ONE" + }, + "dataTrBrakeTwo": { + "S": "DATA-TR-BRAKE-TWO" + }, + "dataTrBrakeThree": { + "S": "DATA-TR-BRAKE-THREE" + }, + "retarderBrakeOne": { + "S": "electric" + }, + "retarderBrakeTwo": { + "S": "electric" + }, + "dtpNumber": { + "S": "666666" + }, + "brakeForceWheelsNotLocked": { + "M": { + "serviceBrakeForceA": { + "N": "1" + }, + "secondaryBrakeForceA": { + "N": "1" + }, + "parkingBrakeForceA": { + "N": "1" + } + } + }, + "brakeForceWheelsUpToHalfLocked": { + "M": { + "serviceBrakeForceB": { + "N": "1" + }, + "secondaryBrakeForceB": { + "N": "1" + }, + "parkingBrakeForceB": { + "N": "1" + } + } + }, + "loadSensingValve": { + "BOOL": true + }, + "antilockBrakingSystem": { + "BOOL": true + } + } + }, + "axles": { + "L": [ + { + "M": { + "axleNumber": { + "N": "1" + }, + "parkingBrakeMrk": { + "BOOL": true + }, + "weights": { + "M": { + "kerbWeight": { + "N": "1" + }, + "ladenWeight": { + "N": "1" + }, + "gbWeight": { + "N": "1" + }, + "eecWeight": { + "N": "1" + }, + "designWeight": { + "N": "1" + } + } + }, + "tyres": { + "M": { + "tyreSize": { + "S": "TYRE-SIZE" + }, + "plyRating": { + "S": "22" + }, + "fitmentCode": { + "S": "double" + }, + "dataTrAxles": { + "N": "1" + }, + "speedCategorySymbol": { + "S": "a7" + }, + "tyreCode": { + "N": "1" + } + } + }, + "brakes": { + "M": { + "brakeActuator": { + "N": "1" + }, + "leverLength": { + "N": "1" + }, + "springBrakeParking": { + "BOOL": true + } + } + } + } + } + ] + } + } + } + ] + } +} diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index c6db6fd..1ee94fc 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -3,11 +3,11 @@ import { TechRecordDocument, } from "../../../src/models/tech-record-document"; import { DynamoDbImage } from "../../../src/services/dynamodb-images"; -import { default as techRecordDocumentJson } from "../../resources/dynamodb-image-technical-record.json"; +import { default as techRecordDocumentJson } from "../../resources/dynamodb-image-technical-record-with-adr.json"; import { castToImageShape } from "../../utils"; describe("parseTechRecordDocument()", () => { - it("should successfully parse a DynamoDB image into a TechRecordDocument", () => { + it("should successfully parse a DynamoDB image with ADR into a TechRecordDocument", async () => { const image = DynamoDbImage.parse(castToImageShape(techRecordDocumentJson)); const techRecordDocument: TechRecordDocument = parseTechRecordDocument( @@ -52,9 +52,78 @@ describe("parseTechRecordDocument()", () => { "333" ); expect(techRecordDocument.techRecord![0].axles![0].axleNumber).toEqual(1); + + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateId).toEqual("CERTIFICATE-ID-1"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].createdByName).toEqual("CREATED-BY-NAME-01"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateType).toEqual("PASS"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].generatedTimestamp).toEqual("2023-04-01 01:49:00.055"); + + // ADR Details attributes + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].note).toEqual("additionalExaminerNotes_note_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].createdAtDate).toEqual("2023-05-30"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].lastUpdatedBy).toEqual("additionalExaminerNotes_lastUpdatedBy_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![0]).toEqual("1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![1]).toEqual("T1B"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrCertificateNotes).toEqual("adrCertificateNotes_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("applicantDetails_Name"); + + expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("BATTERY1"); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationsSeen).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeEndurance).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.compatibilityGroupJ).toEqual("I"); + expect(techRecordDocument.techRecord![0].adrDetails?.dangerousGoods).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.declarationsSeen).toEqual(false); + + expect(techRecordDocument.techRecord![0].adrDetails?.documents![0]).toEqual("documents_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.documents![1]).toEqual("documents_2"); + + expect(techRecordDocument.techRecord![0].adrDetails?.listStatementApplicable).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.m145Statement).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.newCertificateRequested).toEqual(false); + + expect(techRecordDocument.techRecord![0].adrDetails?.memosApply![0]).toEqual("07/09 3mth leak ext"); + + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![0]).toEqual("FP <61 (FL)"); + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturer).toEqual("tankManufacturer_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(2012); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankCode).toEqual("tankCode_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.specialProvisions).toEqual("specialProvisions_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturerSerialNo).toEqual("1234"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankTypeAppNo).toEqual("9876"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2Type).toEqual("initial"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateApprovalNo).toEqual("12345"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3Type).toEqual("intermediate"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); + + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); + + expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(7.50); + }); - it("should successfully parse a DynamoDB image, with no authIntoService, into a TechRecordDocument", () => { + it("should successfully parse a DynamoDB image, with ADR, with no authIntoService, into a TechRecordDocument", async () => { // @ts-ignore delete techRecordDocumentJson.techRecord.L[0].M.authIntoService; const image = DynamoDbImage.parse(castToImageShape(techRecordDocumentJson)); @@ -99,5 +168,74 @@ describe("parseTechRecordDocument()", () => { "333" ); expect(techRecordDocument.techRecord![0].axles![0].axleNumber).toEqual(1); + + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateId).toEqual("CERTIFICATE-ID-1"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].createdByName).toEqual("CREATED-BY-NAME-01"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].certificateType).toEqual("PASS"); + expect(techRecordDocument.techRecord![0].adrPassCertificateDetails![0].generatedTimestamp).toEqual("2023-04-01 01:49:00.055"); + + // ADR Details attributes + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].note).toEqual("additionalExaminerNotes_note_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].createdAtDate).toEqual("2023-05-30"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalExaminerNotes![0].lastUpdatedBy).toEqual("additionalExaminerNotes_lastUpdatedBy_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![0]).toEqual("1"); + expect(techRecordDocument.techRecord![0].adrDetails?.additionalNotes?.number![1]).toEqual("T1B"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrCertificateNotes).toEqual("adrCertificateNotes_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.adrTypeApprovalNo).toEqual("adrTypeApprovalNo_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.applicantDetails?.name).toEqual("applicantDetails_Name"); + + expect(techRecordDocument.techRecord![0].adrDetails?.batteryListNumber).toEqual("BATTERY1"); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationIssuer).toEqual("brakeDeclarationIssuer_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.brakeDeclarationsSeen).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.brakeEndurance).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.compatibilityGroupJ).toEqual("I"); + expect(techRecordDocument.techRecord![0].adrDetails?.dangerousGoods).toEqual(false); + expect(techRecordDocument.techRecord![0].adrDetails?.declarationsSeen).toEqual(false); + + expect(techRecordDocument.techRecord![0].adrDetails?.documents![0]).toEqual("documents_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.documents![1]).toEqual("documents_2"); + + expect(techRecordDocument.techRecord![0].adrDetails?.listStatementApplicable).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.m145Statement).toEqual(true); + expect(techRecordDocument.techRecord![0].adrDetails?.newCertificateRequested).toEqual(false); + + expect(techRecordDocument.techRecord![0].adrDetails?.memosApply![0]).toEqual("07/09 3mth leak ext"); + + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![0]).toEqual("FP <61 (FL)"); + expect(techRecordDocument.techRecord![0].adrDetails?.permittedDangerousGoods![1]).toEqual("Carbon Disulphide"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturer).toEqual("tankManufacturer_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.yearOfManufacture).toEqual(2012); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankCode).toEqual("tankCode_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.specialProvisions).toEqual("specialProvisions_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankManufacturerSerialNo).toEqual("1234"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankTypeAppNo).toEqual("9876"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2Type).toEqual("initial"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateApprovalNo).toEqual("12345"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc2Details?.tc2IntermediateExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3Type).toEqual("intermediate"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); + + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); + + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); + expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); + + expect(techRecordDocument.techRecord![0].adrDetails?.weight).toEqual(7.50); + }); }); diff --git a/tsconfig.json b/tsconfig.json index cf02692..b5af863 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,6 @@ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, - "types": [] + "types": ["jest", "node"] } } From 7e85d064ab29580808b257df86aa3d30f952c991 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Tue, 13 Feb 2024 13:27:24 +0000 Subject: [PATCH 38/44] fix: updating for tank statement attributes, add conditions for missing attributes --- src/models/adr-details.ts | 155 ++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 66 deletions(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index 36db7db..c8515ba 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -120,7 +120,6 @@ export interface AdditionalNotes { export interface Tank { tankDetails?: TankDetails; - tankStatement?: TankStatement; } export interface TankDetails { @@ -132,6 +131,7 @@ export interface TankDetails { tankTypeAppNo?: string; tc2Details?: Tc2Details; tc3Details?: Tc3Details; + tankStatement?: TankStatement; } export interface TankStatement { @@ -149,7 +149,6 @@ export interface Tc2Details { tc2IntermediateExpiryDate?: string; } - export type Tc3Details = Tc3DetailsItem[]; export interface Tc3DetailsItem { @@ -170,7 +169,9 @@ export const parseAdrDetails = ( "additionalNotes" )!; const additionalNotes: AdditionalNotes = { - number: parseStringArray(additionalNotesImage.getList("number")) as additionalNotesNumberEnum[], + number: parseStringArray( + additionalNotesImage.getList("number")! + ) as additionalNotesNumberEnum[], // guidanceNotes: parseStringArray( // additionalNotesImage.getList("guidanceNotes") // ) as additionalNotesguidanceNotesEnum[], @@ -180,19 +181,19 @@ export const parseAdrDetails = ( "applicantDetails" )!; const applicantDetails: ApplicantDetails = { - name: applicantDetailsImage.getString("name"), - street: applicantDetailsImage.getString("street"), - town: applicantDetailsImage.getString("town"), - city: applicantDetailsImage.getString("city"), - postcode: applicantDetailsImage.getString("postcode"), + name: applicantDetailsImage.getString("name")!, + street: applicantDetailsImage.getString("street")!, + town: applicantDetailsImage.getString("town")!, + city: applicantDetailsImage.getString("city")!, + postcode: applicantDetailsImage.getString("postcode")!, }; const vehicleDetailsImage: DynamoDbImage = adrDetails.getMap( "vehicleDetails" )!; const vehicleDetails: VehicleDetails = { - type: vehicleDetailsImage.getString("type") as VehicleDetailsTypeEnum, - approvalDate: vehicleDetailsImage.getString("approvalDate"), + type: vehicleDetailsImage.getString("type")! as VehicleDetailsTypeEnum, + approvalDate: vehicleDetailsImage.getString("approvalDate")!, }; const tankImage: DynamoDbImage = adrDetails.getMap("tank")!; @@ -201,13 +202,13 @@ export const parseAdrDetails = ( const tc2DetailsImage: DynamoDbImage = tankDetailsImage.getMap("tc2Details")!; const tc2Details: Tc2Details = { - tc2Type: tc2DetailsImage.getString("tc2Type") as Tc2TypeEnum, + tc2Type: tc2DetailsImage.getString("tc2Type")! as Tc2TypeEnum, tc2IntermediateApprovalNo: tc2DetailsImage.getString( "tc2IntermediateApprovalNo" - ), + )!, tc2IntermediateExpiryDate: tc2DetailsImage.getString( "tc2IntermediateExpiryDate" - ), + )!, }; const tc3DetailsImage: DynamoDbImage = tankDetailsImage.getList( @@ -215,86 +216,108 @@ export const parseAdrDetails = ( )!; const tc3Details: Tc3Details = []; - for (const key of tc3DetailsImage.getKeys()) { - const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; - tc3Details.push({ - tc3Type: tc3DetailsItemImage.getString("tc3Type") as Tc3TypeEnum, - tc3PeriodicNumber: tc3DetailsItemImage.getString("tc3PeriodicNumber"), - tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( - "tc3PeriodicExpiryDate" - ), - }); + if (tc3DetailsImage) { + for (const key of tc3DetailsImage.getKeys()!) { + const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; + tc3Details.push({ + tc3Type: tc3DetailsItemImage.getString("tc3Type")! as Tc3TypeEnum, + tc3PeriodicNumber: tc3DetailsItemImage.getString("tc3PeriodicNumber")!, + tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( + "tc3PeriodicExpiryDate" + )!, + }); + } + } + + const tankStatementImage: DynamoDbImage = tankDetailsImage.getMap( + "tankStatement" + )!; + const tankStatement: TankStatement = {}; + + if (tankStatementImage) { + tankStatement.substancesPermitted = tankStatementImage.getString( + "substancesPermitted" + )! as substancesPermittedEnum; + tankStatement.select = tankStatementImage.getString( + "select" + )! as tankStatementSelectEnum; + tankStatement.statement = tankStatementImage.getString("statement")!; + tankStatement.productListRefNo = tankStatementImage.getString( + "productListRefNo" + )!; + tankStatement.productListUnNo = parseStringArray( + tankStatementImage.getList("productListUnNo")! + ); + tankStatement.productList = tankStatementImage.getString("productList")!; } const tankDetails: TankDetails = { - tankManufacturer: tankDetailsImage.getString("tankManufacturer"), - yearOfManufacture: tankDetailsImage.getNumber("yearOfManufacture"), - tankCode: tankDetailsImage.getString("tankCode"), - specialProvisions: tankDetailsImage.getString("specialProvisions"), + tankManufacturer: tankDetailsImage.getString("tankManufacturer")!, + yearOfManufacture: tankDetailsImage.getNumber("yearOfManufacture")!, + tankCode: tankDetailsImage.getString("tankCode")!, + specialProvisions: tankDetailsImage.getString("specialProvisions")!, tankManufacturerSerialNo: tankDetailsImage.getString( "tankManufacturerSerialNo" - ), - tankTypeAppNo: tankDetailsImage.getString("tankTypeAppNo"), + )!, + tankTypeAppNo: tankDetailsImage.getString("tankTypeAppNo")!, tc2Details, tc3Details, - }; - - const tankStatementImage: DynamoDbImage = tankImage.getMap("tankStatement")!; - const tankStatement: TankStatement = { - substancesPermitted: tankStatementImage.getString("substancesPermitted") as substancesPermittedEnum, - select: tankStatementImage.getString("select") as tankStatementSelectEnum, - statement: tankStatementImage.getString("statement"), - productListRefNo: tankStatementImage.getString("productListRefNo"), - productListUnNo: parseStringArray( - tankStatementImage.getList("productListUnNo") - ), - productList: tankStatementImage.getString("productList"), + tankStatement, }; const tank: Tank = { tankDetails, - tankStatement, }; - const additionalExaminerNotesImage: DynamoDbImage = adrDetails.getList( "additionalExaminerNotes" )!; const additionalExaminerNotes: AdditionalExaminerNotes = []; - for (const key of additionalExaminerNotesImage.getKeys()) { - const additionalExaminerNotesItemImage = additionalExaminerNotesImage.getMap(key)!; - additionalExaminerNotes.push({ - note: additionalExaminerNotesItemImage.getString("note"), - createdAtDate: additionalExaminerNotesItemImage.getString("createdAtDate"), - lastUpdatedBy: additionalExaminerNotesItemImage.getString("lastUpdatedBy"), - }); + if (additionalExaminerNotesImage) { + for (const key of additionalExaminerNotesImage.getKeys()) { + const additionalExaminerNotesItemImage = additionalExaminerNotesImage.getMap( + key + )!; + additionalExaminerNotes.push({ + note: additionalExaminerNotesItemImage.getString("note")!, + createdAtDate: additionalExaminerNotesItemImage.getString( + "createdAtDate" + )!, + lastUpdatedBy: additionalExaminerNotesItemImage.getString( + "lastUpdatedBy" + )!, + }); + } } - return { vehicleDetails, - listStatementApplicable: adrDetails.getBoolean("listStatementApplicable"), - batteryListNumber: adrDetails.getString("batteryListNumber"), - declarationsSeen: adrDetails.getBoolean("declarationsSeen"), - brakeDeclarationsSeen: adrDetails.getBoolean("brakeDeclarationsSeen"), - brakeDeclarationIssuer: adrDetails.getString("brakeDeclarationIssuer"), - brakeEndurance: adrDetails.getBoolean("brakeEndurance"), - weight: adrDetails.getNumber("weight"), - newCertificateRequested: adrDetails.getBoolean("newCertificateRequested"), - compatibilityGroupJ: adrDetails.getString("compatibilityGroupJ") as compatibilityGroupJEnum, - documents: parseStringArray(adrDetails.getList("documents")), + listStatementApplicable: adrDetails.getBoolean("listStatementApplicable")!, + batteryListNumber: adrDetails.getString("batteryListNumber")!, + declarationsSeen: adrDetails.getBoolean("declarationsSeen")!, + brakeDeclarationsSeen: adrDetails.getBoolean("brakeDeclarationsSeen")!, + brakeDeclarationIssuer: adrDetails.getString("brakeDeclarationIssuer")!, + brakeEndurance: adrDetails.getBoolean("brakeEndurance")!, + weight: adrDetails.getNumber("weight")!, + newCertificateRequested: adrDetails.getBoolean("newCertificateRequested")!, + compatibilityGroupJ: adrDetails.getString( + "compatibilityGroupJ" + )! as compatibilityGroupJEnum, + documents: parseStringArray(adrDetails.getList("documents"))!, permittedDangerousGoods: parseStringArray( - adrDetails.getList("permittedDangerousGoods") + adrDetails.getList("permittedDangerousGoods")! ) as permittedDangerousGoodsEnum[], additionalExaminerNotes, applicantDetails, - dangerousGoods: adrDetails.getBoolean("dangerousGoods"), - memosApply: parseStringArray(adrDetails.getList("memosApply")) as memosApplyEnum[], - m145Statement: adrDetails.getBoolean("m145Statement"), + dangerousGoods: adrDetails.getBoolean("dangerousGoods")!, + memosApply: parseStringArray( + adrDetails.getList("memosApply")! + ) as memosApplyEnum[], + m145Statement: adrDetails.getBoolean("m145Statement")!, additionalNotes, - adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo"), - adrCertificateNotes: adrDetails.getString("adrCertificateNotes"), + adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo")!, + adrCertificateNotes: adrDetails.getString("adrCertificateNotes")!, tank, }; }; From 0c6845ce3e4b259e444fd107e5519e4961be949f Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Tue, 13 Feb 2024 13:28:09 +0000 Subject: [PATCH 39/44] fix: updating for tank statement attributes --- src/services/tech-record-document-conversion.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/services/tech-record-document-conversion.ts b/src/services/tech-record-document-conversion.ts index da021c4..1198d33 100644 --- a/src/services/tech-record-document-conversion.ts +++ b/src/services/tech-record-document-conversion.ts @@ -272,11 +272,11 @@ const upsertTechRecords = async ( ?.tc2IntermediateApprovalNo, techRecord.adrDetails.tank?.tankDetails?.tc2Details ?.tc2IntermediateExpiryDate, - techRecord.adrDetails.tank?.tankStatement?.substancesPermitted, - // techRecord.adrDetails.tank?.tankStatement?.select, - techRecord.adrDetails.tank?.tankStatement?.statement, - techRecord.adrDetails.tank?.tankStatement?.productListRefNo, - techRecord.adrDetails.tank?.tankStatement?.productList, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.substancesPermitted, + // techRecord.adrDetails.tank?.tankDetails?.tankStatement?.select, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.statement, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.productListRefNo, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.productList, techRecord.adrDetails.m145Statement, // techRecord.adrDetails.newCertificateRequested, ], @@ -845,12 +845,12 @@ const upsertAdrProductListUnNo = async ( adrDetailsId: string, techRecord: TechRecord ): Promise => { - if (techRecord.adrDetails?.tank?.tankStatement?.productListUnNo) { + if (techRecord.adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo) { debugLog( `upsertTechRecords: Upserting ADR tankStatement productListUnNo (adr-details-id: ${adrDetailsId})...` ); - for (const productListUnNo of techRecord.adrDetails?.tank?.tankStatement + for (const productListUnNo of techRecord.adrDetails?.tank?.tankDetails?.tankStatement ?.productListUnNo) { const productListUnNoId = await upsertAdrProductListUnNoList( connection, From 485fa8f7f866513a0c0e9066d97a761dbc055710 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Tue, 13 Feb 2024 13:28:39 +0000 Subject: [PATCH 40/44] fix: updating for tank statement attributes --- tests/integration/tech-record-document-conversion.intTest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/tech-record-document-conversion.intTest.ts b/tests/integration/tech-record-document-conversion.intTest.ts index cbc4b7a..469946a 100644 --- a/tests/integration/tech-record-document-conversion.intTest.ts +++ b/tests/integration/tech-record-document-conversion.intTest.ts @@ -1106,7 +1106,7 @@ export const techRecordDocumentConversion = () => // productListUnNo removed from payload delete techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M - .tank.M.tankStatement.M.productListUnNo; + .tank.M.tankDetails.M.tankStatement.M.productListUnNo; const event = { Records: [ @@ -1206,7 +1206,7 @@ export const techRecordDocumentConversion = () => S: "different_tankManufacturer", }; // update missing attribute to NULL - techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankStatement.M.productListUnNo = { NULL: true }; + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankDetails.M.tankStatement.M.productListUnNo = { NULL: true }; const event = { Records: [ From cd24248ef2708bfafa7bb8d23e2fa610b1d95d7e Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Tue, 13 Feb 2024 13:29:26 +0000 Subject: [PATCH 41/44] fix: updating for tank statement attributes --- ...amodb-image-technical-record-with-adr.json | 73 ++++++++++--------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json index 0341ca3..7bac110 100644 --- a/tests/resources/dynamodb-image-technical-record-with-adr.json +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -68,8 +68,12 @@ "M": { "number": { "L": [ - {"S": "1"}, - {"S": "T1B"} + { + "S": "1" + }, + { + "S": "T1B" + } ] } } @@ -127,7 +131,7 @@ }, { "S": "documents_2" - }, + }, { "S": "documents_3" } @@ -142,7 +146,6 @@ "newCertificateRequested": { "BOOL": false }, - "memosApply": { "L": [ { @@ -157,7 +160,7 @@ }, { "S": "Carbon Disulphide" - }, + }, { "S": "Hydrogen" } @@ -214,41 +217,41 @@ } } ] - } - } - }, - "tankStatement": { - "M": { - "select":{ - "S": "Product list" - }, - "substancesPermitted": { - "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" - }, - "statement": { - "S": "statement_1" - }, - "productListRefNo": { - "S": "123456" }, - "productListUnNo": { - "L": [ - { - "S": "123123" + "tankStatement": { + "M": { + "select": { + "S": "Product list" }, - { - "S": "987987" + "substancesPermitted": { + "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" }, - { - "S": "135790" + "statement": { + "S": "statement_1" + }, + "productListRefNo": { + "S": "123456" + }, + "productListUnNo": { + "L": [ + { + "S": "123123" + }, + { + "S": "987987" + }, + { + "S": "135790" + } + ] + }, + "productList": { + "S": "productList_1" } - ] - }, - "productList": { - "S": "productList_1" + } } } - } + } } }, "vehicleDetails": { @@ -265,7 +268,7 @@ "N": "7.50" } } - }, + }, "recordCompleteness": { "S": "88888888" }, From f4bbfbd5ee1a4dc0e0c7dbd328a7882cc317e149 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Tue, 13 Feb 2024 13:29:40 +0000 Subject: [PATCH 42/44] fix: updating for tank statement attributes --- .../models/tech-record-document.unitTest.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index 1ee94fc..e38e8ff 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -108,13 +108,13 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productList).toEqual("productList_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![1]).toEqual("987987"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); @@ -224,13 +224,13 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productList).toEqual("productList_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![1]).toEqual("987987"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); From 914302ed6aa2e2145109ab45c62cd650da30aba8 Mon Sep 17 00:00:00 2001 From: DanielFry-bjss <135820353+DanielFry-bjss@users.noreply.github.com> Date: Tue, 13 Feb 2024 14:31:36 +0000 Subject: [PATCH 43/44] Feature/cb2 10594 (#81) * rectifying data type mismatches, add un-defined Enums and attributes, adding in-line comments * add AdrCertificateDetails interface and parsing function * adding guidanceNotes Enum * adding m145 attribute as per documentation change * feat: adr details added, test resource for technoical record added, unit test added * style: rearrange enums * fix: replace ! with ? for optional attributes * fix: memosApplyEnum value updated * fix: 2 new attributes added to adrDetails, as per documentation * feat: tab le definition * fix: enum updated * feat: adr tables added to the tech record list of tables * feat: new function added for partial upsert based on condition attribute * feat: some adr table detail updated * feat: upsert fun ctionality added for adr-details attributes in tech record * feat: adr parts added to tech record integration test * feat: docker's mysql image updated to version 8 - consistent with recent RDS engine upgarde for NOP * feat: adr attribute values updated * feat: test updated as adr attribute values updated in json file * fix: changes reverted back to original * fix: changes reverted back to original * fix: changes reverted back to original * feat: cleaning and bringing in adr pass certificate * feat: cleaning and bringing in adr pass certificate * feat: cleaning and bringing in adr pass certificate * fix: removed async keyword to avoid error when running the test * fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo * fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo * fix: bringing in to be able to run integration tests on my mac and be able to push changes into repo * fix: updating adr pass certificate function * fix: updating adr pass certificate field name * fix: updating adr pass certificate var name * feat: adding integration tests for additional test scenarios * feat: adding adr pass certificate attribute * feat: adding adr pass certificate attribute test to unit test * fix: syntax fixed * fix: updating for tank statement attributes, add conditions for missing attributes * fix: updating for tank statement attributes * fix: updating for tank statement attributes * fix: updating for tank statement attributes * fix: updating for tank statement attributes --------- Co-authored-by: Meys Torkaman Co-authored-by: meys-bjss <140601718+meys-bjss@users.noreply.github.com> --- src/models/adr-details.ts | 155 ++++++++++-------- .../tech-record-document-conversion.ts | 14 +- ...tech-record-document-conversion.intTest.ts | 4 +- ...amodb-image-technical-record-with-adr.json | 73 +++++---- .../models/tech-record-document.unitTest.ts | 24 +-- 5 files changed, 148 insertions(+), 122 deletions(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index 36db7db..c8515ba 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -120,7 +120,6 @@ export interface AdditionalNotes { export interface Tank { tankDetails?: TankDetails; - tankStatement?: TankStatement; } export interface TankDetails { @@ -132,6 +131,7 @@ export interface TankDetails { tankTypeAppNo?: string; tc2Details?: Tc2Details; tc3Details?: Tc3Details; + tankStatement?: TankStatement; } export interface TankStatement { @@ -149,7 +149,6 @@ export interface Tc2Details { tc2IntermediateExpiryDate?: string; } - export type Tc3Details = Tc3DetailsItem[]; export interface Tc3DetailsItem { @@ -170,7 +169,9 @@ export const parseAdrDetails = ( "additionalNotes" )!; const additionalNotes: AdditionalNotes = { - number: parseStringArray(additionalNotesImage.getList("number")) as additionalNotesNumberEnum[], + number: parseStringArray( + additionalNotesImage.getList("number")! + ) as additionalNotesNumberEnum[], // guidanceNotes: parseStringArray( // additionalNotesImage.getList("guidanceNotes") // ) as additionalNotesguidanceNotesEnum[], @@ -180,19 +181,19 @@ export const parseAdrDetails = ( "applicantDetails" )!; const applicantDetails: ApplicantDetails = { - name: applicantDetailsImage.getString("name"), - street: applicantDetailsImage.getString("street"), - town: applicantDetailsImage.getString("town"), - city: applicantDetailsImage.getString("city"), - postcode: applicantDetailsImage.getString("postcode"), + name: applicantDetailsImage.getString("name")!, + street: applicantDetailsImage.getString("street")!, + town: applicantDetailsImage.getString("town")!, + city: applicantDetailsImage.getString("city")!, + postcode: applicantDetailsImage.getString("postcode")!, }; const vehicleDetailsImage: DynamoDbImage = adrDetails.getMap( "vehicleDetails" )!; const vehicleDetails: VehicleDetails = { - type: vehicleDetailsImage.getString("type") as VehicleDetailsTypeEnum, - approvalDate: vehicleDetailsImage.getString("approvalDate"), + type: vehicleDetailsImage.getString("type")! as VehicleDetailsTypeEnum, + approvalDate: vehicleDetailsImage.getString("approvalDate")!, }; const tankImage: DynamoDbImage = adrDetails.getMap("tank")!; @@ -201,13 +202,13 @@ export const parseAdrDetails = ( const tc2DetailsImage: DynamoDbImage = tankDetailsImage.getMap("tc2Details")!; const tc2Details: Tc2Details = { - tc2Type: tc2DetailsImage.getString("tc2Type") as Tc2TypeEnum, + tc2Type: tc2DetailsImage.getString("tc2Type")! as Tc2TypeEnum, tc2IntermediateApprovalNo: tc2DetailsImage.getString( "tc2IntermediateApprovalNo" - ), + )!, tc2IntermediateExpiryDate: tc2DetailsImage.getString( "tc2IntermediateExpiryDate" - ), + )!, }; const tc3DetailsImage: DynamoDbImage = tankDetailsImage.getList( @@ -215,86 +216,108 @@ export const parseAdrDetails = ( )!; const tc3Details: Tc3Details = []; - for (const key of tc3DetailsImage.getKeys()) { - const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; - tc3Details.push({ - tc3Type: tc3DetailsItemImage.getString("tc3Type") as Tc3TypeEnum, - tc3PeriodicNumber: tc3DetailsItemImage.getString("tc3PeriodicNumber"), - tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( - "tc3PeriodicExpiryDate" - ), - }); + if (tc3DetailsImage) { + for (const key of tc3DetailsImage.getKeys()!) { + const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; + tc3Details.push({ + tc3Type: tc3DetailsItemImage.getString("tc3Type")! as Tc3TypeEnum, + tc3PeriodicNumber: tc3DetailsItemImage.getString("tc3PeriodicNumber")!, + tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( + "tc3PeriodicExpiryDate" + )!, + }); + } + } + + const tankStatementImage: DynamoDbImage = tankDetailsImage.getMap( + "tankStatement" + )!; + const tankStatement: TankStatement = {}; + + if (tankStatementImage) { + tankStatement.substancesPermitted = tankStatementImage.getString( + "substancesPermitted" + )! as substancesPermittedEnum; + tankStatement.select = tankStatementImage.getString( + "select" + )! as tankStatementSelectEnum; + tankStatement.statement = tankStatementImage.getString("statement")!; + tankStatement.productListRefNo = tankStatementImage.getString( + "productListRefNo" + )!; + tankStatement.productListUnNo = parseStringArray( + tankStatementImage.getList("productListUnNo")! + ); + tankStatement.productList = tankStatementImage.getString("productList")!; } const tankDetails: TankDetails = { - tankManufacturer: tankDetailsImage.getString("tankManufacturer"), - yearOfManufacture: tankDetailsImage.getNumber("yearOfManufacture"), - tankCode: tankDetailsImage.getString("tankCode"), - specialProvisions: tankDetailsImage.getString("specialProvisions"), + tankManufacturer: tankDetailsImage.getString("tankManufacturer")!, + yearOfManufacture: tankDetailsImage.getNumber("yearOfManufacture")!, + tankCode: tankDetailsImage.getString("tankCode")!, + specialProvisions: tankDetailsImage.getString("specialProvisions")!, tankManufacturerSerialNo: tankDetailsImage.getString( "tankManufacturerSerialNo" - ), - tankTypeAppNo: tankDetailsImage.getString("tankTypeAppNo"), + )!, + tankTypeAppNo: tankDetailsImage.getString("tankTypeAppNo")!, tc2Details, tc3Details, - }; - - const tankStatementImage: DynamoDbImage = tankImage.getMap("tankStatement")!; - const tankStatement: TankStatement = { - substancesPermitted: tankStatementImage.getString("substancesPermitted") as substancesPermittedEnum, - select: tankStatementImage.getString("select") as tankStatementSelectEnum, - statement: tankStatementImage.getString("statement"), - productListRefNo: tankStatementImage.getString("productListRefNo"), - productListUnNo: parseStringArray( - tankStatementImage.getList("productListUnNo") - ), - productList: tankStatementImage.getString("productList"), + tankStatement, }; const tank: Tank = { tankDetails, - tankStatement, }; - const additionalExaminerNotesImage: DynamoDbImage = adrDetails.getList( "additionalExaminerNotes" )!; const additionalExaminerNotes: AdditionalExaminerNotes = []; - for (const key of additionalExaminerNotesImage.getKeys()) { - const additionalExaminerNotesItemImage = additionalExaminerNotesImage.getMap(key)!; - additionalExaminerNotes.push({ - note: additionalExaminerNotesItemImage.getString("note"), - createdAtDate: additionalExaminerNotesItemImage.getString("createdAtDate"), - lastUpdatedBy: additionalExaminerNotesItemImage.getString("lastUpdatedBy"), - }); + if (additionalExaminerNotesImage) { + for (const key of additionalExaminerNotesImage.getKeys()) { + const additionalExaminerNotesItemImage = additionalExaminerNotesImage.getMap( + key + )!; + additionalExaminerNotes.push({ + note: additionalExaminerNotesItemImage.getString("note")!, + createdAtDate: additionalExaminerNotesItemImage.getString( + "createdAtDate" + )!, + lastUpdatedBy: additionalExaminerNotesItemImage.getString( + "lastUpdatedBy" + )!, + }); + } } - return { vehicleDetails, - listStatementApplicable: adrDetails.getBoolean("listStatementApplicable"), - batteryListNumber: adrDetails.getString("batteryListNumber"), - declarationsSeen: adrDetails.getBoolean("declarationsSeen"), - brakeDeclarationsSeen: adrDetails.getBoolean("brakeDeclarationsSeen"), - brakeDeclarationIssuer: adrDetails.getString("brakeDeclarationIssuer"), - brakeEndurance: adrDetails.getBoolean("brakeEndurance"), - weight: adrDetails.getNumber("weight"), - newCertificateRequested: adrDetails.getBoolean("newCertificateRequested"), - compatibilityGroupJ: adrDetails.getString("compatibilityGroupJ") as compatibilityGroupJEnum, - documents: parseStringArray(adrDetails.getList("documents")), + listStatementApplicable: adrDetails.getBoolean("listStatementApplicable")!, + batteryListNumber: adrDetails.getString("batteryListNumber")!, + declarationsSeen: adrDetails.getBoolean("declarationsSeen")!, + brakeDeclarationsSeen: adrDetails.getBoolean("brakeDeclarationsSeen")!, + brakeDeclarationIssuer: adrDetails.getString("brakeDeclarationIssuer")!, + brakeEndurance: adrDetails.getBoolean("brakeEndurance")!, + weight: adrDetails.getNumber("weight")!, + newCertificateRequested: adrDetails.getBoolean("newCertificateRequested")!, + compatibilityGroupJ: adrDetails.getString( + "compatibilityGroupJ" + )! as compatibilityGroupJEnum, + documents: parseStringArray(adrDetails.getList("documents"))!, permittedDangerousGoods: parseStringArray( - adrDetails.getList("permittedDangerousGoods") + adrDetails.getList("permittedDangerousGoods")! ) as permittedDangerousGoodsEnum[], additionalExaminerNotes, applicantDetails, - dangerousGoods: adrDetails.getBoolean("dangerousGoods"), - memosApply: parseStringArray(adrDetails.getList("memosApply")) as memosApplyEnum[], - m145Statement: adrDetails.getBoolean("m145Statement"), + dangerousGoods: adrDetails.getBoolean("dangerousGoods")!, + memosApply: parseStringArray( + adrDetails.getList("memosApply")! + ) as memosApplyEnum[], + m145Statement: adrDetails.getBoolean("m145Statement")!, additionalNotes, - adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo"), - adrCertificateNotes: adrDetails.getString("adrCertificateNotes"), + adrTypeApprovalNo: adrDetails.getString("adrTypeApprovalNo")!, + adrCertificateNotes: adrDetails.getString("adrCertificateNotes")!, tank, }; }; diff --git a/src/services/tech-record-document-conversion.ts b/src/services/tech-record-document-conversion.ts index da021c4..1198d33 100644 --- a/src/services/tech-record-document-conversion.ts +++ b/src/services/tech-record-document-conversion.ts @@ -272,11 +272,11 @@ const upsertTechRecords = async ( ?.tc2IntermediateApprovalNo, techRecord.adrDetails.tank?.tankDetails?.tc2Details ?.tc2IntermediateExpiryDate, - techRecord.adrDetails.tank?.tankStatement?.substancesPermitted, - // techRecord.adrDetails.tank?.tankStatement?.select, - techRecord.adrDetails.tank?.tankStatement?.statement, - techRecord.adrDetails.tank?.tankStatement?.productListRefNo, - techRecord.adrDetails.tank?.tankStatement?.productList, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.substancesPermitted, + // techRecord.adrDetails.tank?.tankDetails?.tankStatement?.select, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.statement, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.productListRefNo, + techRecord.adrDetails.tank?.tankDetails?.tankStatement?.productList, techRecord.adrDetails.m145Statement, // techRecord.adrDetails.newCertificateRequested, ], @@ -845,12 +845,12 @@ const upsertAdrProductListUnNo = async ( adrDetailsId: string, techRecord: TechRecord ): Promise => { - if (techRecord.adrDetails?.tank?.tankStatement?.productListUnNo) { + if (techRecord.adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo) { debugLog( `upsertTechRecords: Upserting ADR tankStatement productListUnNo (adr-details-id: ${adrDetailsId})...` ); - for (const productListUnNo of techRecord.adrDetails?.tank?.tankStatement + for (const productListUnNo of techRecord.adrDetails?.tank?.tankDetails?.tankStatement ?.productListUnNo) { const productListUnNoId = await upsertAdrProductListUnNoList( connection, diff --git a/tests/integration/tech-record-document-conversion.intTest.ts b/tests/integration/tech-record-document-conversion.intTest.ts index cbc4b7a..469946a 100644 --- a/tests/integration/tech-record-document-conversion.intTest.ts +++ b/tests/integration/tech-record-document-conversion.intTest.ts @@ -1106,7 +1106,7 @@ export const techRecordDocumentConversion = () => // productListUnNo removed from payload delete techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M - .tank.M.tankStatement.M.productListUnNo; + .tank.M.tankDetails.M.tankStatement.M.productListUnNo; const event = { Records: [ @@ -1206,7 +1206,7 @@ export const techRecordDocumentConversion = () => S: "different_tankManufacturer", }; // update missing attribute to NULL - techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankStatement.M.productListUnNo = { NULL: true }; + techRecordDocumentJsonNew.techRecord.L[0].M.adrDetails.M.tank.M.tankDetails.M.tankStatement.M.productListUnNo = { NULL: true }; const event = { Records: [ diff --git a/tests/resources/dynamodb-image-technical-record-with-adr.json b/tests/resources/dynamodb-image-technical-record-with-adr.json index 0341ca3..7bac110 100644 --- a/tests/resources/dynamodb-image-technical-record-with-adr.json +++ b/tests/resources/dynamodb-image-technical-record-with-adr.json @@ -68,8 +68,12 @@ "M": { "number": { "L": [ - {"S": "1"}, - {"S": "T1B"} + { + "S": "1" + }, + { + "S": "T1B" + } ] } } @@ -127,7 +131,7 @@ }, { "S": "documents_2" - }, + }, { "S": "documents_3" } @@ -142,7 +146,6 @@ "newCertificateRequested": { "BOOL": false }, - "memosApply": { "L": [ { @@ -157,7 +160,7 @@ }, { "S": "Carbon Disulphide" - }, + }, { "S": "Hydrogen" } @@ -214,41 +217,41 @@ } } ] - } - } - }, - "tankStatement": { - "M": { - "select":{ - "S": "Product list" - }, - "substancesPermitted": { - "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" - }, - "statement": { - "S": "statement_1" - }, - "productListRefNo": { - "S": "123456" }, - "productListUnNo": { - "L": [ - { - "S": "123123" + "tankStatement": { + "M": { + "select": { + "S": "Product list" }, - { - "S": "987987" + "substancesPermitted": { + "S": "Substances permitted under the tank code and any special provisions specified in 9 may be carried" }, - { - "S": "135790" + "statement": { + "S": "statement_1" + }, + "productListRefNo": { + "S": "123456" + }, + "productListUnNo": { + "L": [ + { + "S": "123123" + }, + { + "S": "987987" + }, + { + "S": "135790" + } + ] + }, + "productList": { + "S": "productList_1" } - ] - }, - "productList": { - "S": "productList_1" + } } } - } + } } }, "vehicleDetails": { @@ -265,7 +268,7 @@ "N": "7.50" } } - }, + }, "recordCompleteness": { "S": "88888888" }, diff --git a/tests/unit/models/tech-record-document.unitTest.ts b/tests/unit/models/tech-record-document.unitTest.ts index 1ee94fc..e38e8ff 100644 --- a/tests/unit/models/tech-record-document.unitTest.ts +++ b/tests/unit/models/tech-record-document.unitTest.ts @@ -108,13 +108,13 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productList).toEqual("productList_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![1]).toEqual("987987"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); @@ -224,13 +224,13 @@ describe("parseTechRecordDocument()", () => { expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicNumber).toEqual("98765"); expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tc3Details![0].tc3PeriodicExpiryDate).toEqual("2024-06-01"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.select).toEqual("Product list"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.statement).toEqual("statement_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListRefNo).toEqual("123456"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productList).toEqual("productList_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.select).toEqual("Product list"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.statement).toEqual("statement_1"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListRefNo).toEqual("123456"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productList).toEqual("productList_1"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![0]).toEqual("123123"); - expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankStatement?.productListUnNo![1]).toEqual("987987"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![0]).toEqual("123123"); + expect(techRecordDocument.techRecord![0].adrDetails?.tank?.tankDetails?.tankStatement?.productListUnNo![1]).toEqual("987987"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.type).toEqual("Artic tractor"); expect(techRecordDocument.techRecord![0].adrDetails?.vehicleDetails?.approvalDate).toEqual("2023-06-12"); From 99cb11b7c433b92761da072c3928a4c3df764001 Mon Sep 17 00:00:00 2001 From: Meys Torkaman Date: Thu, 15 Feb 2024 16:17:37 +0000 Subject: [PATCH 44/44] fix: updating parse adr details function for missing optional attributes --- src/models/adr-details.ts | 193 ++++++++++++++++++++++---------------- 1 file changed, 111 insertions(+), 82 deletions(-) diff --git a/src/models/adr-details.ts b/src/models/adr-details.ts index c8515ba..250716f 100644 --- a/src/models/adr-details.ts +++ b/src/models/adr-details.ts @@ -168,106 +168,135 @@ export const parseAdrDetails = ( const additionalNotesImage: DynamoDbImage = adrDetails.getMap( "additionalNotes" )!; - const additionalNotes: AdditionalNotes = { - number: parseStringArray( + const additionalNotes: AdditionalNotes = {}; + if (additionalNotesImage) { + additionalNotes.number = parseStringArray( additionalNotesImage.getList("number")! - ) as additionalNotesNumberEnum[], + ) as additionalNotesNumberEnum[]; // guidanceNotes: parseStringArray( // additionalNotesImage.getList("guidanceNotes") // ) as additionalNotesguidanceNotesEnum[], - }; + } const applicantDetailsImage: DynamoDbImage = adrDetails.getMap( "applicantDetails" )!; - const applicantDetails: ApplicantDetails = { - name: applicantDetailsImage.getString("name")!, - street: applicantDetailsImage.getString("street")!, - town: applicantDetailsImage.getString("town")!, - city: applicantDetailsImage.getString("city")!, - postcode: applicantDetailsImage.getString("postcode")!, - }; + + const applicantDetails: ApplicantDetails = {}; + if (applicantDetailsImage) { + applicantDetails.name = applicantDetailsImage.getString("name")!; + applicantDetails.street = applicantDetailsImage.getString("street")!; + applicantDetails.town = applicantDetailsImage.getString("town")!; + applicantDetails.city = applicantDetailsImage.getString("city")!; + applicantDetails.postcode = applicantDetailsImage.getString("postcode")!; + } const vehicleDetailsImage: DynamoDbImage = adrDetails.getMap( "vehicleDetails" )!; - const vehicleDetails: VehicleDetails = { - type: vehicleDetailsImage.getString("type")! as VehicleDetailsTypeEnum, - approvalDate: vehicleDetailsImage.getString("approvalDate")!, - }; + const vehicleDetails: VehicleDetails = {}; + + if (vehicleDetailsImage) { + vehicleDetails.type = vehicleDetailsImage.getString( + "type" + )! as VehicleDetailsTypeEnum; + vehicleDetails.approvalDate = vehicleDetailsImage.getString( + "approvalDate" + )!; + } const tankImage: DynamoDbImage = adrDetails.getMap("tank")!; + const tank: Tank = {}; - const tankDetailsImage = tankImage.getMap("tankDetails")!; - - const tc2DetailsImage: DynamoDbImage = tankDetailsImage.getMap("tc2Details")!; - const tc2Details: Tc2Details = { - tc2Type: tc2DetailsImage.getString("tc2Type")! as Tc2TypeEnum, - tc2IntermediateApprovalNo: tc2DetailsImage.getString( - "tc2IntermediateApprovalNo" - )!, - tc2IntermediateExpiryDate: tc2DetailsImage.getString( - "tc2IntermediateExpiryDate" - )!, - }; - - const tc3DetailsImage: DynamoDbImage = tankDetailsImage.getList( - "tc3Details" - )!; - const tc3Details: Tc3Details = []; - - if (tc3DetailsImage) { - for (const key of tc3DetailsImage.getKeys()!) { - const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; - tc3Details.push({ - tc3Type: tc3DetailsItemImage.getString("tc3Type")! as Tc3TypeEnum, - tc3PeriodicNumber: tc3DetailsItemImage.getString("tc3PeriodicNumber")!, - tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( - "tc3PeriodicExpiryDate" - )!, - }); - } - } + if (tankImage) { + const tankDetailsImage = tankImage.getMap("tankDetails")!; + const tankDetails: TankDetails = {}; - const tankStatementImage: DynamoDbImage = tankDetailsImage.getMap( - "tankStatement" - )!; - const tankStatement: TankStatement = {}; - - if (tankStatementImage) { - tankStatement.substancesPermitted = tankStatementImage.getString( - "substancesPermitted" - )! as substancesPermittedEnum; - tankStatement.select = tankStatementImage.getString( - "select" - )! as tankStatementSelectEnum; - tankStatement.statement = tankStatementImage.getString("statement")!; - tankStatement.productListRefNo = tankStatementImage.getString( - "productListRefNo" - )!; - tankStatement.productListUnNo = parseStringArray( - tankStatementImage.getList("productListUnNo")! - ); - tankStatement.productList = tankStatementImage.getString("productList")!; - } + if (tankDetailsImage) { + const tc2Details: Tc2Details = {}; + const tc2DetailsImage: DynamoDbImage = tankDetailsImage.getMap( + "tc2Details" + )!; - const tankDetails: TankDetails = { - tankManufacturer: tankDetailsImage.getString("tankManufacturer")!, - yearOfManufacture: tankDetailsImage.getNumber("yearOfManufacture")!, - tankCode: tankDetailsImage.getString("tankCode")!, - specialProvisions: tankDetailsImage.getString("specialProvisions")!, - tankManufacturerSerialNo: tankDetailsImage.getString( - "tankManufacturerSerialNo" - )!, - tankTypeAppNo: tankDetailsImage.getString("tankTypeAppNo")!, - tc2Details, - tc3Details, - tankStatement, - }; + if (tc2DetailsImage) { + tc2Details.tc2Type = tc2DetailsImage.getString( + "tc2Type" + )! as Tc2TypeEnum; + tc2Details.tc2IntermediateApprovalNo = tc2DetailsImage.getString( + "tc2IntermediateApprovalNo" + )!; + tc2Details.tc2IntermediateExpiryDate = tc2DetailsImage.getString( + "tc2IntermediateExpiryDate" + )!; + + tankDetails.tc2Details = tc2Details; + } + + const tc3DetailsImage: DynamoDbImage = tankDetailsImage.getList( + "tc3Details" + )!; + const tc3Details: Tc3Details = []; + + if (tc3DetailsImage) { + for (const key of tc3DetailsImage.getKeys()!) { + const tc3DetailsItemImage = tc3DetailsImage.getMap(key)!; + tc3Details.push({ + tc3Type: tc3DetailsItemImage.getString("tc3Type")! as Tc3TypeEnum, + tc3PeriodicNumber: tc3DetailsItemImage.getString( + "tc3PeriodicNumber" + )!, + tc3PeriodicExpiryDate: tc3DetailsItemImage.getString( + "tc3PeriodicExpiryDate" + )!, + }); + } + tankDetails.tc3Details = tc3Details; + } + + const tankStatementImage: DynamoDbImage = tankDetailsImage.getMap( + "tankStatement" + )!; + const tankStatement: TankStatement = {}; + + if (tankStatementImage) { + tankStatement.substancesPermitted = tankStatementImage.getString( + "substancesPermitted" + )! as substancesPermittedEnum; + tankStatement.select = tankStatementImage.getString( + "select" + )! as tankStatementSelectEnum; + tankStatement.statement = tankStatementImage.getString("statement")!; + tankStatement.productListRefNo = tankStatementImage.getString( + "productListRefNo" + )!; + tankStatement.productListUnNo = parseStringArray( + tankStatementImage.getList("productListUnNo")! + ); + tankStatement.productList = tankStatementImage.getString( + "productList" + )!; + + tankDetails.tankStatement = tankStatement; + } + + tankDetails.tankManufacturer = tankDetailsImage.getString( + "tankManufacturer" + )!; + tankDetails.yearOfManufacture = tankDetailsImage.getNumber( + "yearOfManufacture" + )!; + tankDetails.tankCode = tankDetailsImage.getString("tankCode")!; + tankDetails.specialProvisions = tankDetailsImage.getString( + "specialProvisions" + )!; + tankDetails.tankManufacturerSerialNo = tankDetailsImage.getString( + "tankManufacturerSerialNo" + )!; + tankDetails.tankTypeAppNo = tankDetailsImage.getString("tankTypeAppNo")!; - const tank: Tank = { - tankDetails, - }; + tank.tankDetails = tankDetails; + } + } const additionalExaminerNotesImage: DynamoDbImage = adrDetails.getList( "additionalExaminerNotes"