import { Injectable } from '@nestjs/common';
@Injectable()
export class DatevCsvService {
render(rows:Array<any>,meta:{
consultantNumber?:string;
clientNumber?:string;
fiscalYearStart?:string;
accountLength?:number;
}={}) {
const quote=(value:unknown)=>{
let s=value==null?'':String(value);
if(/^[=+\-@]/.test(s)) s=`'${s}`;
return `"${s.replace(/"/g,'""')}"`;
};
const money=(minor:any)=>{
const n=BigInt(minor??0), sign=n<0n?'-':'', abs=n<0n?-n:n;
return `${sign}${abs/100n},${String(abs%100n).padStart(2,'0')}`;
};
const header=[
'EXTF','700','21','Buchungsstapel','13',
new Date().toISOString().slice(0,10).replace(/-/g,''),
'',meta.consultantNumber??'',meta.clientNumber??'',
meta.fiscalYearStart??'',String(meta.accountLength??4),
].map(quote).join(';');
const columns=[
'Umsatz (ohne Soll/Haben-Kz)','Soll/Haben-Kennzeichen','WKZ Umsatz','Kurs',
'Basis-Umsatz','WKZ Basis-Umsatz','Konto','Gegenkonto (ohne BU-Schlüssel)',
'BU-Schlüssel','Belegdatum','Belegfeld 1','Belegfeld 2','Skonto',
'Buchungstext'
].map(quote).join(';');
const lines=[header,columns];
for(const row of rows) {
const debit=String(row.debit_account??'');
const credit=String(row.credit_account??'');
const amount=BigInt(row.amount_minor??0);
const sollHaben=amount>=0n?'S':'H';
lines.push([
money(amount<0n?-amount:amount),sollHaben,row.currency_code??'EUR','',
'','',''+debit,''+credit,row.tax_key??'',
String(row.booking_date??'').replace(/-/g,'').slice(4),
row.reference??'','','',row.booking_text??''
].map(quote).join(';'));
}
return Buffer.from(lines.join('\r\n'),'utf8');
}
}
