@openade/fe
Version:
Fatturazione Elettronica - Electronic Invoicing for Sistema di Interscambio (SDI)
149 lines • 5.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InvoiceBuilder = void 0;
class InvoiceBuilder {
constructor(config) {
this.progressiveCounter = 0;
this.config = config;
}
build(data) {
this.progressiveCounter++;
const header = this.buildHeader(data);
const body = this.buildBody(data);
return {
'@_versione': 'FPR12',
fatturaElettronicaHeader: header,
fatturaElettronicaBody: body,
};
}
buildHeader(data) {
const transmissionCode = this.config.transmissionCode || this.config.supplierVatNumber;
const cedente = {
datiAnagrafici: {
idFiscaleIVA: {
idPaese: this.config.transmissionCountry || 'IT',
idCodice: this.config.supplierVatNumber,
},
anagrafica: {
denominazione: this.config.supplierBusinessName,
},
...(this.config.taxRegime && { regimeFiscale: this.config.taxRegime }),
},
sede: this.config.supplierAddress,
};
const cessionario = {
datiAnagrafici: {
...(data.customer.vatNumber && {
idFiscaleIVA: {
idPaese: data.customer.address.nazione,
idCodice: data.customer.vatNumber,
},
}),
...(data.customer.fiscalCode && { codiceFiscale: data.customer.fiscalCode }),
anagrafica: {
...(data.customer.businessName && { denominazione: data.customer.businessName }),
...(data.customer.firstName && { nome: data.customer.firstName }),
...(data.customer.lastName && { cognome: data.customer.lastName }),
},
},
sede: data.customer.address,
};
let codiceDestinatario = data.customer.sdiCode || '0000000';
if (data.customer.address.nazione !== 'IT') {
codiceDestinatario = 'XXXXXXX';
}
return {
datiTrasmissione: {
idTrasmittente: {
idPaese: this.config.transmissionCountry || 'IT',
idCodice: transmissionCode,
},
progressivoInvio: this.progressiveCounter.toString().padStart(5, '0'),
formatoTrasmissione: 'FPR12',
codiceDestinatario,
...(data.customer.pec &&
codiceDestinatario === '0000000' && {
pecDestinatario: data.customer.pec,
}),
},
cedentePrestatore: cedente,
cessionarioCommittente: cessionario,
};
}
buildBody(data) {
const lines = data.lines.map((line, index) => ({
numeroLinea: index + 1,
descrizione: line.description,
...(line.quantity !== undefined && { quantita: line.quantity }),
prezzoUnitario: line.unitPrice,
prezzoTotale: (line.quantity || 1) * line.unitPrice,
aliquotaIVA: line.vatRate,
...(line.vatNature && { natura: line.vatNature }),
}));
const vatSummary = this.calculateVatSummary(lines);
const totalAmount = vatSummary.reduce((sum, item) => sum + item.imponibileImporto + item.imposta, 0);
return {
datiGenerali: {
datiGeneraliDocumento: {
tipoDocumento: data.documentType || 'TD01',
divisa: 'EUR',
data: data.invoiceDate,
numero: data.invoiceNumber,
...(data.notes && { causale: data.notes }),
importoTotaleDocumento: totalAmount,
},
},
datiBeniServizi: {
dettaglioLinee: lines,
datiRiepilogo: vatSummary,
},
...(data.paymentMethod && {
datiPagamento: [
{
condizioniPagamento: 'TP01',
dettaglioPagamento: [
{
modalitaPagamento: data.paymentMethod,
importoPagamento: data.paymentAmount || totalAmount,
},
],
},
],
}),
};
}
calculateVatSummary(lines) {
const summary = new Map();
for (const line of lines) {
const key = `${line.aliquotaIVA}-${line.natura || ''}`;
if (!summary.has(key)) {
summary.set(key, {
aliquotaIVA: line.aliquotaIVA,
...(line.natura && { natura: line.natura }),
imponibileImporto: 0,
imposta: 0,
});
}
const item = summary.get(key);
item.imponibileImporto += line.prezzoTotale;
item.imposta += (line.prezzoTotale * line.aliquotaIVA) / 100;
item.imponibileImporto = Math.round(item.imponibileImporto * 100) / 100;
item.imposta = Math.round(item.imposta * 100) / 100;
}
return Array.from(summary.values());
}
generateFilename() {
const country = this.config.transmissionCountry || 'IT';
const code = this.config.transmissionCode || this.config.supplierVatNumber;
const progressive = this.progressiveCounter.toString().padStart(5, '0');
return `${country}${code}_${progressive}.xml`;
}
resetCounter() {
this.progressiveCounter = 0;
}
getCurrentProgressive() {
return this.progressiveCounter;
}
}
exports.InvoiceBuilder = InvoiceBuilder;
//# sourceMappingURL=invoice.builder.js.map