implemented absence report module with form validation, prefill support, and API integration
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import '../../marianumconnect/queries/absence/absence_prefill_response.dart';
|
||||
|
||||
/// Demo fixtures for the absence-report form: the class dropdown and the
|
||||
/// identity/phone prefill. Typed (compile-checked) so a field rename can't
|
||||
/// silently drift the demo shape away from what the queries parse.
|
||||
class DemoAbsence {
|
||||
const DemoAbsence._();
|
||||
|
||||
static List<String> classes() => const ['5a', '6b', '7c', '9d', '10a', 'Q1'];
|
||||
|
||||
static AbsencePrefillResponse prefill() => AbsencePrefillResponse(
|
||||
firstName: 'Max',
|
||||
lastName: 'Mustermann',
|
||||
className: '10a',
|
||||
phone: '0123 456789',
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'data/demo_absence.dart';
|
||||
import 'data/demo_breaker.dart';
|
||||
import 'data/demo_holidays.dart';
|
||||
import 'data/demo_timetable.dart';
|
||||
@@ -39,6 +40,10 @@ class DemoMarianumConnect {
|
||||
.toList();
|
||||
case 'breaker':
|
||||
return DemoBreaker.none().toJson();
|
||||
case 'absence/classes':
|
||||
return DemoAbsence.classes();
|
||||
case 'absence/prefill':
|
||||
return DemoAbsence.prefill().toJson();
|
||||
case 'timetable/elements/teachers':
|
||||
case 'timetable/elements/students':
|
||||
case 'timetable/elements/classes':
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import '../../marianumconnect_query.dart';
|
||||
|
||||
/// GETs the selectable classes for the absence form (`absence/classes`). The
|
||||
/// body is a bare JSON string array, so [getList] (which maps objects) does not
|
||||
/// fit — read the raw list and cast.
|
||||
class AbsenceClasses extends MarianumConnectQuery {
|
||||
AbsenceClasses({super.dio});
|
||||
|
||||
Future<List<String>> run() => guard(() async {
|
||||
final response = await dio.get<List<dynamic>>(endpoint('absence/classes'));
|
||||
return response.data!.cast<String>();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import '../../marianumconnect_query.dart';
|
||||
import 'absence_prefill_response.dart';
|
||||
|
||||
/// GETs the absence-report form prefill (`absence/prefill`, bearer-auth).
|
||||
class AbsencePrefill extends MarianumConnectQuery {
|
||||
AbsencePrefill({super.dio});
|
||||
|
||||
Future<AbsencePrefillResponse> run() =>
|
||||
getObject('absence/prefill', AbsencePrefillResponse.fromJson);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'absence_prefill_response.g.dart';
|
||||
|
||||
/// Prefill for the absence-report form: identity from LDAP plus the phone
|
||||
/// number from the user's last report (empty strings when unknown).
|
||||
@JsonSerializable()
|
||||
class AbsencePrefillResponse {
|
||||
@JsonKey(defaultValue: '')
|
||||
final String firstName;
|
||||
@JsonKey(defaultValue: '')
|
||||
final String lastName;
|
||||
@JsonKey(defaultValue: '')
|
||||
final String className;
|
||||
@JsonKey(defaultValue: '')
|
||||
final String phone;
|
||||
|
||||
AbsencePrefillResponse({
|
||||
required this.firstName,
|
||||
required this.lastName,
|
||||
required this.className,
|
||||
required this.phone,
|
||||
});
|
||||
|
||||
factory AbsencePrefillResponse.fromJson(Map<String, dynamic> json) =>
|
||||
_$AbsencePrefillResponseFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$AbsencePrefillResponseToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'absence_prefill_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
AbsencePrefillResponse _$AbsencePrefillResponseFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => AbsencePrefillResponse(
|
||||
firstName: json['firstName'] as String? ?? '',
|
||||
lastName: json['lastName'] as String? ?? '',
|
||||
className: json['className'] as String? ?? '',
|
||||
phone: json['phone'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AbsencePrefillResponseToJson(
|
||||
AbsencePrefillResponse instance,
|
||||
) => <String, dynamic>{
|
||||
'firstName': instance.firstName,
|
||||
'lastName': instance.lastName,
|
||||
'className': instance.className,
|
||||
'phone': instance.phone,
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import '../../marianumconnect_query.dart';
|
||||
|
||||
/// Submits an absence report (`POST absence`, bearer-auth, `source=mobile`).
|
||||
/// Empty identity fields are backfilled from LDAP server-side; validation
|
||||
/// (all fields required, class must exist, no past start date, end >= start)
|
||||
/// also runs server-side and mirrors the client checks.
|
||||
class AbsenceSubmit extends MarianumConnectQuery {
|
||||
AbsenceSubmit({super.dio});
|
||||
|
||||
Future<void> run({
|
||||
required String firstName,
|
||||
required String lastName,
|
||||
required String className,
|
||||
required DateTime absentFrom,
|
||||
required DateTime absentUntil,
|
||||
required String phone,
|
||||
required String note,
|
||||
}) => guard(() async {
|
||||
await dio.post<void>(
|
||||
endpoint('absence'),
|
||||
data: {
|
||||
'firstName': firstName,
|
||||
'lastName': lastName,
|
||||
'className': className,
|
||||
'absentFrom': isoDate(absentFrom),
|
||||
'absentUntil': isoDate(absentUntil),
|
||||
'phone': phone,
|
||||
'note': note,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user