feat(core): improve in-memory validation, FatturaPA detection coverage, and published type compatibility

This commit is contained in:
2026-04-16 20:30:56 +00:00
parent 55bee02a2e
commit 3f37f6538c
60 changed files with 5723 additions and 6678 deletions
+50 -16
View File
@@ -169,17 +169,45 @@ export class SemanticModelAdapter {
}
// Set payment options
if (model.paymentInstructions.paymentAccountIdentifier) {
if (
model.paymentInstructions.paymentAccountIdentifier ||
model.paymentInstructions.paymentMeansText ||
model.paymentInstructions.paymentServiceProviderIdentifier
) {
invoice.paymentOptions = {
sepa: {
iban: model.paymentInstructions.paymentAccountIdentifier,
bic: model.paymentInstructions.paymentServiceProviderIdentifier
description: model.paymentInstructions.paymentMeansText,
sepaConnection: {
iban: model.paymentInstructions.paymentAccountIdentifier || '',
bic: model.paymentInstructions.paymentServiceProviderIdentifier || '',
institution: model.paymentInstructions.paymentServiceProviderIdentifier
},
bankInfo: {
accountHolder: model.paymentInstructions.paymentAccountName || '',
institutionName: model.paymentInstructions.paymentServiceProviderIdentifier || ''
payPal: { email: '' }
};
invoice.metadata = {
...invoice.metadata,
paymentMeansCode: model.paymentInstructions.paymentMeansTypeCode,
paymentAccount: {
iban: model.paymentInstructions.paymentAccountIdentifier,
accountName: model.paymentInstructions.paymentAccountName,
bankId: model.paymentInstructions.paymentServiceProviderIdentifier
},
extensions: {
...invoice.metadata?.extensions,
paymentMeans: {
paymentMeansCode: model.paymentInstructions.paymentMeansTypeCode,
paymentMeansText: model.paymentInstructions.paymentMeansText,
remittanceInformation: model.paymentInstructions.remittanceInformation
},
paymentAccount: {
iban: model.paymentInstructions.paymentAccountIdentifier,
accountName: model.paymentInstructions.paymentAccountName,
bankId: model.paymentInstructions.paymentServiceProviderIdentifier,
bic: model.paymentInstructions.paymentServiceProviderIdentifier,
institutionName: model.paymentInstructions.paymentServiceProviderIdentifier
}
}
} as any;
};
}
// Set extensions
@@ -376,15 +404,21 @@ export class SemanticModelAdapter {
*/
private mapPaymentInstructions(invoice: EInvoice): PaymentInstructions {
const paymentMeans = invoice.metadata?.extensions?.paymentMeans;
const paymentAccount = invoice.metadata?.extensions?.paymentAccount;
const paymentAccount = invoice.metadata?.extensions?.paymentAccount || invoice.metadata?.paymentAccount;
const sepaConnection = invoice.paymentOptions?.sepaConnection;
return {
paymentMeansTypeCode: paymentMeans?.paymentMeansCode || '30', // Default to credit transfer
paymentMeansText: paymentMeans?.paymentMeansText,
paymentMeansTypeCode: paymentMeans?.paymentMeansCode || invoice.metadata?.paymentMeansCode || '30',
paymentMeansText: paymentMeans?.paymentMeansText || invoice.paymentOptions?.description,
remittanceInformation: paymentMeans?.remittanceInformation,
paymentAccountIdentifier: paymentAccount?.iban,
paymentAccountIdentifier: paymentAccount?.iban || sepaConnection?.iban,
paymentAccountName: paymentAccount?.accountName,
paymentServiceProviderIdentifier: paymentAccount?.bic || paymentAccount?.institutionName
paymentServiceProviderIdentifier:
paymentAccount?.bic ||
paymentAccount?.institutionName ||
paymentAccount?.bankId ||
sepaConnection?.bic ||
sepaConnection?.institution
};
}
@@ -397,10 +431,10 @@ export class SemanticModelAdapter {
taxExclusiveAmount: invoice.totalNet,
taxInclusiveAmount: invoice.totalGross,
allowanceTotalAmount: invoice.metadata?.extensions?.documentAllowances?.reduce(
(sum, a) => sum + a.amount, 0
(sum: number, a: { amount: number }) => sum + a.amount, 0
),
chargeTotalAmount: invoice.metadata?.extensions?.documentCharges?.reduce(
(sum, c) => sum + c.amount, 0
(sum: number, c: { amount: number }) => sum + c.amount, 0
),
prepaidAmount: invoice.metadata?.extensions?.prepaidAmount,
roundingAmount: invoice.metadata?.extensions?.roundingAmount,
@@ -597,4 +631,4 @@ export class SemanticModelAdapter {
return errors;
}
}
}