64 lines
2.0 KiB
TypeScript
64 lines
2.0 KiB
TypeScript
import { BaseEncoder } from '../base/base.encoder.js';
|
|
import type { TInvoice, TCreditNote, TDebitNote } from '../../interfaces/common.js';
|
|
import { UBLDocumentType, UBL_NAMESPACES } from './ubl.types.js';
|
|
|
|
/**
|
|
* Base encoder for UBL-based invoice formats
|
|
*/
|
|
export abstract class UBLBaseEncoder extends BaseEncoder {
|
|
/**
|
|
* Encodes a TInvoice object into UBL XML
|
|
* @param invoice TInvoice object to encode
|
|
* @returns UBL XML string
|
|
*/
|
|
public async encode(invoice: TInvoice): Promise<string> {
|
|
// TInvoice is always an invoice, treat it as debit note for encoding
|
|
return this.encodeDebitNote(invoice as unknown as TDebitNote);
|
|
}
|
|
|
|
/**
|
|
* Encodes a TCreditNote object into UBL XML
|
|
* @param creditNote TCreditNote object to encode
|
|
* @returns UBL XML string
|
|
*/
|
|
protected abstract encodeCreditNote(creditNote: TCreditNote): Promise<string>;
|
|
|
|
/**
|
|
* Encodes a TDebitNote object into UBL XML
|
|
* @param debitNote TDebitNote object to encode
|
|
* @returns UBL XML string
|
|
*/
|
|
protected abstract encodeDebitNote(debitNote: TDebitNote): Promise<string>;
|
|
|
|
/**
|
|
* Creates the XML declaration and root element
|
|
* @param documentType UBL document type
|
|
* @returns XML string with declaration and root element
|
|
*/
|
|
protected createXmlRoot(documentType: UBLDocumentType): string {
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<${documentType} xmlns="urn:oasis:names:specification:ubl:schema:xsd:${documentType}-2"
|
|
xmlns:cac="${UBL_NAMESPACES.CAC}"
|
|
xmlns:cbc="${UBL_NAMESPACES.CBC}">
|
|
</${documentType}>`;
|
|
}
|
|
|
|
/**
|
|
* Formats a date as an ISO string (YYYY-MM-DD)
|
|
* @param timestamp Timestamp to format
|
|
* @returns Formatted date string
|
|
*/
|
|
protected formatDate(timestamp: number): string {
|
|
// Ensure timestamp is valid
|
|
if (!timestamp || isNaN(timestamp)) {
|
|
timestamp = Date.now();
|
|
}
|
|
const date = new Date(timestamp);
|
|
// Check if date is valid
|
|
if (isNaN(date.getTime())) {
|
|
return new Date().toISOString().split('T')[0];
|
|
}
|
|
return date.toISOString().split('T')[0];
|
|
}
|
|
}
|