Task-Typnummern neu zugeordnet und benutzerdefinierte Typen via effectiveType unterstuetzt
- TourTask: base_type-Feld und effectiveType-Getter ergaenzt; benutzerdefinierte Typen (>= 1000) aus dem Workflow-Editor werden auf ihren Basis-Typ abgebildet, bei Altdaten ohne base_type wird der Basis-Typ aus den Eigenschaften abgeleitet - TaskListPage: alle Typ-Switches auf effectiveType und die neuen Typnummern umgestellt (u.a. Ankunft 1->3, Fotos 3->4, Bestaetigung 6->12, Listen 12-14->13-15) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa44311776
commit
ac4266079a
2 files changed
+88
-54
No files matched your search
@@ -313,19 +313,19 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
|
||||
Widget _buildEditableBody(TaskInfo taskInfo) {
|
||||
final draft = _draftFor(taskInfo);
|
||||
final type = taskInfo.task?.type ?? 0;
|
||||
// Benutzerdefinierte Typen aus dem Workflow-Editor (>= 1000) verhalten
|
||||
// sich wie ihr Basis-Typ, siehe TourTask.effectiveType.
|
||||
final type = taskInfo.task?.effectiveType ?? 0;
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
return _buildConfirmButtonBody(draft, 'confirm_arrival'.tr);
|
||||
case 2:
|
||||
return _buildSignatureBody(taskInfo, draft);
|
||||
case 3:
|
||||
return _buildConfirmButtonBody(draft, 'confirm_arrival'.tr);
|
||||
case 4:
|
||||
return _buildPhotosBody(taskInfo, draft);
|
||||
case 5:
|
||||
return Text('barcode_disabled'.tr, style: const TextStyle(color: Colors.grey));
|
||||
case 6:
|
||||
return _buildConfirmBody(draft, taskInfo.task?.topic ?? 'confirm'.tr);
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
@@ -333,17 +333,19 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
case 11:
|
||||
return _buildStatusBody(taskInfo, draft);
|
||||
case 12:
|
||||
return _buildFieldsBody(taskInfo, draft, numeric: false);
|
||||
return _buildConfirmBody(draft, taskInfo.task?.topic ?? 'confirm'.tr);
|
||||
case 13:
|
||||
return _buildFieldsBody(taskInfo, draft, numeric: true);
|
||||
return _buildFieldsBody(taskInfo, draft, numeric: false);
|
||||
case 14:
|
||||
return _buildFieldsBody(taskInfo, draft, numeric: true);
|
||||
case 15:
|
||||
return _buildCheckboxListBody(taskInfo, draft);
|
||||
default:
|
||||
return Text('task_type_unsupported'.tr, style: const TextStyle(color: Colors.grey));
|
||||
}
|
||||
}
|
||||
|
||||
/// Bestätigung per Button (Ankunft melden = 1). Antippen bestätigt bzw.
|
||||
/// Bestätigung per Button (Ankunft melden = 3). Antippen bestätigt bzw.
|
||||
/// nimmt die Bestätigung wieder zurück; der Zustand wird über ein
|
||||
/// Häkchen-Symbol im Button angezeigt.
|
||||
Widget _buildConfirmButtonBody(_TaskDraft draft, String label) {
|
||||
@@ -375,7 +377,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
);
|
||||
}
|
||||
|
||||
/// Bestätigungs-Aufgabe als Checkbox (Typ 6).
|
||||
/// Bestätigungs-Aufgabe als Checkbox (Typ 12).
|
||||
Widget _buildConfirmBody(_TaskDraft draft, String label) {
|
||||
return CheckboxListTile(
|
||||
value: draft.confirmed,
|
||||
@@ -440,7 +442,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
);
|
||||
}
|
||||
|
||||
/// Text-/Zahlen-Liste (Typ 12/13): je Feld ein beschriftetes Eingabefeld.
|
||||
/// Text-/Zahlen-Liste (Typ 13/14): je Feld ein beschriftetes Eingabefeld.
|
||||
Widget _buildFieldsBody(TaskInfo taskInfo, _TaskDraft draft, {required bool numeric}) {
|
||||
final fields = taskInfo.task?.fields ?? [];
|
||||
if (fields.isEmpty) {
|
||||
@@ -480,7 +482,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
);
|
||||
}
|
||||
|
||||
/// Checkbox-Liste (Typ 14): Mehrfachauswahl aus den entries.
|
||||
/// Checkbox-Liste (Typ 15): Mehrfachauswahl aus den entries.
|
||||
Widget _buildCheckboxListBody(TaskInfo taskInfo, _TaskDraft draft) {
|
||||
final entries = taskInfo.task?.entries ?? [];
|
||||
if (entries.isEmpty) {
|
||||
@@ -554,7 +556,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
);
|
||||
}
|
||||
|
||||
/// Fotos aufnehmen (Typ 3) – Inline-Aufnahme und Vorschau.
|
||||
/// Fotos aufnehmen (Typ 4) – Inline-Aufnahme und Vorschau.
|
||||
Widget _buildPhotosBody(TaskInfo taskInfo, _TaskDraft draft) {
|
||||
final max = taskInfo.task?.max ?? 999;
|
||||
final min = taskInfo.task?.min ?? 0;
|
||||
@@ -641,14 +643,14 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
final task = taskInfo.task;
|
||||
if (task == null) return true;
|
||||
if (task.opt ?? false) return true;
|
||||
switch (task.type) {
|
||||
case 12:
|
||||
switch (task.effectiveType) {
|
||||
case 13:
|
||||
case 14:
|
||||
final fields = task.fields ?? [];
|
||||
if (fields.isEmpty) return true;
|
||||
if (fields.every((f) => f.required == null)) return false;
|
||||
return fields.every((f) => f.required != true);
|
||||
case 14:
|
||||
case 15:
|
||||
final entries = task.entries ?? [];
|
||||
if (entries.isEmpty) return true;
|
||||
if (entries.every((e) => e.required == null)) return false;
|
||||
@@ -660,15 +662,15 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
|
||||
bool _isValid(TaskInfo taskInfo) {
|
||||
final draft = _draftFor(taskInfo);
|
||||
final type = taskInfo.task?.type ?? 0;
|
||||
final type = taskInfo.task?.effectiveType ?? 0;
|
||||
switch (type) {
|
||||
case 1:
|
||||
case 6:
|
||||
return draft.confirmed;
|
||||
case 2:
|
||||
final sig = draft.signatureController;
|
||||
return sig != null && sig.points.length > 50;
|
||||
case 3:
|
||||
case 12:
|
||||
return draft.confirmed;
|
||||
case 4:
|
||||
final min = (taskInfo.task?.min ?? 0);
|
||||
final max = (taskInfo.task?.max ?? 999);
|
||||
final required = min > 0 ? min : 1;
|
||||
@@ -687,13 +689,13 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
return (draft.remark?.text.trim().isNotEmpty ?? false);
|
||||
}
|
||||
return true;
|
||||
case 12:
|
||||
_ensureFieldControllers(draft, taskInfo.task?.fields?.length ?? 0);
|
||||
return _fieldsValid(taskInfo, draft, numeric: false);
|
||||
case 13:
|
||||
_ensureFieldControllers(draft, taskInfo.task?.fields?.length ?? 0);
|
||||
return _fieldsValid(taskInfo, draft, numeric: true);
|
||||
return _fieldsValid(taskInfo, draft, numeric: false);
|
||||
case 14:
|
||||
_ensureFieldControllers(draft, taskInfo.task?.fields?.length ?? 0);
|
||||
return _fieldsValid(taskInfo, draft, numeric: true);
|
||||
case 15:
|
||||
final entries = taskInfo.task?.entries ?? [];
|
||||
// Ohne definierte Einträge gibt es keine Pflichtfelder -> freigeben.
|
||||
if (entries.isEmpty) return true;
|
||||
@@ -709,7 +711,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
}
|
||||
}
|
||||
|
||||
/// Prüft die Eingabefelder einer Text-/Zahlen-Liste (Typ 12/13) gegen ihre
|
||||
/// Prüft die Eingabefelder einer Text-/Zahlen-Liste (Typ 13/14) gegen ihre
|
||||
/// Pflicht-Kennzeichen. Altdaten ohne Kennzeichen behalten das bisherige
|
||||
/// Verhalten (alle Felder müssen gefüllt bzw. numerisch sein). Sonst müssen
|
||||
/// nur Pflichtfelder gefüllt (bei Zahlenlisten numerisch) sein; optionale
|
||||
@@ -736,15 +738,15 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
/// entscheidet, ob eine Antwort geschrieben oder die Aufgabe übersprungen wird).
|
||||
bool _hasData(TaskInfo taskInfo) {
|
||||
final draft = _draftFor(taskInfo);
|
||||
final type = taskInfo.task?.type ?? 0;
|
||||
final type = taskInfo.task?.effectiveType ?? 0;
|
||||
switch (type) {
|
||||
case 1:
|
||||
case 6:
|
||||
return draft.confirmed;
|
||||
case 2:
|
||||
final sig = draft.signatureController;
|
||||
return sig != null && sig.points.length > 50;
|
||||
case 3:
|
||||
case 12:
|
||||
return draft.confirmed;
|
||||
case 4:
|
||||
return draft.photos.isNotEmpty;
|
||||
case 7:
|
||||
case 8:
|
||||
@@ -752,10 +754,10 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
return (draft.text?.text.trim().isNotEmpty ?? false);
|
||||
case 11:
|
||||
return draft.selectedCode != null;
|
||||
case 12:
|
||||
case 13:
|
||||
return draft.fields.any((c) => c.text.trim().isNotEmpty);
|
||||
case 14:
|
||||
return draft.fields.any((c) => c.text.trim().isNotEmpty);
|
||||
case 15:
|
||||
return draft.checked.isNotEmpty;
|
||||
default:
|
||||
return false;
|
||||
@@ -800,7 +802,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
|
||||
Future<void> _commitCurrent(TaskInfo taskInfo) async {
|
||||
final draft = _draftFor(taskInfo);
|
||||
final type = taskInfo.task?.type ?? 0;
|
||||
final type = taskInfo.task?.effectiveType ?? 0;
|
||||
|
||||
// Optionale Aufgabe ohne Eingabe: als erledigt markieren, keine Antwort.
|
||||
if (!_hasData(taskInfo)) {
|
||||
@@ -812,15 +814,6 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 1: // Ankunft melden
|
||||
final answer = await _createAnswerHeader(taskInfo);
|
||||
taskInfo.answer = jsonEncode(answer.toJson());
|
||||
taskInfo.additionalText = DateFormat("dd.MM.yyyy HH:mm").format(DateTime.now());
|
||||
taskInfo.completed = true;
|
||||
_persist(taskInfo);
|
||||
_sendArrivedMessage(taskInfo);
|
||||
break;
|
||||
|
||||
case 2: // Unterschrift
|
||||
final answer = await _createAnswerHeader(taskInfo);
|
||||
answer.sign = _convertSignaturePoints(draft.signatureController!.points);
|
||||
@@ -830,7 +823,16 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
_persist(taskInfo);
|
||||
break;
|
||||
|
||||
case 3: // Fotos
|
||||
case 3: // Ankunft melden
|
||||
final answer = await _createAnswerHeader(taskInfo);
|
||||
taskInfo.answer = jsonEncode(answer.toJson());
|
||||
taskInfo.additionalText = DateFormat("dd.MM.yyyy HH:mm").format(DateTime.now());
|
||||
taskInfo.completed = true;
|
||||
_persist(taskInfo);
|
||||
_sendArrivedMessage(taskInfo);
|
||||
break;
|
||||
|
||||
case 4: // Fotos
|
||||
_storePhotos(draft.photos);
|
||||
taskInfo.answer = null; // Bilder werden separat als pic-Nachrichten gesendet.
|
||||
taskInfo.additionalText = 'photos_taken'.tr;
|
||||
@@ -838,7 +840,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
_persist(taskInfo);
|
||||
break;
|
||||
|
||||
case 6: // Checkbox / Bestätigung
|
||||
case 12: // Checkbox / Bestätigung
|
||||
final answer = await _createAnswerHeader(taskInfo);
|
||||
answer.val = "1";
|
||||
taskInfo.answer = jsonEncode(answer.toJson());
|
||||
@@ -871,8 +873,8 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
_persist(taskInfo);
|
||||
break;
|
||||
|
||||
case 12: // Text-Liste
|
||||
case 13: // Zahlen-Liste
|
||||
case 13: // Text-Liste
|
||||
case 14: // Zahlen-Liste
|
||||
final answer = await _createAnswerHeader(taskInfo);
|
||||
final fields = taskInfo.task?.fields ?? [];
|
||||
final answers = <FinFieldAnswer>[];
|
||||
@@ -891,7 +893,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
_persist(taskInfo);
|
||||
break;
|
||||
|
||||
case 14: // Checkbox-Liste
|
||||
case 15: // Checkbox-Liste
|
||||
final answer = await _createAnswerHeader(taskInfo);
|
||||
final checked = draft.checked.toList()..sort();
|
||||
answer.checked = checked;
|
||||
@@ -943,9 +945,9 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
/// erneut bearbeitbaren Aufgaben aus der gespeicherten Antwort vor.
|
||||
_TaskDraft _buildDraft(TaskInfo taskInfo) {
|
||||
final draft = _TaskDraft();
|
||||
final type = taskInfo.task?.type ?? 0;
|
||||
final type = taskInfo.task?.effectiveType ?? 0;
|
||||
|
||||
if (type == 12 || type == 13) {
|
||||
if (type == 13 || type == 14) {
|
||||
_ensureFieldControllers(draft, taskInfo.task?.fields?.length ?? 0);
|
||||
}
|
||||
|
||||
@@ -957,8 +959,8 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
try {
|
||||
final answer = FinTourTask.fromJson(jsonDecode(taskInfo.answer!) as Map<String, dynamic>);
|
||||
switch (type) {
|
||||
case 1:
|
||||
case 6:
|
||||
case 3:
|
||||
case 12:
|
||||
draft.confirmed = true;
|
||||
break;
|
||||
case 7:
|
||||
@@ -970,14 +972,14 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
draft.selectedCode = answer.code;
|
||||
draft.remark = _listenedController(answer.val ?? '');
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
final values = answer.fields ?? [];
|
||||
for (int i = 0; i < draft.fields.length && i < values.length; i++) {
|
||||
draft.fields[i].text = values[i].val ?? '';
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
case 15:
|
||||
draft.checked = (answer.checked ?? []).toSet();
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user