BREAKING CHANGE(core): Refactor contact and PDF handling across the library by replacing IContact with TContact and updating PDF processing to use a structured IPdf object. These changes ensure that empty contact objects include registration details, founded/closed dates, and status, and that PDF loading/exporting uniformly wraps buffers in a proper object.

This commit is contained in:
2025-03-20 13:57:45 +00:00
parent 75b720a98d
commit 6906e2f778
8 changed files with 164 additions and 31 deletions

View File

@ -27,31 +27,63 @@ export abstract class BaseDecoder {
*/
protected createDefaultLetter(): plugins.tsclass.business.ILetter {
// Create a default seller
const seller: plugins.tsclass.business.IContact = {
const seller: plugins.tsclass.business.TContact = {
name: 'Unknown Seller',
type: 'company',
description: 'Unknown Seller', // Required by IContact interface
description: 'Unknown Seller',
address: {
streetName: 'Unknown',
houseNumber: '0', // Required by IAddress interface
houseNumber: '0',
city: 'Unknown',
country: 'Unknown',
postalCode: 'Unknown',
},
registrationDetails: {
vatId: 'Unknown',
registrationId: 'Unknown',
registrationName: 'Unknown'
},
foundedDate: {
year: 2000,
month: 1,
day: 1
},
closedDate: {
year: 9999,
month: 12,
day: 31
},
status: 'active'
};
// Create a default buyer
const buyer: plugins.tsclass.business.IContact = {
const buyer: plugins.tsclass.business.TContact = {
name: 'Unknown Buyer',
type: 'company',
description: 'Unknown Buyer', // Required by IContact interface
description: 'Unknown Buyer',
address: {
streetName: 'Unknown',
houseNumber: '0', // Required by IAddress interface
houseNumber: '0',
city: 'Unknown',
country: 'Unknown',
postalCode: 'Unknown',
},
registrationDetails: {
vatId: 'Unknown',
registrationId: 'Unknown',
registrationName: 'Unknown'
},
foundedDate: {
year: 2000,
month: 1,
day: 1
},
closedDate: {
year: 9999,
month: 12,
day: 31
},
status: 'active'
};
// Create default invoice data

View File

@ -97,21 +97,37 @@ export class FacturXDecoder extends BaseDecoder {
}
// Create seller
const seller: plugins.tsclass.business.IContact = {
const seller: plugins.tsclass.business.TContact = {
name: sellerName,
type: 'company',
description: sellerName,
address: {
streetName: this.getElementText('ram:LineOne') || 'Unknown',
houseNumber: '0', // Required by IAddress interface
houseNumber: '0',
city: this.getElementText('ram:CityName') || 'Unknown',
country: this.getElementText('ram:CountryID') || 'Unknown',
postalCode: this.getElementText('ram:PostcodeCode') || 'Unknown',
},
registrationDetails: {
vatId: this.getElementText('ram:ID') || 'Unknown',
registrationId: this.getElementText('ram:ID') || 'Unknown',
registrationName: sellerName
},
foundedDate: {
year: 2000,
month: 1,
day: 1
},
closedDate: {
year: 9999,
month: 12,
day: 31
},
status: 'active'
};
// Create buyer
const buyer: plugins.tsclass.business.IContact = {
const buyer: plugins.tsclass.business.TContact = {
name: buyerName,
type: 'company',
description: buyerName,
@ -122,6 +138,22 @@ export class FacturXDecoder extends BaseDecoder {
country: 'Unknown',
postalCode: 'Unknown',
},
registrationDetails: {
vatId: 'Unknown',
registrationId: 'Unknown',
registrationName: buyerName
},
foundedDate: {
year: 2000,
month: 1,
day: 1
},
closedDate: {
year: 9999,
month: 12,
day: 31
},
status: 'active'
};
// Extract invoice type

View File

@ -32,8 +32,8 @@ export class FacturXEncoder {
}
const invoice: plugins.tsclass.finance.IInvoice = letterArg.content.invoiceData;
const billedBy: plugins.tsclass.business.IContact = invoice.billedBy;
const billedTo: plugins.tsclass.business.IContact = invoice.billedTo;
const billedBy: plugins.tsclass.business.TContact = invoice.billedBy;
const billedTo: plugins.tsclass.business.TContact = invoice.billedTo;
// 2) Start building the document
const doc = smartxmlInstance

View File

@ -118,21 +118,37 @@ export class XInvoiceDecoder extends BaseDecoder {
'Unknown Buyer';
// Create seller contact
const seller: plugins.tsclass.business.IContact = {
const seller: plugins.tsclass.business.TContact = {
name: sellerName,
type: 'company',
description: sellerName,
address: {
streetName: sellerStreet,
houseNumber: '0', // Required by IAddress interface
houseNumber: '0',
city: sellerCity,
country: sellerCountry,
postalCode: sellerPostcode,
},
registrationDetails: {
vatId: this.getElementText('cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID') || 'Unknown',
registrationId: this.getElementText('cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cbc:CompanyID') || 'Unknown',
registrationName: sellerName
},
foundedDate: {
year: 2000,
month: 1,
day: 1
},
closedDate: {
year: 9999,
month: 12,
day: 31
},
status: 'active'
};
// Create buyer contact
const buyer: plugins.tsclass.business.IContact = {
const buyer: plugins.tsclass.business.TContact = {
name: buyerName,
type: 'company',
description: buyerName,
@ -143,6 +159,22 @@ export class XInvoiceDecoder extends BaseDecoder {
country: 'Unknown',
postalCode: 'Unknown',
},
registrationDetails: {
vatId: this.getElementText('cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID') || 'Unknown',
registrationId: this.getElementText('cac:AccountingCustomerParty/cac:Party/cac:PartyLegalEntity/cbc:CompanyID') || 'Unknown',
registrationName: buyerName
},
foundedDate: {
year: 2000,
month: 1,
day: 1
},
closedDate: {
year: 9999,
month: 12,
day: 31
},
status: 'active'
};
// Extract invoice type

View File

@ -23,8 +23,8 @@ export class XInvoiceEncoder {
}
const invoice: plugins.tsclass.finance.IInvoice = letterArg.content.invoiceData;
const billedBy: plugins.tsclass.business.IContact = invoice.billedBy;
const billedTo: plugins.tsclass.business.IContact = invoice.billedTo;
const billedBy: plugins.tsclass.business.TContact = invoice.billedBy;
const billedTo: plugins.tsclass.business.TContact = invoice.billedTo;
// Create the XML document
const doc = smartxmlInstance
@ -76,9 +76,9 @@ export class XInvoiceEncoder {
const supplierPartyDetails = supplierParty.ele('cac:Party');
// Seller VAT ID
if (billedBy.vatId) {
if (billedBy.type === 'company' && billedBy.registrationDetails?.vatId) {
const partyTaxScheme = supplierPartyDetails.ele('cac:PartyTaxScheme');
partyTaxScheme.ele('cbc:CompanyID').txt(billedBy.vatId).up();
partyTaxScheme.ele('cbc:CompanyID').txt(billedBy.registrationDetails.vatId).up();
partyTaxScheme.ele('cac:TaxScheme')
.ele('cbc:ID').txt('VAT').up()
.up();
@ -117,9 +117,9 @@ export class XInvoiceEncoder {
const customerPartyDetails = customerParty.ele('cac:Party');
// Buyer VAT ID
if (billedTo.vatId) {
if (billedTo.type === 'company' && billedTo.registrationDetails?.vatId) {
const partyTaxScheme = customerPartyDetails.ele('cac:PartyTaxScheme');
partyTaxScheme.ele('cbc:CompanyID').txt(billedTo.vatId).up();
partyTaxScheme.ele('cbc:CompanyID').txt(billedTo.registrationDetails.vatId).up();
partyTaxScheme.ele('cac:TaxScheme')
.ele('cbc:ID').txt('VAT').up()
.up();