47 lines
1.3 KiB
Dart
47 lines
1.3 KiB
Dart
import '../models/auftrag.dart';
|
|
import 'german_amount_parser.dart';
|
|
|
|
/// EPC / GiroCode-kompatibler QR-Payload (SEPA Credit Transfer, Version 002).
|
|
///
|
|
/// Siehe [EPC069-12](https://www.europeanpaymentscouncil.eu/document-library/).
|
|
class SepaQrData {
|
|
SepaQrData._();
|
|
|
|
static String? buildEpcString(Auftrag auftrag) {
|
|
final iban = _normalizeIban(auftrag.ibanVerkaeufer);
|
|
if (iban.isEmpty) return null;
|
|
final name = auftrag.kontoinhaberVerkaeufer.trim().isEmpty
|
|
? 'Empfänger'
|
|
: _truncate(auftrag.kontoinhaberVerkaeufer.trim(), 70);
|
|
final bic = auftrag.bicVerkaeufer.trim().replaceAll(' ', '');
|
|
final amount = GermanAmountParser.formatForSepaQr(auftrag.betragText);
|
|
if (amount == null) return null;
|
|
final nr = auftrag.rechnungsnummer.trim();
|
|
final purpose = _truncate(nr.isEmpty ? auftrag.titel : 'Rechnung $nr', 140);
|
|
|
|
final lines = <String>[
|
|
'BCD',
|
|
'002',
|
|
'1',
|
|
'SCT',
|
|
bic.isEmpty ? '' : _truncate(bic, 11),
|
|
name,
|
|
iban,
|
|
amount,
|
|
'',
|
|
'',
|
|
purpose,
|
|
];
|
|
return lines.join('\n');
|
|
}
|
|
|
|
static String _normalizeIban(String raw) {
|
|
return raw.replaceAll(' ', '').toUpperCase();
|
|
}
|
|
|
|
static String _truncate(String s, int max) {
|
|
if (s.length <= max) return s;
|
|
return s.substring(0, max);
|
|
}
|
|
}
|