From 85ef77b8d53c8f3e6fa6eecf86ede8e3c2dd1f24 Mon Sep 17 00:00:00 2001 From: Shane Froebel Date: Fri, 8 Dec 2023 17:57:53 -0500 Subject: [PATCH] feat: message added to batch - message added to batch - batch footer (BTS) shows the correct number - updated date util to be set at 14, 12, or 8, default at 14 #4 --- __tests__/hl7.build.test.ts | 40 +++++++++++++++++++++++++++++++++---- src/builder/batch.ts | 30 +++++++++++++++++----------- src/builder/message.ts | 10 +++++----- src/utils/index.ts | 22 +++++++++++++++----- 4 files changed, 76 insertions(+), 26 deletions(-) diff --git a/__tests__/hl7.build.test.ts b/__tests__/hl7.build.test.ts index 23a1e65..7ac6d45 100644 --- a/__tests__/hl7.build.test.ts +++ b/__tests__/hl7.build.test.ts @@ -1,5 +1,5 @@ import {randomUUID} from "crypto"; -// import * as Util from '../src/utils/' +import * as Util from '../src/utils/' import {Batch, Message} from "../src"; describe('node hl7 client - builder tests', () => { @@ -263,14 +263,14 @@ describe('node hl7 client - builder tests', () => { test('... initial build', async() => { batch.end() expect(batch.toString()).toContain("BHS|^~\\&") - expect(batch.toString()).toContain("BTS|") + expect(batch.toString()).toContain("BTS|0") }) test('... verify BHS header is correct', async() => { batch.set('BHS.7', '20081231') batch.end() expect(batch.get('BHS.7').toString()).toBe("20081231") - expect(batch.toString()).toBe("BHS|^~\\&|||||20081231\rBTS|1|End of Batch") + expect(batch.toString()).toBe("BHS|^~\\&|||||20081231\rBTS|0") }) test('... add onto the BHS header', async() => { @@ -285,7 +285,7 @@ describe('node hl7 client - builder tests', () => { expect(batch.get("BHS.4").toString()).toBe( "SendingFacility"); expect(batch.get("BHS.5").toString()).toBe( "ReceivingApp"); expect(batch.get("BHS.6").toString()).toBe( "ReceivingFacility"); - expect(batch.toString()).toBe("BHS|^~\\&|SendingApp|SendingFacility|ReceivingApp|ReceivingFacility|20081231\rBTS|1|End of Batch") + expect(batch.toString()).toBe("BHS|^~\\&|SendingApp|SendingFacility|ReceivingApp|ReceivingFacility|20081231\rBTS|0") }) test.todo('...override BSH.7 (Date/Time/Field)') @@ -294,4 +294,36 @@ describe('node hl7 client - builder tests', () => { }) + describe('complex builder batch tests', () => { + + let batch: Batch + let message: Message + const date = Util.createHL7Date(new Date(), "8") + + beforeEach(async () => { + batch = new Batch() + batch.start() + batch.set('BHS.7', date) + }) + + test('... add single message to batch', async () => { + + message = new Message({ + messageHeader: { + msh_9: { + msh_9_1: "ADT", + msh_9_2: "A01" + }, + msh_10: 'CONTROL_ID' + } + }) + message.set('MSH.7', date) + + batch.add(message) + batch.end() + expect(batch.toString()).toBe([`BHS|^~\\&|||||${date}`, `MSH|^~\\&|||||${date}||ADT^A01^ADT_A01|CONTROL_ID||2.7`, "BTS|1"].join("\r")) + }) + + }) + }) \ No newline at end of file diff --git a/src/builder/batch.ts b/src/builder/batch.ts index 9dfea98..4ac2e86 100644 --- a/src/builder/batch.ts +++ b/src/builder/batch.ts @@ -1,11 +1,11 @@ import * as Util from '../utils' import { HL7FatalError } from '../utils/exception' -/* import { HL7FatalError } from '../utils/exception' */ import { ClientBuilderBatchOptions, normalizedClientBatchBuilderOptions } from '../utils/normalize' import { Node } from './interface/node' +import { Message } from './message' import { RootBase } from './modules/rootBase' import { Segment } from './modules/segment' import { SegmentList } from './modules/segmentList' @@ -18,6 +18,7 @@ import { SegmentList } from './modules/segmentList' export class Batch extends RootBase { /** @internal **/ _opt: ReturnType + _messagesCount: number /** * @since 1.0.0 @@ -27,10 +28,18 @@ export class Batch extends RootBase { const opt = normalizedClientBatchBuilderOptions(props) super(opt) this._opt = opt + this._messagesCount = 0 } - addMessage (): void { - throw new Error('Not Implemented') + /** + * Add a Message to the Batch + * @since 1.0.0 + * @param message + */ + add (message: Message): void { + this.setDirty() + this._messagesCount = this._messagesCount + 1 + this.children.push(message) } /** @@ -39,8 +48,7 @@ export class Batch extends RootBase { */ end (): void { const segment = this._addSegment('BTS') - segment.set('1', 1) // this will be the number of message segments - segment.set('2', 'End of Batch') // maybe from options? + segment.set('1', this._messagesCount) } /** @@ -52,21 +60,20 @@ export class Batch extends RootBase { read (path: string[]): Node { const segmentName = path.shift() as string if (path.length === 0) { - // only the segment name was in the path so return a SegmentList const segments = this.children.filter(x => (x as Segment).name === segmentName) as Segment[] if (segments.length > 0) { return new SegmentList(this, segments) as Node } } else { if (typeof segmentName === 'undefined') { - throw new Error('We have an error Huston.') + throw new HL7FatalError(500, 'segment name is not defined.') } const segment = this._getFirstSegment(segmentName) if (typeof segment !== 'undefined') { return segment.read(path) } } - throw new Error('Failure is not an option.') + throw new HL7FatalError(500, 'Unable to process the read function correctly.') } /** @@ -74,8 +81,7 @@ export class Batch extends RootBase { * @since 1.0.0 */ start (): void { - this.set('BSH.7', Util.createDate(new Date())) - // this.set('BSH.10', 'Start of Batch') // maybe from options? + this.set('BSH.7', Util.createHL7Date(new Date())) } /** @@ -88,7 +94,7 @@ export class Batch extends RootBase { protected writeCore (path: string[], value: string): Node { const segmentName = path.shift() as string if (typeof segmentName === 'undefined') { - throw new Error('Danger, Will Robinson') + throw new HL7FatalError(500, 'segment name is not defined.') } return this.writeAtIndex(path, value, 0, segmentName) } @@ -128,6 +134,6 @@ export class Batch extends RootBase { return segment } } - throw new Error('We have a problem.') + throw new HL7FatalError(500, 'Unable to process _getFirstSegment.') } } diff --git a/src/builder/message.ts b/src/builder/message.ts index 4f20ab9..68c836f 100644 --- a/src/builder/message.ts +++ b/src/builder/message.ts @@ -41,7 +41,7 @@ export class Message extends RootBase { if (typeof this._opt.messageHeader !== 'undefined') { if (this._opt.specification.checkMSH(this._opt.messageHeader) === true) { - this.set('MSH.7', Util.createDate(new Date())) + this.set('MSH.7', Util.createHL7Date(new Date())) this.set('MSH.9.1', this._opt.messageHeader.msh_9.msh_9_1.toString()) this.set('MSH.9.2', this._opt.messageHeader.msh_9.msh_9_2.toString()) this.set('MSH.9.3', `${this._opt.messageHeader.msh_9.msh_9_1.toString()}_${this._opt.messageHeader.msh_9.msh_9_2.toString()}`) @@ -101,14 +101,14 @@ export class Message extends RootBase { } } else { if (typeof segmentName === 'undefined') { - throw new Error('We have an error Huston.') + throw new HL7FatalError(500, 'segment name is not defined.') } const segment = this._getFirstSegment(segmentName) if (typeof segment !== 'undefined') { return segment.read(path) } } - throw new Error('Failure is not an option.') + throw new HL7FatalError(500, 'Unable to process the read function correctly.') } /** @@ -121,7 +121,7 @@ export class Message extends RootBase { protected writeCore (path: string[], value: string): Node { const segmentName = path.shift() as string if (typeof segmentName === 'undefined') { - throw new Error('Danger, Will Robinson') + throw new HL7FatalError(500, 'segment name is not defined.') } let index = this._getFirstSegmentIndex(segmentName) if (index === undefined) { @@ -160,7 +160,7 @@ export class Message extends RootBase { return segment } } - throw new Error('We have a problem.') + throw new HL7FatalError(500, 'Unable to process _getFirstSegment.') } /** @internal */ diff --git a/src/utils/index.ts b/src/utils/index.ts index a5458ee..99c04b4 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -46,15 +46,27 @@ export const validIPv6 = (ip: string): boolean => { } /** - * Create Date + * Create HL7 Valid Date * @since 1.0.0 * @param date + * @param length (@default 14) * @example - * const date = Util.createDate(new Date()) - * // date = 2023120305123434 or YYYYMMDDHHMMSS + * const date = Util.createDate(new Date(), "14") (default) + * // date = 20231203051234 or YYYYMMDDHHMMSS + * const date = Util.createDate(new Date(), "12") + * // date = 202312030512 or YYYYMMDDHHMM + * const date = Util.createDate(new Date(), "8") + * // date = 20231203 or YYYYMMDD */ -export const createDate = (date: Date): string => { - return `${date.getFullYear()}${pad(date.getMonth() + 1, 2)}${pad(date.getDate(), 2)}${pad(date.getHours(), 2)}${pad(date.getMinutes(), 2)}${pad(date.getSeconds(), 2)}` +export const createHL7Date = (date: Date, length: '8' | '12' | '14' = '14'): string => { + switch (length) { + case '14': + return `${date.getFullYear()}${pad(date.getMonth() + 1, 2)}${pad(date.getDate(), 2)}${pad(date.getHours(), 2)}${pad(date.getMinutes(), 2)}${pad(date.getSeconds(), 2)}` + case '12': + return `${date.getFullYear()}${pad(date.getMonth() + 1, 2)}${pad(date.getDate(), 2)}${pad(date.getHours(), 2)}${pad(date.getMinutes(), 2)}` + case '8': + return `${date.getFullYear()}${pad(date.getMonth() + 1, 2)}${pad(date.getDate(), 2)}` + } } /**