@@ -62,7 +62,7 @@ function rejectUnknownKeys(
6262function positiveQuickBooksAmount (
6363 value : unknown ,
6464 fieldName : string
65- ) : { decimal : Decimal ; number : number } {
65+ ) : { cents : bigint ; number : number } {
6666 if ( typeof value !== 'number' && typeof value !== 'string' ) {
6767 throw new Error ( `${ fieldName } must be a positive finite number` )
6868 }
@@ -82,11 +82,16 @@ function positiveQuickBooksAmount(
8282 throw new Error ( `${ fieldName } cannot have more than two decimal places` )
8383 }
8484
85+ const centsNumber = decimal . times ( 100 ) . toNumber ( )
86+ if ( ! Number . isSafeInteger ( centsNumber ) ) {
87+ throw new Error ( `${ fieldName } is outside the safely supported amount range` )
88+ }
89+
8590 const number = decimal . toNumber ( )
8691 if ( ! Number . isFinite ( number ) || ! new Decimal ( number ) . equals ( decimal ) ) {
8792 throw new Error ( `${ fieldName } is outside the safely supported amount range` )
8893 }
89- return { decimal , number }
94+ return { cents : BigInt ( centsNumber ) , number }
9095}
9196
9297function stringValue ( value : unknown , fieldName : string ) : string {
@@ -119,7 +124,7 @@ export function parseQuickBooksJournalLines(
119124 if ( ! parsed ) return undefined
120125 validateLineCount ( parsed , fieldName , 2 )
121126
122- const decimalAmounts : Decimal [ ] = [ ]
127+ const centAmounts : bigint [ ] = [ ]
123128 const lines = parsed . map ( ( rawLine , index ) => {
124129 const itemName = `${ fieldName } [${ index } ]`
125130 const line = requireObject ( rawLine , itemName )
@@ -141,7 +146,7 @@ export function parseQuickBooksJournalLines(
141146 throw new Error ( `${ itemName } .entityType and entityId must be supplied together` )
142147 }
143148 const amount = positiveQuickBooksAmount ( line . amount , `${ itemName } .amount` )
144- decimalAmounts . push ( amount . decimal )
149+ centAmounts . push ( amount . cents )
145150 return {
146151 postingType,
147152 amount : amount . number ,
@@ -156,14 +161,14 @@ export function parseQuickBooksJournalLines(
156161 } )
157162
158163 const debitTotal = lines . reduce (
159- ( sum , line , index ) => ( line . postingType === 'debit' ? sum . plus ( decimalAmounts [ index ] ) : sum ) ,
160- new Decimal ( 0 )
164+ ( sum , line , index ) => ( line . postingType === 'debit' ? sum + centAmounts [ index ] : sum ) ,
165+ 0n
161166 )
162167 const creditTotal = lines . reduce (
163- ( sum , line , index ) => ( line . postingType === 'credit' ? sum . plus ( decimalAmounts [ index ] ) : sum ) ,
164- new Decimal ( 0 )
168+ ( sum , line , index ) => ( line . postingType === 'credit' ? sum + centAmounts [ index ] : sum ) ,
169+ 0n
165170 )
166- if ( ! debitTotal . equals ( creditTotal ) ) {
171+ if ( debitTotal !== creditTotal ) {
167172 throw new Error ( 'Journal entry debit and credit totals must balance' )
168173 }
169174 return lines
0 commit comments