97 lines
2.7 KiB
Dart
97 lines
2.7 KiB
Dart
import 'dart:convert';
|
||
import 'dart:io';
|
||
|
||
import 'package:path_provider/path_provider.dart';
|
||
|
||
import '../models/auftrag.dart';
|
||
import '../models/auftrag_status.dart';
|
||
import '../models/dokument_typ.dart';
|
||
import '../models/zahlungs_status.dart';
|
||
|
||
/// Export der Auftragsdaten als JSON (ohne Binärdaten der Fotos/Unterschrift).
|
||
class DataExportService {
|
||
DataExportService._();
|
||
|
||
static String _csvZelle(String? s) {
|
||
final t = (s ?? '').replaceAll('"', '""');
|
||
if (t.contains(';') || t.contains('\n') || t.contains('"')) {
|
||
return '"$t"';
|
||
}
|
||
return t;
|
||
}
|
||
|
||
/// Semikolon-CSV (Excel DE) – grobe Vorlage für Steuerbüro / DATEV-Vorbereitung.
|
||
static Future<File> exportAuftraegeCsvToTempFile(List<Auftrag> list) async {
|
||
final header = [
|
||
'Rechnungsnummer',
|
||
'Dokumenttyp',
|
||
'Titel',
|
||
'Kunde',
|
||
'Adresse',
|
||
'E-Mail',
|
||
'Betrag_Text',
|
||
'Status',
|
||
'Zahlungsstatus',
|
||
'Faellig_am',
|
||
'Leistungsdatum',
|
||
'Kleinunternehmer',
|
||
'Reverse_Charge',
|
||
'Skonto',
|
||
'USt_Id_Kunde',
|
||
'IBAN',
|
||
'BIC',
|
||
'Kontoinhaber',
|
||
'Erstellt',
|
||
];
|
||
final sb = StringBuffer()
|
||
..writeln(header.map(_csvZelle).join(';'));
|
||
for (final a in list) {
|
||
sb.writeln(
|
||
[
|
||
a.rechnungsnummer,
|
||
a.dokumentTyp.labelDe,
|
||
a.titel,
|
||
a.kundenName,
|
||
a.kundenAdresse,
|
||
a.kundenEmail,
|
||
a.betragText,
|
||
a.status.labelDe,
|
||
a.zahlungsStatus.labelDe,
|
||
a.faelligAm?.toIso8601String() ?? '',
|
||
a.leistungsDatum?.toIso8601String() ?? '',
|
||
a.kleinunternehmer ? 'ja' : 'nein',
|
||
a.reverseCharge ? 'ja' : 'nein',
|
||
a.skontoText,
|
||
a.ustIdKunde,
|
||
a.ibanVerkaeufer,
|
||
a.bicVerkaeufer,
|
||
a.kontoinhaberVerkaeufer,
|
||
a.createdAt?.toIso8601String() ?? '',
|
||
].map(_csvZelle).join(';'),
|
||
);
|
||
}
|
||
final dir = await getTemporaryDirectory();
|
||
final name =
|
||
'handwerkpro_export_${DateTime.now().millisecondsSinceEpoch}.csv';
|
||
final file = File('${dir.path}/$name');
|
||
await file.writeAsString(sb.toString(), encoding: utf8);
|
||
return file;
|
||
}
|
||
|
||
static Future<File> exportAuftraegeToTempFile(List<Auftrag> list) async {
|
||
final payload = {
|
||
'exportVersion': 4,
|
||
'exportedAt': DateTime.now().toIso8601String(),
|
||
'count': list.length,
|
||
'auftraege': list.map((a) => a.toExportMap()).toList(),
|
||
};
|
||
final json = const JsonEncoder.withIndent(' ').convert(payload);
|
||
final dir = await getTemporaryDirectory();
|
||
final name =
|
||
'handwerkpro_export_${DateTime.now().millisecondsSinceEpoch}.json';
|
||
final file = File('${dir.path}/$name');
|
||
await file.writeAsString(json);
|
||
return file;
|
||
}
|
||
}
|