Initial commit: TimeReg Flutter app med Firebase backend
- Opprettet Flutter-prosjekt med alle nødvendige avhengigheter - Implementert datamodeller (User, TimeRegistration, TariffProfile, Deviation, AuditLog) - Implementert tjenester (AuthService, TimeService) - Implementert Riverpod providers for state management - Opprettet autentiseringsskjermer (login, signup, reset password) - Opprettet hjemmeskjerm med timer-funksjonalitet - Opprettet placeholder-skjermer for historikk, rapporter og profil - Lagt til norsk dokumentasjon i README
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class NightWorkRules {
|
||||
final int startHour; // e.g., 21 for 9 PM
|
||||
final int endHour; // e.g., 6 for 6 AM
|
||||
final int maxNightHours;
|
||||
|
||||
NightWorkRules({
|
||||
required this.startHour,
|
||||
required this.endHour,
|
||||
required this.maxNightHours,
|
||||
});
|
||||
|
||||
factory NightWorkRules.fromMap(Map<String, dynamic> map) {
|
||||
return NightWorkRules(
|
||||
startHour: map['startHour'] ?? 21,
|
||||
endHour: map['endHour'] ?? 6,
|
||||
maxNightHours: map['maxNightHours'] ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'startHour': startHour,
|
||||
'endHour': endHour,
|
||||
'maxNightHours': maxNightHours,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TariffRules {
|
||||
final int maxDailyHours;
|
||||
final int maxWeeklyHours;
|
||||
final int minDailyRest; // in minutes
|
||||
final int minWeeklyRest; // in minutes
|
||||
final bool useAverageCalculation;
|
||||
final int? averagePeriodWeeks;
|
||||
final int? maxAverageHours;
|
||||
final NightWorkRules? nightWorkRules;
|
||||
|
||||
TariffRules({
|
||||
required this.maxDailyHours,
|
||||
required this.maxWeeklyHours,
|
||||
required this.minDailyRest,
|
||||
required this.minWeeklyRest,
|
||||
this.useAverageCalculation = false,
|
||||
this.averagePeriodWeeks,
|
||||
this.maxAverageHours,
|
||||
this.nightWorkRules,
|
||||
});
|
||||
|
||||
factory TariffRules.fromMap(Map<String, dynamic> map) {
|
||||
return TariffRules(
|
||||
maxDailyHours: map['maxDailyHours'] ?? 9,
|
||||
maxWeeklyHours: map['maxWeeklyHours'] ?? 40,
|
||||
minDailyRest: map['minDailyRest'] ?? 660, // 11 hours
|
||||
minWeeklyRest: map['minWeeklyRest'] ?? 2100, // 35 hours
|
||||
useAverageCalculation: map['useAverageCalculation'] ?? false,
|
||||
averagePeriodWeeks: map['averagePeriodWeeks'],
|
||||
maxAverageHours: map['maxAverageHours'],
|
||||
nightWorkRules: map['nightWorkRules'] != null
|
||||
? NightWorkRules.fromMap(map['nightWorkRules'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'maxDailyHours': maxDailyHours,
|
||||
'maxWeeklyHours': maxWeeklyHours,
|
||||
'minDailyRest': minDailyRest,
|
||||
'minWeeklyRest': minWeeklyRest,
|
||||
'useAverageCalculation': useAverageCalculation,
|
||||
'averagePeriodWeeks': averagePeriodWeeks,
|
||||
'maxAverageHours': maxAverageHours,
|
||||
'nightWorkRules': nightWorkRules?.toMap(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TariffProfile {
|
||||
final String id;
|
||||
final String name;
|
||||
final String description;
|
||||
final String organizationId;
|
||||
final TariffRules rules;
|
||||
final bool isDefault;
|
||||
final bool isActive;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
|
||||
TariffProfile({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.organizationId,
|
||||
required this.rules,
|
||||
this.isDefault = false,
|
||||
this.isActive = true,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
factory TariffProfile.fromFirestore(DocumentSnapshot doc) {
|
||||
final data = doc.data() as Map<String, dynamic>;
|
||||
return TariffProfile(
|
||||
id: doc.id,
|
||||
name: data['name'] ?? '',
|
||||
description: data['description'] ?? '',
|
||||
organizationId: data['organizationId'] ?? '',
|
||||
rules: TariffRules.fromMap(data['rules'] ?? {}),
|
||||
isDefault: data['isDefault'] ?? false,
|
||||
isActive: data['isActive'] ?? true,
|
||||
createdAt: (data['createdAt'] as Timestamp).toDate(),
|
||||
updatedAt: (data['updatedAt'] as Timestamp).toDate(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toFirestore() {
|
||||
return {
|
||||
'name': name,
|
||||
'description': description,
|
||||
'organizationId': organizationId,
|
||||
'rules': rules.toMap(),
|
||||
'isDefault': isDefault,
|
||||
'isActive': isActive,
|
||||
'createdAt': Timestamp.fromDate(createdAt),
|
||||
'updatedAt': Timestamp.fromDate(updatedAt),
|
||||
};
|
||||
}
|
||||
|
||||
TariffProfile copyWith({
|
||||
String? name,
|
||||
String? description,
|
||||
String? organizationId,
|
||||
TariffRules? rules,
|
||||
bool? isDefault,
|
||||
bool? isActive,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return TariffProfile(
|
||||
id: id,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
organizationId: organizationId ?? this.organizationId,
|
||||
rules: rules ?? this.rules,
|
||||
isDefault: isDefault ?? this.isDefault,
|
||||
isActive: isActive ?? this.isActive,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
);
|
||||
}
|
||||
|
||||
// Predefined profiles
|
||||
static TariffProfile createDefaultAML(String organizationId) {
|
||||
return TariffProfile(
|
||||
id: 'default_aml',
|
||||
name: 'Ingen tariffavtale (AML Standard)',
|
||||
description: 'Standard arbeidsmiljøloven uten tariffavtale',
|
||||
organizationId: organizationId,
|
||||
rules: TariffRules(
|
||||
maxDailyHours: 9,
|
||||
maxWeeklyHours: 40,
|
||||
minDailyRest: 660, // 11 hours
|
||||
minWeeklyRest: 2100, // 35 hours
|
||||
),
|
||||
isDefault: true,
|
||||
isActive: true,
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
}
|
||||
|
||||
static TariffProfile createTariffA(String organizationId) {
|
||||
return TariffProfile(
|
||||
id: 'tariff_a',
|
||||
name: 'Tariffavtale A',
|
||||
description: 'Tariffavtale med utvidet arbeidstid og gjennomsnittsberegning',
|
||||
organizationId: organizationId,
|
||||
rules: TariffRules(
|
||||
maxDailyHours: 10,
|
||||
maxWeeklyHours: 48,
|
||||
minDailyRest: 660, // 11 hours
|
||||
minWeeklyRest: 2100, // 35 hours
|
||||
useAverageCalculation: true,
|
||||
averagePeriodWeeks: 8,
|
||||
maxAverageHours: 48,
|
||||
),
|
||||
isDefault: false,
|
||||
isActive: true,
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user