import type { TInvoice } from '../../interfaces/common.js'; import { ValidationLevel } from '../../interfaces/common.js'; import type { ValidationResult } from '../../interfaces/common.js'; /** * Base decoder class that defines common decoding functionality * for all invoice format decoders */ export abstract class BaseDecoder { protected xml: string; constructor(xml: string) { this.xml = xml; } /** * Decodes XML into a TInvoice object * @returns Promise resolving to a TInvoice object */ abstract decode(): Promise; /** * Gets letter data in the standard format * @returns Promise resolving to a TInvoice object */ public async getLetterData(): Promise { return this.decode(); } /** * Gets the raw XML content * @returns XML string */ public getXml(): string { return this.xml; } /** * Parses a CII date string based on format code * @param dateStr Date string * @param format Format code (e.g., '102' for YYYYMMDD) * @returns Timestamp in milliseconds */ protected parseCIIDate(dateStr: string, format?: string): number { if (!dateStr) return Date.now(); // Format 102 is YYYYMMDD if (format === '102' && dateStr.length === 8) { const year = parseInt(dateStr.substring(0, 4)); const month = parseInt(dateStr.substring(4, 6)) - 1; // Month is 0-indexed in JS const day = parseInt(dateStr.substring(6, 8)); return new Date(year, month, day).getTime(); } // Format 610 is YYYYMM if (format === '610' && dateStr.length === 6) { const year = parseInt(dateStr.substring(0, 4)); const month = parseInt(dateStr.substring(4, 6)) - 1; return new Date(year, month, 1).getTime(); } // Try to parse as ISO date or other standard formats const parsed = Date.parse(dateStr); return isNaN(parsed) ? Date.now() : parsed; } }