UNPKG

@cityssm/mpac-yetf

Version:

Parses the MPAC Year-End Tax File (YETF) into a usable object.

197 lines (178 loc) 6.23 kB
import events from 'node:events' import fs from 'node:fs' import readline from 'node:readline' import * as rollNumberLookups from './lookups/rollNumberLookups.js' import { formatBB } from './formatters/bbFormatter.js' import { formatCC } from './formatters/ccFormatter.js' import { formatDD } from './formatters/ddFormatter.js' import { formatGG } from './formatters/ggFormatter.js' import { formatKK } from './formatters/kkFormatter.js' import { formatPA } from './formatters/paFormatter.js' import { formatPB } from './formatters/pbFormatter.js' import { formatPC } from './formatters/pcFormatter.js' import { formatPD } from './formatters/pdFormatter.js' import { formatPI } from './formatters/piFormatter.js' import { parseRollNumber, parseYetfRecordString } from './parsers.js' import type * as types from './types' interface ParseYetfOptions { addFormattedFields?: boolean callbacks: { all?: ( record: types.RawYetfRecord | types.FormattedYetfRecord, lineNumber?: number ) => void AA?: ( record: types.RawYetfRecordAA | types.FormattedYetfRecordAA, lineNumber?: number ) => void BB?: ( record: types.RawYetfRecordBB | types.FormattedYetfRecordBB, lineNumber?: number ) => void CC?: ( record: types.RawYetfRecordCC | types.FormattedYetfRecordCC, lineNumber?: number ) => void DD?: ( record: types.RawYetfRecordDD | types.FormattedYetfRecordDD, lineNumber?: number ) => void GG?: ( record: types.RawYetfRecordGG | types.FormattedYetfRecordGG, lineNumber?: number ) => void HH?: ( record: types.RawYetfRecordHH | types.FormattedYetfRecordHH, lineNumber?: number ) => void JJ?: ( record: types.RawYetfRecordJJ | types.FormattedYetfRecordJJ, lineNumber?: number ) => void KK?: ( record: types.RawYetfRecordKK | types.FormattedYetfRecordKK, lineNumber?: number ) => void LL?: ( record: types.RawYetfRecordLL | types.FormattedYetfRecordLL, lineNumber?: number ) => void MM?: ( record: types.RawYetfRecordMM | types.FormattedYetfRecordMM, lineNumber?: number ) => void PA?: ( record: types.RawYetfRecordPA | types.FormattedYetfRecordPA, lineNumber?: number ) => void PB?: ( record: types.RawYetfRecordPB | types.FormattedYetfRecordPB, lineNumber?: number ) => void PC?: ( record: types.RawYetfRecordPC | types.FormattedYetfRecordPC, lineNumber?: number ) => void PD?: ( record: types.RawYetfRecordPD | types.FormattedYetfRecordPD, lineNumber?: number ) => void PI?: ( record: types.RawYetfRecordPI | types.FormattedYetfRecordPI, lineNumber?: number ) => void } } export async function parseYetf( filePath: string, options: ParseYetfOptions ): Promise<boolean> { const rl = readline.createInterface({ input: fs.createReadStream(filePath) }) let lineNumber = 0 rl.on('line', (recordString) => { lineNumber += 1 let record = parseYetfRecordString(recordString) if (options.addFormattedFields ?? false) { const parsedRollNumber = parseRollNumber(record.rollNumber) // Roll Number Pieces ;(record as types.FormattedYetfRecord).rollNumberCounty = parsedRollNumber.county ;(record as types.FormattedYetfRecord).rollNumberMunicipality = parsedRollNumber.municipality ;(record as types.FormattedYetfRecord).rollNumberMapArea = parsedRollNumber.mapArea ;(record as types.FormattedYetfRecord).rollNumberMapDivision = parsedRollNumber.mapDivision ;(record as types.FormattedYetfRecord).rollNumberMapSubdivision = parsedRollNumber.mapSubdivision ;(record as types.FormattedYetfRecord).rollNumberParcel = parsedRollNumber.parcel ;(record as types.FormattedYetfRecord).rollNumberParcelSub = parsedRollNumber.parcelSub ;(record as types.FormattedYetfRecord).rollNumberPrimarySubordinate = parsedRollNumber.primarySubordinate // Related Roll Number Data ;(record as types.FormattedYetfRecord).rollNumberMunicipalityName = rollNumberLookups.rollNumberMunicipalities[ parsedRollNumber.county + parsedRollNumber.municipality ] ;(record as types.FormattedYetfRecord).rollNumberIsPrimary = parsedRollNumber.primarySubordinate === '0000' switch (record.recordType) { case 'BB': { record = formatBB(record as types.RawYetfRecordBB) break } case 'CC': { record = formatCC(record as types.RawYetfRecordCC) break } case 'DD': { record = formatDD(record as types.RawYetfRecordDD) break } case 'GG': { record = formatGG(record as types.RawYetfRecordGG) break } case 'KK': { record = formatKK(record as types.RawYetfRecordKK) break } case 'PA': { record = formatPA(record as types.RawYetfRecordPA) break } case 'PC': { record = formatPC(record as types.RawYetfRecordPC) break } case 'PB': { record = formatPB(record as types.RawYetfRecordPB) break } case 'PD': { record = formatPD(record as types.RawYetfRecordPD) break } case 'PI': { record = formatPI(record as types.RawYetfRecordPI) break } } } // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (options.callbacks.all) { options.callbacks.all(record, lineNumber) } // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (options.callbacks[record.recordType]) { options.callbacks[record.recordType]!(record, lineNumber) } }) await events.once(rl, 'close') return true } export default parseYetf