From 8d95c71faec20ad410ded2bc1e9bde112a70105a Mon Sep 17 00:00:00 2001 From: Armand <4831c0@proton.me> Date: Sun, 1 Mar 2026 14:52:54 +0100 Subject: [PATCH] chore: add kreta_api shared package --- kreta_api/lib/kreta_api.dart | 19 +++ kreta_api/lib/src/api_response.dart | 18 ++ kreta_api/lib/src/endpoints.dart | 46 ++++++ kreta_api/lib/src/exceptions/token.dart | 7 + kreta_api/lib/src/model/all_lessons.dart | 131 +++++++++++++++ kreta_api/lib/src/model/class_group.dart | 113 +++++++++++++ kreta_api/lib/src/model/generic.dart | 64 ++++++++ kreta_api/lib/src/model/grade.dart | 113 +++++++++++++ kreta_api/lib/src/model/guardian.dart | 36 ++++ kreta_api/lib/src/model/homework.dart | 71 ++++++++ kreta_api/lib/src/model/institution.dart | 89 ++++++++++ kreta_api/lib/src/model/notice_board.dart | 95 +++++++++++ kreta_api/lib/src/model/omission.dart | 96 +++++++++++ kreta_api/lib/src/model/student.dart | 114 +++++++++++++ kreta_api/lib/src/model/subject.dart | 48 ++++++ kreta_api/lib/src/model/test.dart | 59 +++++++ kreta_api/lib/src/model/timetable.dart | 190 ++++++++++++++++++++++ kreta_api/lib/src/resp/token_grant.dart | 38 +++++ kreta_api/pubspec.yaml | 10 ++ 19 files changed, 1357 insertions(+) create mode 100644 kreta_api/lib/kreta_api.dart create mode 100644 kreta_api/lib/src/api_response.dart create mode 100644 kreta_api/lib/src/endpoints.dart create mode 100644 kreta_api/lib/src/exceptions/token.dart create mode 100644 kreta_api/lib/src/model/all_lessons.dart create mode 100644 kreta_api/lib/src/model/class_group.dart create mode 100644 kreta_api/lib/src/model/generic.dart create mode 100644 kreta_api/lib/src/model/grade.dart create mode 100644 kreta_api/lib/src/model/guardian.dart create mode 100644 kreta_api/lib/src/model/homework.dart create mode 100644 kreta_api/lib/src/model/institution.dart create mode 100644 kreta_api/lib/src/model/notice_board.dart create mode 100644 kreta_api/lib/src/model/omission.dart create mode 100644 kreta_api/lib/src/model/student.dart create mode 100644 kreta_api/lib/src/model/subject.dart create mode 100644 kreta_api/lib/src/model/test.dart create mode 100644 kreta_api/lib/src/model/timetable.dart create mode 100644 kreta_api/lib/src/resp/token_grant.dart create mode 100644 kreta_api/pubspec.yaml diff --git a/kreta_api/lib/kreta_api.dart b/kreta_api/lib/kreta_api.dart new file mode 100644 index 00000000..73744670 --- /dev/null +++ b/kreta_api/lib/kreta_api.dart @@ -0,0 +1,19 @@ +library kreta_api; + +export 'src/api_response.dart'; +export 'src/endpoints.dart'; +export 'src/exceptions/token.dart'; +export 'src/model/all_lessons.dart'; +export 'src/model/class_group.dart'; +export 'src/model/generic.dart'; +export 'src/model/grade.dart'; +export 'src/model/guardian.dart'; +export 'src/model/homework.dart'; +export 'src/model/institution.dart'; +export 'src/model/notice_board.dart'; +export 'src/model/omission.dart'; +export 'src/model/student.dart'; +export 'src/model/subject.dart'; +export 'src/model/test.dart'; +export 'src/model/timetable.dart'; +export 'src/resp/token_grant.dart'; diff --git a/kreta_api/lib/src/api_response.dart b/kreta_api/lib/src/api_response.dart new file mode 100644 index 00000000..dc02ea6f --- /dev/null +++ b/kreta_api/lib/src/api_response.dart @@ -0,0 +1,18 @@ +class ApiResponse { + T? response; + int statusCode; + String? err; + bool cached; + + ApiResponse(this.response, this.statusCode, this.err, this.cached); + + @override + String toString() { + return "ApiResponse(" + "response: $response, " + "statusCode: $statusCode, " + "err: \"$err\", " + "cached: $cached" + ")"; + } +} diff --git a/kreta_api/lib/src/endpoints.dart b/kreta_api/lib/src/endpoints.dart new file mode 100644 index 00000000..5ec97ad0 --- /dev/null +++ b/kreta_api/lib/src/endpoints.dart @@ -0,0 +1,46 @@ +/// URL builders for Kreta ellenorzo API that depend only on [iss]. +/// Auth-related URLs (login, token) and Constants stay in the app (firka). +class KretaEndpoints { + static const String kretaBase = "e-kreta.hu"; + + static String kreta(String iss) { + if (iss == "firka-test") { + return kretaBase; + } else { + return "https://$iss.$kretaBase"; + } + } + + static String getStudentUrl(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/TanuloAdatlap"; + + static String getClassGroups(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/OsztalyCsoportok"; + + static String getNoticeBoard(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/FaliujsagElemek"; + + static String getInfoBoard(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/Feljegyzesek"; + + static String getGrades(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/Ertekelesek"; + + static String getSubjectAvg(String iss, String studyGroupId) => + "${kreta(iss)}/ellenorzo/v3/sajat/Ertekelesek/Atlagok/TantargyiAtlagok?oktatasiNevelesiFeladatUid=$studyGroupId&oktatasiNevelesiFeladatUid=$studyGroupId"; + + static String getTimeTable(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/OrarendElemek"; + + static String getOmissions(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/Mulasztasok"; + + static String getHomework(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/HaziFeladatok"; + + static String getTests(String iss) => + "${kreta(iss)}/ellenorzo/v3/sajat/BejelentettSzamonkeresek"; + + static String getLessons(String iss) => + "${kreta(iss)}/dktapi/intezmenyek/munkaterek/tanulok"; +} diff --git a/kreta_api/lib/src/exceptions/token.dart b/kreta_api/lib/src/exceptions/token.dart new file mode 100644 index 00000000..70ccdbbf --- /dev/null +++ b/kreta_api/lib/src/exceptions/token.dart @@ -0,0 +1,7 @@ +class TokenExpiredException implements Exception { + TokenExpiredException(); +} + +class InvalidGrantException implements Exception { + InvalidGrantException(); +} diff --git a/kreta_api/lib/src/model/all_lessons.dart b/kreta_api/lib/src/model/all_lessons.dart new file mode 100644 index 00000000..c09b44d5 --- /dev/null +++ b/kreta_api/lib/src/model/all_lessons.dart @@ -0,0 +1,131 @@ +import 'dart:convert'; + +class AllLessons { + final String schoolId; + final String yearId; + final dynamic classId; + final String? className; + final bool classWorkspace; + final dynamic groupId; + final String? groupName; + final bool groupWorkspace; + final String groupWorkspaceName; + final dynamic subjectId; + final String subjectName; + final dynamic teacherId; + final String teacherGuid; + final String teacherName; + final dynamic teacherAnnoId; + final dynamic annoId; + final String? languageId; + final dynamic subjectCategoryId; + final String subjectCategoryName; + final dynamic typeId; + final String typeName; + final dynamic gradeTypeId; + final String gradeTypeName; + final dynamic taskPlaceId; + final String taskPlaceName; + final dynamic teacherAvatarTypeId; + final String teacherAvatarTypePath; + final dynamic taskGroupId; + + AllLessons({ + required this.schoolId, + required this.yearId, + this.classId, + this.className, + required this.classWorkspace, + this.groupId, + this.groupName, + required this.groupWorkspace, + required this.groupWorkspaceName, + required this.subjectId, + required this.subjectName, + required this.teacherId, + required this.teacherGuid, + required this.teacherName, + this.teacherAnnoId, + this.annoId, + this.languageId, + required this.subjectCategoryId, + required this.subjectCategoryName, + required this.typeId, + required this.typeName, + required this.gradeTypeId, + required this.gradeTypeName, + required this.taskPlaceId, + required this.taskPlaceName, + required this.teacherAvatarTypeId, + required this.teacherAvatarTypePath, + this.taskGroupId, + }); + + factory AllLessons.fromJson(Map json) => AllLessons( + schoolId: json['intezmenyId']?.toString() ?? '', + yearId: json['tanevId']?.toString() ?? '', + classId: json['osztalyId'], + className: json['osztalyNev']?.toString(), + classWorkspace: json['osztalyMunkaTer'] == true, + groupId: json['csoportId'], + groupName: json['csoportNev']?.toString(), + groupWorkspace: json['csoportMunkaTer'] == true, + groupWorkspaceName: json['osztalyCsoportNev']?.toString() ?? '', + subjectId: json['tantargyId'], + subjectName: json['tantargyNev']?.toString() ?? '', + teacherId: json['alkalmazottId'], + teacherGuid: json['alkalmazottGuid']?.toString() ?? '', + teacherName: json['alkalmazottNev']?.toString() ?? '', + teacherAnnoId: json['alkalmazottUzenoFalId'], + annoId: json['uzenoFalId'], + languageId: json['nyelvId']?.toString(), + subjectCategoryId: json['tantargyKategoriaId'], + subjectCategoryName: json['tantargyKategoriaNev']?.toString() ?? '', + typeId: json['tipusId'], + typeName: json['tipusNev']?.toString() ?? '', + gradeTypeId: json['evfolyamTipusId'], + gradeTypeName: json['evfolyamTipusNev']?.toString() ?? '', + taskPlaceId: json['feladatEllatasiHelyId'], + taskPlaceName: json['feladatEllatasiHelyNev']?.toString() ?? '', + teacherAvatarTypeId: json['alkalmazottAvatarTipusId'], + teacherAvatarTypePath: json['alkalmazottAvatarEleres']?.toString() ?? '', + taskGroupId: json['oraiFeladatGroupId'], + ); + + Map toJson() => { + 'intezmenyId': schoolId, + 'tanevId': yearId, + 'osztalyId': classId, + 'osztalyNev': className, + 'osztalyMunkaTer': classWorkspace, + 'csoportId': groupId, + 'csoportNev': groupName, + 'csoportMunkaTer': groupWorkspace, + 'osztalyCsoportNev': groupWorkspaceName, + 'tantargyId': subjectId, + 'tantargyNev': subjectName, + 'alkalmazottId': teacherId, + 'alkalmazottGuid': teacherGuid, + 'alkalmazottNev': teacherName, + 'alkalmazottUzenoFalId': teacherAnnoId, + 'uzenoFalId': annoId, + 'nyelvId': languageId, + 'tantargyKategoriaId': subjectCategoryId, + 'tantargyKategoriaNev': subjectCategoryName, + 'tipusId': typeId, + 'tipusNev': typeName, + 'evfolyamTipusId': gradeTypeId, + 'evfolyamTipusNev': gradeTypeName, + 'feladatEllatasiHelyId': taskPlaceId, + 'feladatEllatasiHelyNev': taskPlaceName, + 'alkalmazottAvatarTipusId': teacherAvatarTypeId, + 'alkalmazottAvatarEleres': teacherAvatarTypePath, + 'oraiFeladatGroupId': taskGroupId, + }; +} + +List lessonsFromJson(String str) => + List.from(json.decode(str).map((x) => AllLessons.fromJson(x))); + +String lessonsToJson(List data) => + json.encode(List.from(data.map((x) => x.toJson()))); diff --git a/kreta_api/lib/src/model/class_group.dart b/kreta_api/lib/src/model/class_group.dart new file mode 100644 index 00000000..d520c582 --- /dev/null +++ b/kreta_api/lib/src/model/class_group.dart @@ -0,0 +1,113 @@ +import 'generic.dart'; + +class ClassGroup { + final String uid; + final String name; + final UidObj? headTeacher; + final UidObj? substituteHeadTeacher; + final NameUidDesc studyGroup; + final int? studyGroupSortIndex; + final NameUidDesc? studyTask; + final bool isActive; + final String type; + + ClassGroup({ + required this.uid, + required this.name, + required this.headTeacher, + required this.substituteHeadTeacher, + required this.studyGroup, + required this.studyGroupSortIndex, + required this.studyTask, + required this.isActive, + required this.type, + }); + + factory ClassGroup.fromJson(Map json) { + return ClassGroup( + uid: json['Uid'], + name: json['Nev'], + headTeacher: json['OsztalyFonok'] != null + ? UidObj.fromJson(json['OsztalyFonok']) + : null, + substituteHeadTeacher: json['OsztalyFonokHelyettes'] != null + ? UidObj.fromJson(json['OsztalyFonokHelyettes']) + : null, + studyGroup: NameUidDesc.fromJson(json['OktatasNevelesiKategoria']), + studyGroupSortIndex: json['OktatasNevelesiKategoriaSortIndex'], + studyTask: json['OktatasNevelesiFeladat'] != null + ? NameUidDesc.fromJson(json['OktatasNevelesiFeladat']) + : null, + isActive: json['IsAktiv'], + type: json['Tipus'], + ); + } + + @override + String toString() { + return 'ClassGroup(' + 'uid: "$uid", ' + 'name: "$name", ' + 'headTeacher: $headTeacher, ' + 'substituteHeadTeacher: $substituteHeadTeacher, ' + 'studyGroup: $studyGroup, ' + 'studyGroupSortIndex: $studyGroupSortIndex, ' + 'studyTask: $studyTask, ' + 'isActive: $isActive, ' + 'type: "$type"' + ')'; + } +} + +class SubjectAverage { + final String uid; + final String name; + final String? teacherName; + final String subjectCategoryId; + final String subjectCategoryName; + final String subjectCategoryDescription; + final double? average; + final double? weightedSum; + final double? weightedCount; + final int sortIndex; + + SubjectAverage({ + required this.uid, + required this.name, + this.teacherName, + required this.subjectCategoryId, + required this.subjectCategoryName, + required this.subjectCategoryDescription, + this.average, + this.weightedSum, + this.weightedCount, + required this.sortIndex, + }); + + factory SubjectAverage.fromJson(Map json) { + final tantargy = json['Tantargy'] ?? {}; + final kategori = tantargy['Kategoria'] ?? {}; + + return SubjectAverage( + uid: json['Uid'] ?? '', + name: tantargy['Nev'] ?? '', + teacherName: json['TeacherName'], + subjectCategoryId: kategori['Uid'] ?? '', + subjectCategoryName: kategori['Nev'] ?? '', + subjectCategoryDescription: kategori['Leiras'] ?? '', + average: json['Atlag'] != null ? (json['Atlag'] as num).toDouble() : null, + weightedSum: json['SulyozottOsztalyzatOsszege'] != null + ? (json['SulyozottOsztalyzatOsszege'] as num).toDouble() + : null, + weightedCount: json['SulyozottOsztalyzatSzama'] != null + ? (json['SulyozottOsztalyzatSzama'] as num).toDouble() + : null, + sortIndex: tantargy['SortIndex'] ?? 0, + ); + } + + @override + String toString() { + return 'SubjectAverage(uid: "$uid", name: "$name", category: "$subjectCategoryName", average: $average)'; + } +} diff --git a/kreta_api/lib/src/model/generic.dart b/kreta_api/lib/src/model/generic.dart new file mode 100644 index 00000000..cb2d276d --- /dev/null +++ b/kreta_api/lib/src/model/generic.dart @@ -0,0 +1,64 @@ +class NameUidDesc { + final String uid; + final String? name; + final String? description; + + NameUidDesc({ + required this.uid, + required this.name, + required this.description, + }); + + factory NameUidDesc.fromJson(Map json) { + return NameUidDesc( + uid: json['Uid'], + name: json['Nev'], + description: json['Leiras'], + ); + } + + Map toJson() { + return {'Uid': uid, 'Nev': name, 'Leiras': description}; + } + + @override + String toString() { + return 'NameUidDesc(' + 'uid: "$uid", ' + 'name: "$name", ' + 'description: "$description"' + ')'; + } +} + +class NameUid { + final String uid; + final String name; + + NameUid({required this.uid, required this.name}); + + factory NameUid.fromJson(Map json) { + return NameUid(uid: json['Uid'], name: json['Nev']); + } + + Map toJson() { + return {'Uid': uid, 'Nev': name}; + } +} + +class UidObj { + final String uid; + + UidObj({required this.uid}); + + factory UidObj.fromJson(Map json) { + return UidObj(uid: json['Uid']); + } + + @override + String toString() { + return 'UidObj(' + 'uid: "$uid"' + ')'; + } +} diff --git a/kreta_api/lib/src/model/grade.dart b/kreta_api/lib/src/model/grade.dart new file mode 100644 index 00000000..ef04aaa7 --- /dev/null +++ b/kreta_api/lib/src/model/grade.dart @@ -0,0 +1,113 @@ +import 'generic.dart'; +import 'subject.dart'; + +class Grade { + final String uid; + final DateTime recordDate; + final DateTime creationDate; + final DateTime? ackDate; + final Subject subject; + final String? topic; + final NameUidDesc type; + final NameUidDesc? mode; + NameUidDesc valueType; + final String teacher; + final String? kind; + int? numericValue; + final String strValue; + final int? weightPercentage; + final String? shortStrValue; + final UidObj? classGroup; + final int sortIndex; + + Grade({ + required this.uid, + required this.recordDate, + required this.creationDate, + this.ackDate, + required this.subject, + this.topic, + required this.type, + this.mode, + required this.valueType, + required this.teacher, + this.kind, + this.numericValue, + required this.strValue, + this.weightPercentage, + this.shortStrValue, + this.classGroup, + required this.sortIndex, + }); + + factory Grade.fromJson(Map json) { + return Grade( + uid: json['Uid'], + recordDate: DateTime.parse(json['RogzitesDatuma']).toLocal(), + creationDate: DateTime.parse(json['KeszitesDatuma']).toLocal(), + ackDate: json['LattamozasDatuma'] != null + ? DateTime.parse(json['LattamozasDatuma']).toLocal() + : null, + subject: Subject.fromJson(json['Tantargy']), + topic: json['Tema'], + type: NameUidDesc.fromJson(json['Tipus']), + mode: json['Mod'] != null ? NameUidDesc.fromJson(json['Mod']) : null, + valueType: NameUidDesc.fromJson(json['ErtekFajta']), + teacher: json['ErtekeloTanarNeve'], + kind: json['Kind'], + numericValue: json['SzamErtek'], + strValue: json['SzovegesErtek'], + weightPercentage: json['SulySzazalekErteke'], + shortStrValue: json['SzovegesErtekelesRovidNev'], + classGroup: json['OsztalyCsoport'] != null + ? UidObj.fromJson(json['OsztalyCsoport']) + : null, + sortIndex: json['SortIndex'], + ); + } + + Map toJson() { + return { + 'Uid': uid, + 'RogzitesDatuma': recordDate.toUtc().toIso8601String(), + 'KeszitesDatuma': creationDate.toUtc().toIso8601String(), + 'LattamozasDatuma': ackDate?.toUtc().toIso8601String(), + 'Tantargy': subject.toJson(), + 'Tema': topic, + 'Tipus': type.toJson(), + 'Mod': mode?.toJson(), + 'ErtekFajta': valueType.toJson(), + 'ErtekeloTanarNeve': teacher, + 'Kind': kind, + 'SzamErtek': numericValue, + 'SzovegesErtek': strValue, + 'SulySzazalekErteke': weightPercentage, + 'SzovegesErtekelesRovidNev': shortStrValue, + 'OsztalyCsoport': classGroup != null ? {'Uid': classGroup!.uid} : null, + 'SortIndex': sortIndex, + }; + } + + @override + String toString() { + return 'Grade(' + 'uid: "$uid", ' + 'recordDate: "$recordDate", ' + 'creationDate: "$creationDate", ' + 'ackDate: "${ackDate ?? 'null'}", ' + 'subject: $subject, ' + 'topic: "${topic ?? 'null'}", ' + 'type: $type, ' + 'mode: ${mode ?? 'null'}, ' + 'valueType: $valueType, ' + 'teacher: "$teacher", ' + 'kind: "${kind ?? 'null'}", ' + 'numericValue: ${numericValue ?? 'null'}, ' + 'strValue: "$strValue", ' + 'weightPercentage: ${weightPercentage ?? 'null'}, ' + 'shortStrValue: "${shortStrValue ?? 'null'}", ' + 'classGroup: ${classGroup ?? 'null'}, ' + 'sortIndex: $sortIndex' + ')'; + } +} diff --git a/kreta_api/lib/src/model/guardian.dart b/kreta_api/lib/src/model/guardian.dart new file mode 100644 index 00000000..123bf4f4 --- /dev/null +++ b/kreta_api/lib/src/model/guardian.dart @@ -0,0 +1,36 @@ +class Guardian { + final String? email; + final bool isLegalRepresentative; + final String? name; + final String? phoneNumber; + final String uid; + + Guardian({ + required this.email, + required this.isLegalRepresentative, + required this.name, + required this.phoneNumber, + required this.uid, + }); + + factory Guardian.fromJson(Map json) { + return Guardian( + email: json['EmailCim'], + isLegalRepresentative: json['IsTorvenyesKepviselo'], + name: json['Nev'], + phoneNumber: json['Telefonszam'], + uid: json['Uid'], + ); + } + + @override + String toString() { + return 'Guardian(' + 'email: "$email", ' + 'isLegalRepresentative: $isLegalRepresentative, ' + 'name: "$name", ' + 'phoneNumber: "$phoneNumber", ' + 'uid: "$uid"' + ')'; + } +} diff --git a/kreta_api/lib/src/model/homework.dart b/kreta_api/lib/src/model/homework.dart new file mode 100644 index 00000000..d3662a7c --- /dev/null +++ b/kreta_api/lib/src/model/homework.dart @@ -0,0 +1,71 @@ +import 'generic.dart'; +import 'subject.dart'; + +class Homework { + final String uid; + final Subject subject; + final String subjectName; + final String teacherName; + final String description; + final DateTime startDate; + final DateTime dueDate; + final DateTime creationDate; + final bool isCreatedByTeacher; + final bool isDone; + final bool canBeSubmitted; + final UidObj classGroup; + final bool canAttach; + + Homework({ + required this.uid, + required this.subject, + required this.subjectName, + required this.teacherName, + required this.description, + required this.startDate, + required this.dueDate, + required this.creationDate, + required this.isCreatedByTeacher, + required this.isDone, + required this.canBeSubmitted, + required this.classGroup, + required this.canAttach, + }); + + factory Homework.fromJson(Map json) { + return Homework( + uid: json["Uid"], + subject: Subject.fromJson(json["Tantargy"]), + subjectName: json["TantargyNeve"], + teacherName: json["RogzitoTanarNeve"], + description: json["Szoveg"], + startDate: DateTime.parse(json["FeladasDatuma"]).toLocal(), + dueDate: DateTime.parse(json["HataridoDatuma"]).toLocal(), + creationDate: DateTime.parse(json["RogzitesIdopontja"]).toLocal(), + isCreatedByTeacher: json["IsTanarRogzitette"], + isDone: json["IsMegoldva"], + canBeSubmitted: json["IsBeadhato"], + classGroup: UidObj.fromJson(json["OsztalyCsoport"]), + canAttach: json["IsCsatolasEngedelyezes"], + ); + } + + @override + String toString() { + return 'Homework(' + 'uid: "$uid", ' + 'subject: $subject, ' + 'subjectName: "$subjectName", ' + 'teacherName: "$teacherName", ' + 'description: "$description", ' + 'startDate: $startDate, ' + 'dueDate: $dueDate, ' + 'creationDate: $creationDate, ' + 'isCreatedByTeacher: $isCreatedByTeacher, ' + 'isDone: $isDone, ' + 'canBeSubmitted: $canBeSubmitted, ' + 'classGroup: $classGroup, ' + 'canAttach: $canAttach' + ')'; + } +} diff --git a/kreta_api/lib/src/model/institution.dart b/kreta_api/lib/src/model/institution.dart new file mode 100644 index 00000000..54248544 --- /dev/null +++ b/kreta_api/lib/src/model/institution.dart @@ -0,0 +1,89 @@ +class Institution { + final CustomizationSettings customizationSettings; + final String shortName; + final List systemModuleList; + final String uid; + + Institution({ + required this.customizationSettings, + required this.shortName, + required this.systemModuleList, + required this.uid, + }); + + factory Institution.fromJson(Map json) { + var systemModuleList = List.empty(growable: true); + + for (var item in json['Rendszermodulok']) { + systemModuleList.add(SystemModule.fromJson(item)); + } + + return Institution( + customizationSettings: CustomizationSettings.fromJson( + json['TestreszabasBeallitasok'], + ), + shortName: json['RovidNev'], + systemModuleList: systemModuleList, + uid: json['Uid'], + ); + } +} + +class CustomizationSettings { + final int delayForNotifications; + final bool isClassAverageVisible; + final bool isLessonsThemeVisible; + final String nextServerDeployAsString; + + CustomizationSettings({ + required this.delayForNotifications, + required this.isClassAverageVisible, + required this.isLessonsThemeVisible, + required this.nextServerDeployAsString, + }); + + factory CustomizationSettings.fromJson(Map json) { + return CustomizationSettings( + delayForNotifications: + json['ErtekelesekMegjelenitesenekKesleltetesenekMerteke'], + isClassAverageVisible: json['IsOsztalyAtlagMegjeleniteseEllenorzoben'], + isLessonsThemeVisible: json['IsTanorakTemajaMegtekinthetoEllenorzoben'], + nextServerDeployAsString: json['KovetkezoTelepitesDatuma'], + ); + } + + @override + String toString() { + return 'CustomizationSettings(' + 'delayForNotifications: $delayForNotifications, ' + 'isClassAverageVisible: $isClassAverageVisible, ' + 'isLessonsThemeVisible: $isLessonsThemeVisible, ' + 'nextServerDeployAsString: "$nextServerDeployAsString"' + ')'; + } +} + +class SystemModule { + final bool isActive; + final String type; + final String? url; + + SystemModule({required this.isActive, required this.type, required this.url}); + + factory SystemModule.fromJson(Map json) { + return SystemModule( + isActive: json['IsAktiv'], + type: json['Tipus'], + url: json['Url'], + ); + } + + @override + String toString() { + return 'SystemModule(' + 'isActive: $isActive, ' + 'type: "$type", ' + 'url: "$url"' + ')'; + } +} diff --git a/kreta_api/lib/src/model/notice_board.dart b/kreta_api/lib/src/model/notice_board.dart new file mode 100644 index 00000000..52d9cc2f --- /dev/null +++ b/kreta_api/lib/src/model/notice_board.dart @@ -0,0 +1,95 @@ +import 'generic.dart'; + +class NoticeBoardItem { + final String uid; + final String author; + final DateTime validFrom; + final DateTime validTo; + final String title; + final String contentHTML; + final String contentText; + + NoticeBoardItem({ + required this.uid, + required this.author, + required this.validFrom, + required this.validTo, + required this.title, + required this.contentHTML, + required this.contentText, + }); + + factory NoticeBoardItem.fromJson(Map json) { + return NoticeBoardItem( + uid: json['Uid'], + author: json['RogzitoNeve'], + validFrom: DateTime.parse(json['ErvenyessegKezdete']), + validTo: DateTime.parse(json['ErvenyessegVege']), + title: json['Cim'], + contentHTML: json['Tartalom'], + contentText: json['TartalomText'], + ); + } + + @override + String toString() { + return 'NoticeBoardItem(' + 'uid: "$uid", ' + 'author: "$author", ' + 'validFrom: "$validFrom", ' + 'validTo: "$validTo", ' + 'title: "$title", ' + 'contentHTML: "$contentHTML", ' + 'contentText: "$contentText"' + ')'; + } +} + +class InfoBoardItem { + final String uid; + final String title; + final DateTime date; + final String author; + final DateTime createdAt; + final String contentHTML; + final String contentText; + final NameUidDesc type; + + InfoBoardItem({ + required this.uid, + required this.title, + required this.date, + required this.author, + required this.createdAt, + required this.contentHTML, + required this.contentText, + required this.type, + }); + + factory InfoBoardItem.fromJson(Map json) { + return InfoBoardItem( + uid: json['Uid'], + title: json['Cim'], + date: DateTime.parse(json['Datum']), + author: json['KeszitoTanarNeve'], + createdAt: DateTime.parse(json['KeszitesDatuma']), + contentText: json['Tartalom'], + contentHTML: json['TartalomFormazott'], + type: NameUidDesc.fromJson(json['Tipus']), + ); + } + + @override + String toString() { + return 'InfoBoard(' + 'uid: "$uid", ' + 'title: "$title", ' + 'date: "$date", ' + 'author: "$author", ' + 'createdAt: "$createdAt", ' + 'contentText: "$contentText", ' + 'contentHTML: "$contentHTML", ' + 'type: $type' + ')'; + } +} diff --git a/kreta_api/lib/src/model/omission.dart b/kreta_api/lib/src/model/omission.dart new file mode 100644 index 00000000..9c354bc0 --- /dev/null +++ b/kreta_api/lib/src/model/omission.dart @@ -0,0 +1,96 @@ +import 'generic.dart'; +import 'subject.dart'; + +class Omission { + final String uid; + final Subject subject; + final Class? c; + final DateTime date; + final String teacher; + final NameUidDesc? type; + final NameUidDesc? mode; + final int? lateForMin; + final DateTime createdAt; + final String state; + final NameUidDesc? proofType; + final UidObj? classGroup; + + Omission({ + required this.uid, + required this.subject, + required this.c, + required this.date, + required this.teacher, + this.type, + this.mode, + this.lateForMin, + required this.createdAt, + required this.state, + required this.proofType, + this.classGroup, + }); + + factory Omission.fromJson(Map json) { + return Omission( + uid: json['Uid'], + subject: Subject.fromJson(json['Tantargy']), + c: json['Osztaly'] != null ? Class.fromJson(json['Osztaly']) : null, + date: DateTime.parse(json['Datum']).toLocal(), + teacher: json['RogzitoTanarNeve'], + type: json['Tipus'] != null ? NameUidDesc.fromJson(json['Tipus']) : null, + mode: json['Mod'] != null ? NameUidDesc.fromJson(json['Mod']) : null, + lateForMin: json['KesesPercben'], + createdAt: DateTime.parse(json['KeszitesDatuma']).toLocal(), + state: json['IgazolasAllapota'], + proofType: json['IgazolasTipusa'] != null + ? NameUidDesc.fromJson(json['IgazolasTipusa']) + : null, + classGroup: json['OsztalyCsoport'] != null + ? UidObj.fromJson(json['OsztalyCsoport']) + : null, + ); + } + + @override + String toString() { + return 'Omission(' + 'uid: "$uid", ' + 'subject: $subject, ' + 'c: $c, ' + 'date: $date, ' + 'teacher: "$teacher", ' + 'type: $type, ' + 'mode: $mode, ' + 'lateForMin: $lateForMin, ' + 'createdAt: $createdAt, ' + 'state: "$state", ' + 'proofType: $proofType, ' + 'classGroup: $classGroup' + ')'; + } +} + +class Class { + final DateTime start; + final DateTime end; + final int classNo; + + Class({required this.start, required this.end, required this.classNo}); + + factory Class.fromJson(Map json) { + return Class( + start: DateTime.parse(json['KezdoDatum']).toLocal(), + end: DateTime.parse(json['VegDatum']).toLocal(), + classNo: json['Oraszam'], + ); + } + + @override + String toString() { + return 'Class(' + 'start: "$start", ' + 'end: "$end", ' + 'classNo: $classNo' + ')'; + } +} diff --git a/kreta_api/lib/src/model/student.dart b/kreta_api/lib/src/model/student.dart new file mode 100644 index 00000000..38c8bbb8 --- /dev/null +++ b/kreta_api/lib/src/model/student.dart @@ -0,0 +1,114 @@ +import 'package:intl/intl.dart'; + +import 'guardian.dart'; +import 'institution.dart'; + +class Student { + final List addressDataList; + final BankAccount bankAccount; + + final DateTime birthdate; + + final String? emailAddress; + final String name; + final String? phoneNumber; + + final String schoolYearUID; + final String uid; + + final List guardianList; + final String instituteCode; + final String instituteName; + + final Institution institution; + + Student({ + required this.addressDataList, + required this.bankAccount, + required this.birthdate, + required this.emailAddress, + required this.name, + required this.phoneNumber, + required this.schoolYearUID, + required this.uid, + required this.guardianList, + required this.instituteCode, + required this.instituteName, + required this.institution, + }); + + factory Student.fromJson(Map json) { + var guardianList = List.empty(growable: true); + + for (var item in json['Gondviselok']) { + guardianList.add(Guardian.fromJson(item)); + } + + return Student( + addressDataList: List.from(json['Cimek'] as List), + bankAccount: BankAccount.fromJson(json['Bankszamla']), + birthdate: DateFormat('yyyy-M-d').parse( + "${json['SzuletesiEv']}-${json['SzuletesiHonap']}-${json['SzuletesiNap']}", + ), + emailAddress: json['EmailCim'], + name: json['Nev'], + phoneNumber: json['Telefonszam'], + schoolYearUID: json['TanevUid'], + uid: json['Uid'], + guardianList: guardianList, + instituteCode: json['IntezmenyAzonosito'], + instituteName: json['IntezmenyNev'], + institution: Institution.fromJson(json['Intezmeny']), + ); + } + + @override + String toString() { + return 'Student(' + 'addressDataList: [$addressDataList], ' + 'bankAccount: $bankAccount, ' + 'birthDate: $birthdate, ' + 'emailAddress: "$emailAddress", ' + 'name: "$name", ' + 'phoneNumber: "$phoneNumber", ' + 'schoolYearUID: "$schoolYearUID", ' + 'uid: "$uid", ' + 'guardianList: [$guardianList], ' + 'instituteCode: "$instituteCode", ' + 'instituteName: "$instituteName", ' + ')'; + } +} + +class BankAccount { + final String? accountNumber; + final bool? isReadOnly; + final String? ownerName; + final int? ownerType; + + BankAccount({ + required this.accountNumber, + required this.isReadOnly, + required this.ownerName, + required this.ownerType, + }); + + factory BankAccount.fromJson(Map json) { + return BankAccount( + accountNumber: json['BankszamlaSzam'], + isReadOnly: json['IsReadOnly'], + ownerName: json['BankszamlaTulajdonosNeve'], + ownerType: json['BankszamlaTulajdonosTipusId'], + ); + } + + @override + String toString() { + return 'BankAccount(' + 'accountNumber: "$accountNumber", ' + 'isReadOnly: "$isReadOnly", ' + 'ownerName: "$ownerName", ' + 'ownerType: "$ownerType"' + ')'; + } +} diff --git a/kreta_api/lib/src/model/subject.dart b/kreta_api/lib/src/model/subject.dart new file mode 100644 index 00000000..25060b42 --- /dev/null +++ b/kreta_api/lib/src/model/subject.dart @@ -0,0 +1,48 @@ +import 'generic.dart'; + +class Subject { + final String uid; + final String name; + final NameUidDesc category; + final int sortIndex; + final String? teacherName; + + Subject({ + required this.uid, + required this.name, + required this.category, + required this.sortIndex, + this.teacherName, + }); + + factory Subject.fromJson(Map json) { + return Subject( + uid: json['Uid'], + name: json['Nev'], + category: NameUidDesc.fromJson(json['Kategoria']), + sortIndex: json['SortIndex'], + teacherName: json['alkalmazottNev'], + ); + } + + Map toJson() { + return { + 'Uid': uid, + 'Nev': name, + 'Kategoria': category.toJson(), + 'SortIndex': sortIndex, + 'alkalmazottNev': teacherName, + }; + } + + @override + String toString() { + return 'Subject(' + 'uid: "$uid", ' + 'name: "$name", ' + 'category: $category, ' + 'sortIndex: $sortIndex, ' + 'nameOfTeacher: $teacherName' + ')'; + } +} diff --git a/kreta_api/lib/src/model/test.dart b/kreta_api/lib/src/model/test.dart new file mode 100644 index 00000000..9e685a52 --- /dev/null +++ b/kreta_api/lib/src/model/test.dart @@ -0,0 +1,59 @@ +import 'generic.dart'; +import 'subject.dart'; + +class Test { + final String uid; + final DateTime date; + final DateTime reportDate; + final String teacherName; + final int lessonNumber; + final Subject subject; + final String subjectName; + final String theme; + final NameUidDesc method; + final UidObj classGroup; + + Test({ + required this.uid, + required this.date, + required this.reportDate, + required this.teacherName, + required this.lessonNumber, + required this.subject, + required this.subjectName, + required this.theme, + required this.method, + required this.classGroup, + }); + + factory Test.fromJson(Map json) { + return Test( + uid: json['Uid'], + date: DateTime.parse(json['Datum']).toLocal(), + reportDate: DateTime.parse(json['BejelentesDatuma']).toLocal(), + teacherName: json['RogzitoTanarNeve'], + lessonNumber: json['OrarendiOraOraszama'], + subject: Subject.fromJson(json['Tantargy']), + subjectName: json['TantargyNeve'], + theme: json['Temaja'], + method: NameUidDesc.fromJson(json['Modja']), + classGroup: UidObj.fromJson(json['OsztalyCsoport']), + ); + } + + @override + String toString() { + return 'Test(' + 'uid: "$uid", ' + 'date: $date, ' + 'reportDate: $reportDate, ' + 'teacherName: "$teacherName", ' + 'lessonNumber: $lessonNumber, ' + 'subject: $subject, ' + 'subjectName: "$subjectName", ' + 'theme: "$theme", ' + 'method: $method, ' + 'classGroup: $classGroup' + ')'; + } +} diff --git a/kreta_api/lib/src/model/timetable.dart b/kreta_api/lib/src/model/timetable.dart new file mode 100644 index 00000000..8fb5efc0 --- /dev/null +++ b/kreta_api/lib/src/model/timetable.dart @@ -0,0 +1,190 @@ +import 'generic.dart'; +import 'subject.dart'; + +class Lesson { + final String uid; + final String date; + final DateTime start; + final DateTime end; + final String name; + final int? lessonNumber; + final int? lessonSeqNumber; + final NameUid? classGroup; + final String? teacher; + final Subject? subject; + final String? theme; + final String? roomName; + final NameUidDesc type; + final NameUidDesc? studentPresence; + final NameUidDesc state; + final String? substituteTeacher; + final String? homeworkUid; + final String? taskGroupUid; + final String? languageTaskGroupUid; + final String? assessmentUid; + final bool canStudentEditHomework; + final bool isHomeworkComplete; + final List attachments; + final bool isDigitalLesson; + final String? digitalDeviceList; + final String? digitalPlatformType; + final List digitalSupportDeviceTypeList; + final DateTime createdAt; + final DateTime lastModifiedAt; + + Lesson({ + required this.uid, + required this.date, + required this.start, + required this.end, + required this.name, + this.lessonNumber, + this.lessonSeqNumber, + this.classGroup, + this.teacher, + this.subject, + this.theme, + this.roomName, + required this.type, + this.studentPresence, + required this.state, + this.substituteTeacher, + this.homeworkUid, + this.taskGroupUid, + this.languageTaskGroupUid, + this.assessmentUid, + required this.canStudentEditHomework, + required this.isHomeworkComplete, + required this.attachments, + required this.isDigitalLesson, + this.digitalDeviceList, + this.digitalPlatformType, + required this.digitalSupportDeviceTypeList, + required this.createdAt, + required this.lastModifiedAt, + }); + + factory Lesson.fromJson(Map json) { + var attachments = List.empty(growable: true); + var rawAttachments = json['Csatolmanyok']; + + for (var attachment in rawAttachments) { + attachments.add(NameUid.fromJson(attachment)); + } + return Lesson( + uid: json['Uid'], + date: json['Datum'], + start: DateTime.parse(json['KezdetIdopont']).toLocal(), + end: DateTime.parse(json['VegIdopont']).toLocal(), + name: json['Nev'], + lessonNumber: json['Oraszam'], + lessonSeqNumber: json['OraEvesSorszama'], + classGroup: json['OsztalyCsoport'] != null + ? NameUid.fromJson(json['OsztalyCsoport']) + : null, + teacher: json['TanarNeve'], + subject: json['Tantargy'] != null + ? Subject.fromJson(json['Tantargy']) + : null, + theme: json['Tema'], + roomName: json['TeremNeve'], + type: NameUidDesc.fromJson(json['Tipus']), + studentPresence: json['TanuloJelenlet'] != null + ? NameUidDesc.fromJson(json['TanuloJelenlet']) + : null, + state: NameUidDesc.fromJson(json['Allapot']), + substituteTeacher: json['HelyettesTanarNeve'], + homeworkUid: json['HaziFeladatUid'], + taskGroupUid: json['FeladatGroupUid'], + languageTaskGroupUid: json['NyelviFeladatGroupUid'], + assessmentUid: json['BejelentettSzamonkeresUid'], + canStudentEditHomework: json['IsTanuloHaziFeladatEnabled'], + isHomeworkComplete: json['IsHaziFeladatMegoldva'], + attachments: attachments, + isDigitalLesson: json['IsDigitalisOra'], + digitalDeviceList: json['DigitalisEszkozTipus'], + digitalPlatformType: json['DigitalisPlatformTipus'], + digitalSupportDeviceTypeList: + json['DigitalisTamogatoEszkozTipusList'] != null + ? List.from(json['DigitalisTamogatoEszkozTipusList']) + : List.empty(), + createdAt: DateTime.parse(json['Letrehozas']).toLocal(), + lastModifiedAt: DateTime.parse(json['UtolsoModositas']).toLocal(), + ); + } + + Map toJson() { + List rawAttachments = []; + + for (var item in attachments) { + rawAttachments.add(item.toJson()); + } + + return { + 'Uid': uid, + 'Datum': date, + 'KezdetIdopont': start.toIso8601String(), + 'VegIdopont': end.toIso8601String(), + 'Nev': name, + 'Oraszam': lessonNumber, + 'OraEvesSorszama': lessonSeqNumber, + 'OsztalyCsoport': classGroup?.toJson(), + 'TanarNeve': teacher, + 'Tantargy': subject?.toJson(), + 'Tema': theme, + 'TeremNeve': roomName, + 'Tipus': type.toJson(), + 'TanuloJelenlet': studentPresence?.toJson(), + 'Allapot': state.toJson(), + 'HelyettesTanarNeve': substituteTeacher, + 'HaziFeladatUid': homeworkUid, + 'FeladatGroupUid': taskGroupUid, + 'NyelviFeladatGroupUid': languageTaskGroupUid, + 'BejelentettSzamonkeresUid': assessmentUid, + 'IsTanuloHaziFeladatEnabled': canStudentEditHomework, + 'IsHaziFeladatMegoldva': isHomeworkComplete, + 'Csatolmanyok': rawAttachments, + 'IsDigitalisOra': isDigitalLesson, + 'DigitalisEszkozTipus': digitalDeviceList, + 'DigitalisPlatformTipus': digitalPlatformType, + 'DigitalisTamogatoEszkozTipusList': digitalSupportDeviceTypeList, + 'Letrehozas': createdAt.toIso8601String(), + 'UtolsoModositas': lastModifiedAt.toIso8601String(), + }; + } + + @override + String toString() { + return 'Lesson(' + 'uid: "$uid", ' + 'date: "$date", ' + 'start: $start, ' + 'end: $end, ' + 'name: "$name", ' + 'lessonNumber: $lessonNumber, ' + 'lessonSeqNumber: $lessonSeqNumber, ' + 'classGroup: $classGroup, ' + 'teacher: "$teacher", ' + 'subject: $subject, ' + 'theme: "$theme", ' + 'roomName: "$roomName", ' + 'type: $type, ' + 'studentPresence: $studentPresence, ' + 'state: $state, ' + 'substituteTeacher: "$substituteTeacher", ' + 'homeworkUid: "$homeworkUid", ' + 'taskGroupUid: "$taskGroupUid", ' + 'languageTaskGroupUid: "$languageTaskGroupUid", ' + 'assessmentUid: "$assessmentUid", ' + 'canStudentEditHomework: $canStudentEditHomework, ' + 'isHomeworkComplete: $isHomeworkComplete, ' + 'attachments: $attachments, ' + 'isDigitalLesson: $isDigitalLesson, ' + 'digitalDeviceList: "$digitalDeviceList", ' + 'digitalPlatformType: "$digitalPlatformType", ' + 'digitalSupportDeviceTypeList: $digitalSupportDeviceTypeList, ' + 'create: $createdAt, ' + 'lastModified: $lastModifiedAt' + ')'; + } +} diff --git a/kreta_api/lib/src/resp/token_grant.dart b/kreta_api/lib/src/resp/token_grant.dart new file mode 100644 index 00000000..1bedf052 --- /dev/null +++ b/kreta_api/lib/src/resp/token_grant.dart @@ -0,0 +1,38 @@ +class TokenGrantResponse { + final String idToken; + final String accessToken; + final int expiresIn; + final String tokenType; + final String refreshToken; + final String scope; + + TokenGrantResponse({ + required this.idToken, + required this.accessToken, + required this.expiresIn, + required this.tokenType, + required this.refreshToken, + required this.scope, + }); + + factory TokenGrantResponse.fromJson(Map json) { + return TokenGrantResponse( + idToken: json['id_token'], + accessToken: json['access_token'], + expiresIn: json['expires_in'], + tokenType: json['token_type'], + refreshToken: json['refresh_token'], + scope: json['scope'], + ); + } + + @override + String toString() { + return 'TokenGrant(idToken: "$idToken", accessToken: "$accessToken", ' + 'expiresIn: $expiresIn, ' + 'tokenType: "$tokenType", ' + 'refreshToken: "$refreshToken", ' + 'scope: "$scope"' + ')'; + } +} diff --git a/kreta_api/pubspec.yaml b/kreta_api/pubspec.yaml new file mode 100644 index 00000000..61f868f2 --- /dev/null +++ b/kreta_api/pubspec.yaml @@ -0,0 +1,10 @@ +name: kreta_api +description: Shared Kreta API data structures (models, DTOs, exceptions) for firka and firka_wear. +version: 0.1.0 +repository: https://github.com/firka/firka + +environment: + sdk: ^3.11.0 + +dependencies: + intl: any