/// Heuristik: Freitext wie „2h Elektro Küche“ → Zeile für die Positionsbeschreibung. /// /// Kein externes KI-Modell – nur Muster, die auf der Baustelle häufig vorkommen. class PositionFromTextParser { PositionFromTextParser._(); /// Liefert einen Vorschlag für eine neue Zeile (mehrzeilig anfügbar). static String? vorschlagZeile(String raw) { final s = raw.trim(); if (s.isEmpty) return null; final stunden = RegExp( r'^(\d+(?:[.,]\d+)?)\s*h(?:\s+|$)', caseSensitive: false, ).firstMatch(s); if (stunden != null) { final h = stunden.group(1)!.replaceAll(',', '.'); final rest = s.substring(stunden.end).trim(); final leistung = rest.isEmpty ? 'Arbeitsleistung' : rest; return '${h}h – $leistung'; } final euro = RegExp( r'^(\d+(?:[.,]\d+)?)\s*€', caseSensitive: false, ).firstMatch(s); if (euro != null) { final betrag = euro.group(1)!.replaceAll('.', '').replaceAll(',', '.'); final rest = s.substring(euro.end).trim(); final leistung = rest.isEmpty ? 'Material / Leistung' : rest; return '$leistung – $betrag€ (netto/brutto lt. Vereinbarung)'; } final mal = RegExp( r'^(\d+)\s*x\s*', caseSensitive: false, ).firstMatch(s); if (mal != null) { final n = mal.group(1)!; final rest = s.substring(mal.end).trim(); if (rest.isNotEmpty) return '$n× $rest'; } return '• $s'; } }