'use strict' ; import { JSEDISegment } from './JSEDINotation' ; import { Range } from './Positioning' ; import { X12Element } from './X12Element' ; import { defaultSerializationOptions , X12SerializationOptions } from './X12SerializationOptions' ; import { ISASegmentHeader } from './X12SegmentHeader' ; import { GeneratorError } from './Errors' ; export class X12Segment { description param { string } tag param { X12SerializationOptions } options constructor ( tag = '' , options ? ) { this . tag = tag ; this . elements = new Array < X12Element > ( ) ; this . range = new Range ( ) ; this . options = defaultSerializationOptions ( options ) ; } tag : string ; elements : X12Element [ ] ; range : Range ; options : X12SerializationOptions ; description param { string } tag setTag ( tag ) { this . tag = tag ; } description param { string [ ] } values returns { X12Segment } setElements ( values ) { this . _formatValues ( values ) ; this . elements = new Array < X12Element > ( ) ; values . forEach ( value => { this . elements . push ( new X12Element ( value ) ) ; } ) ; return this ; } description param { string } value returns { X12Element } addElement ( value = '' ) { const element = new X12Element ( value ) ; this . elements . push ( element ) ; return element ; } description param { string } value param { number } segmentPosition returns { X12Element } replaceElement ( value , segmentPosition ) { const index = segmentPosition - 1 ; if ( this . elements . length <= index ) { return null ; } else { this . elements [ index ] = new X12Element ( value ) ; } return this . elements [ index ] ; } description param { string } value param { number } segmentPosition returns { X12Element } insertElement ( value = '' , segmentPosition = 1 ) { const index = segmentPosition - 1 ; if ( this . elements . length <= index ) { return null ; } return this . elements . splice ( index , 0 , new X12Element ( value ) ) . length === 1 ; } description param { number } segmentPosition returns { boolean } removeElement ( segmentPosition ) { const index = segmentPosition - 1 ; if ( this . elements . length <= index ) { return false ; } return this . elements . splice ( index , 1 ) . length === 1 ; } description param { number } segmentPosition param { string } defaultValue returns { string } valueOf ( segmentPosition , defaultValue ? ) { const index = segmentPosition - 1 ; if ( this . elements . length <= index ) { return defaultValue === undefined ? null : defaultValue ; } return this . elements [ index ] . value === undefined ? defaultValue === undefined ? null : defaultValue : this . elements [ index ] . value ; } description param { X12SerializationOptions } options returns { string } toString ( options ? ) { options = options !== undefined ? defaultSerializationOptions ( options ) : this . options ; let edi = this . tag ; for ( let i = 0 ; i < this . elements . length ; i ++ ) { edi += options . elementDelimiter ; if ( ( this . tag === 'ISA' && i === 12 ) || ( this . tag === 'IEA' && i === 1 ) ) { edi += String . prototype . padStart . call ( this . elements [ i ] . value , 9 , '0' ) as string ; } else { edi += this . elements [ i ] . value ; } } edi += options . segmentTerminator ; return edi ; } description returns { object } toJSON ( ) { return new JSEDISegment ( this . tag , this . elements . map ( x => x . value ) ) as object ; } private description returns { boolean } private _checkSupportedSegment ( ) { return ( this . options . segmentHeaders . findIndex ( sh => { return sh . tag === this . tag ; } ) > - 1 ) ; } private description returns { object } private _getX12Enumerable ( ) { const match = this . options . segmentHeaders . find ( sh => { return sh . tag === this . tag ; } ) ; if ( match !== undefined ) { return match . layout ; } else { throw Error ( `Unable to find segment header for tag '${ this . tag }' even though it should be supported.` ) ; } } private description param { string [ ] } values private _formatValues ( values ) { if ( this . _checkSupportedSegment ( ) ) { const enumerable = this . _getX12Enumerable ( ) ; if ( this . tag === ISASegmentHeader . tag && this . options . subElementDelimiter . length === 1 ) { values [ 15 ] = this . options . subElementDelimiter ; } if ( values . length === enumerable . COUNT ) { for ( let i = 0 ; i < values . length ; i ++ ) { const name = `${ this . tag }${ String . prototype . padStart . call ( i + 1 , 2 , '0' ) }` ; const max = enumerable [ name ] ; const min = enumerable [ `${ name }_MIN` ] === undefined ? 0 : enumerable [ `${ name }_MIN` ] ; values [ i ] = `${ values [ i ] }` ; if ( values [ i ] . length > max && values [ i ] . length !== 0 ) { throw new GeneratorError ( `Segment element "${ name }" with value of "${ values [ i ] }" exceeds maximum of ${ max } characters.` ) ; } if ( values [ i ] . length < min && values [ i ] . length !== 0 ) { throw new GeneratorError ( `Segment element "${ name }" with value of "${ values [ i ] }" does not meet minimum of ${ min } characters.` ) ; } if ( ( enumerable . PADDING as boolean ) && ( ( values [ i ] . length < max && values [ i ] . length > min ) || values [ i ] . length === 0 ) ) { if ( name === 'ISA13' ) { values [ i ] = String . prototype . padStart . call ( values [ i ] , max , '0' ) ; } else { values [ i ] = String . prototype . padEnd . call ( values [ i ] , max , ' ' ) ; } } } } else { throw new GeneratorError ( `Segment "${ this . tag }" with ${ values . length } elements does meet the required count of ${ enumerable . COUNT }.` ) ; } } } }