145 lines
6.4 KiB
TypeScript
145 lines
6.4 KiB
TypeScript
import { UBLBaseEncoder } from '../ubl.encoder.js';
|
|
import type { TInvoice, TCreditNote, TDebitNote } from '../../../interfaces/common.js';
|
|
import { UBLDocumentType } from '../ubl.types.js';
|
|
|
|
/**
|
|
* Encoder for XRechnung (UBL) format
|
|
* Implements encoding of TInvoice to XRechnung XML
|
|
*/
|
|
export class XRechnungEncoder extends UBLBaseEncoder {
|
|
/**
|
|
* Encodes a TCreditNote object to XRechnung XML
|
|
* @param creditNote TCreditNote object to encode
|
|
* @returns Promise resolving to XML string
|
|
*/
|
|
protected async encodeCreditNote(creditNote: TCreditNote): Promise<string> {
|
|
// For now, we'll just return a simple UBL credit note template
|
|
// In a real implementation, we would generate a proper UBL credit note
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<CreditNote xmlns="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
|
|
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
|
|
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
|
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0</cbc:CustomizationID>
|
|
<cbc:ID>${creditNote.id}</cbc:ID>
|
|
<cbc:IssueDate>${this.formatDate(creditNote.date)}</cbc:IssueDate>
|
|
<cbc:CreditNoteTypeCode>381</cbc:CreditNoteTypeCode>
|
|
<cbc:DocumentCurrencyCode>${creditNote.currency}</cbc:DocumentCurrencyCode>
|
|
|
|
<!-- Rest of the credit note XML would go here -->
|
|
</CreditNote>`;
|
|
}
|
|
|
|
/**
|
|
* Encodes a TDebitNote object to XRechnung XML
|
|
* @param debitNote TDebitNote object to encode
|
|
* @returns Promise resolving to XML string
|
|
*/
|
|
protected async encodeDebitNote(debitNote: TDebitNote): Promise<string> {
|
|
// For now, we'll just return a simple UBL invoice template
|
|
// In a real implementation, we would generate a proper UBL invoice
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
|
|
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
|
|
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
|
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0</cbc:CustomizationID>
|
|
<cbc:ID>${debitNote.id}</cbc:ID>
|
|
<cbc:IssueDate>${this.formatDate(debitNote.date)}</cbc:IssueDate>
|
|
<cbc:DueDate>${this.formatDate(debitNote.date + debitNote.dueInDays * 24 * 60 * 60 * 1000)}</cbc:DueDate>
|
|
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
|
|
<cbc:DocumentCurrencyCode>${debitNote.currency}</cbc:DocumentCurrencyCode>
|
|
|
|
<cac:AccountingSupplierParty>
|
|
<cac:Party>
|
|
<cac:PartyName>
|
|
<cbc:Name>${debitNote.from.name}</cbc:Name>
|
|
</cac:PartyName>
|
|
<cac:PostalAddress>
|
|
<cbc:StreetName>${debitNote.from.address.streetName || ''}</cbc:StreetName>
|
|
<cbc:BuildingNumber>${debitNote.from.address.houseNumber || ''}</cbc:BuildingNumber>
|
|
<cbc:CityName>${debitNote.from.address.city || ''}</cbc:CityName>
|
|
<cbc:PostalZone>${debitNote.from.address.postalCode || ''}</cbc:PostalZone>
|
|
<cac:Country>
|
|
<cbc:IdentificationCode>${debitNote.from.address.countryCode || ''}</cbc:IdentificationCode>
|
|
</cac:Country>
|
|
</cac:PostalAddress>
|
|
${debitNote.from.registrationDetails?.vatId ? `
|
|
<cac:PartyTaxScheme>
|
|
<cbc:CompanyID>${debitNote.from.registrationDetails.vatId}</cbc:CompanyID>
|
|
<cac:TaxScheme>
|
|
<cbc:ID>VAT</cbc:ID>
|
|
</cac:TaxScheme>
|
|
</cac:PartyTaxScheme>` : ''}
|
|
${debitNote.from.registrationDetails?.registrationId ? `
|
|
<cac:PartyLegalEntity>
|
|
<cbc:RegistrationName>${debitNote.from.registrationDetails.registrationName || debitNote.from.name}</cbc:RegistrationName>
|
|
<cbc:CompanyID>${debitNote.from.registrationDetails.registrationId}</cbc:CompanyID>
|
|
</cac:PartyLegalEntity>` : ''}
|
|
</cac:Party>
|
|
</cac:AccountingSupplierParty>
|
|
|
|
<cac:AccountingCustomerParty>
|
|
<cac:Party>
|
|
<cac:PartyName>
|
|
<cbc:Name>${debitNote.to.name}</cbc:Name>
|
|
</cac:PartyName>
|
|
<cac:PostalAddress>
|
|
<cbc:StreetName>${debitNote.to.address.streetName || ''}</cbc:StreetName>
|
|
<cbc:BuildingNumber>${debitNote.to.address.houseNumber || ''}</cbc:BuildingNumber>
|
|
<cbc:CityName>${debitNote.to.address.city || ''}</cbc:CityName>
|
|
<cbc:PostalZone>${debitNote.to.address.postalCode || ''}</cbc:PostalZone>
|
|
<cac:Country>
|
|
<cbc:IdentificationCode>${debitNote.to.address.countryCode || ''}</cbc:IdentificationCode>
|
|
</cac:Country>
|
|
</cac:PostalAddress>
|
|
${debitNote.to.registrationDetails?.vatId ? `
|
|
<cac:PartyTaxScheme>
|
|
<cbc:CompanyID>${debitNote.to.registrationDetails.vatId}</cbc:CompanyID>
|
|
<cac:TaxScheme>
|
|
<cbc:ID>VAT</cbc:ID>
|
|
</cac:TaxScheme>
|
|
</cac:PartyTaxScheme>` : ''}
|
|
</cac:Party>
|
|
</cac:AccountingCustomerParty>
|
|
|
|
<cac:PaymentTerms>
|
|
<cbc:Note>Due in ${debitNote.dueInDays} days</cbc:Note>
|
|
</cac:PaymentTerms>
|
|
|
|
<cac:TaxTotal>
|
|
<cbc:TaxAmount currencyID="${debitNote.currency}">0.00</cbc:TaxAmount>
|
|
</cac:TaxTotal>
|
|
|
|
<cac:LegalMonetaryTotal>
|
|
<cbc:LineExtensionAmount currencyID="${debitNote.currency}">0.00</cbc:LineExtensionAmount>
|
|
<cbc:TaxExclusiveAmount currencyID="${debitNote.currency}">0.00</cbc:TaxExclusiveAmount>
|
|
<cbc:TaxInclusiveAmount currencyID="${debitNote.currency}">0.00</cbc:TaxInclusiveAmount>
|
|
<cbc:PayableAmount currencyID="${debitNote.currency}">0.00</cbc:PayableAmount>
|
|
</cac:LegalMonetaryTotal>
|
|
|
|
${debitNote.items.map((item, index) => `
|
|
<cac:InvoiceLine>
|
|
<cbc:ID>${index + 1}</cbc:ID>
|
|
<cbc:InvoicedQuantity unitCode="${item.unitType}">${item.unitQuantity}</cbc:InvoicedQuantity>
|
|
<cbc:LineExtensionAmount currencyID="${debitNote.currency}">${item.unitNetPrice * item.unitQuantity}</cbc:LineExtensionAmount>
|
|
<cac:Item>
|
|
<cbc:Name>${item.name}</cbc:Name>
|
|
${item.articleNumber ? `
|
|
<cac:SellersItemIdentification>
|
|
<cbc:ID>${item.articleNumber}</cbc:ID>
|
|
</cac:SellersItemIdentification>` : ''}
|
|
<cac:ClassifiedTaxCategory>
|
|
<cbc:ID>S</cbc:ID>
|
|
<cbc:Percent>${item.vatPercentage}</cbc:Percent>
|
|
<cac:TaxScheme>
|
|
<cbc:ID>VAT</cbc:ID>
|
|
</cac:TaxScheme>
|
|
</cac:ClassifiedTaxCategory>
|
|
</cac:Item>
|
|
<cac:Price>
|
|
<cbc:PriceAmount currencyID="${debitNote.currency}">${item.unitNetPrice}</cbc:PriceAmount>
|
|
</cac:Price>
|
|
</cac:InvoiceLine>`).join('')}
|
|
</Invoice>`;
|
|
}
|
|
}
|